| Index: third_party/wtl/include/atlprint.h
|
| diff --git a/third_party/wtl/include/atlprint.h b/third_party/wtl/include/atlprint.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..db30a06a5ed1123121e82eb74077afca912e994d
|
| --- /dev/null
|
| +++ b/third_party/wtl/include/atlprint.h
|
| @@ -0,0 +1,1110 @@
|
| +// Windows Template Library - WTL version 8.0
|
| +// Copyright (C) Microsoft Corporation. All rights reserved.
|
| +//
|
| +// This file is a part of the Windows Template Library.
|
| +// The use and distribution terms for this software are covered by the
|
| +// Microsoft Permissive License (Ms-PL) which can be found in the file
|
| +// Ms-PL.txt at the root of this distribution.
|
| +
|
| +#ifndef __ATLPRINT_H__
|
| +#define __ATLPRINT_H__
|
| +
|
| +#pragma once
|
| +
|
| +#ifndef __cplusplus
|
| + #error ATL requires C++ compilation (use a .cpp suffix)
|
| +#endif
|
| +
|
| +#ifdef _WIN32_WCE
|
| + #error atlprint.h is not supported on Windows CE
|
| +#endif
|
| +
|
| +#ifndef __ATLAPP_H__
|
| + #error atlprint.h requires atlapp.h to be included first
|
| +#endif
|
| +
|
| +#ifndef __ATLWIN_H__
|
| + #error atlprint.h requires atlwin.h to be included first
|
| +#endif
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// Classes in this file:
|
| +//
|
| +// CPrinterInfo<t_nInfo>
|
| +// CPrinterT<t_bManaged>
|
| +// CDevModeT<t_bManaged>
|
| +// CPrinterDC
|
| +// CPrintJobInfo
|
| +// CPrintJob
|
| +// CPrintPreview
|
| +// CPrintPreviewWindowImpl<T, TBase, TWinTraits>
|
| +// CPrintPreviewWindow
|
| +// CZoomPrintPreviewWindowImpl<T, TBase, TWinTraits>
|
| +// CZoomPrintPreviewWindow
|
| +
|
| +namespace WTL
|
| +{
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrinterInfo - This class wraps all of the PRINTER_INFO_* structures
|
| +// and provided by ::GetPrinter.
|
| +
|
| +template <unsigned int t_nInfo>
|
| +class _printer_info
|
| +{
|
| +public:
|
| + typedef void infotype;
|
| +};
|
| +
|
| +template <> class _printer_info<1> { public: typedef PRINTER_INFO_1 infotype; };
|
| +template <> class _printer_info<2> { public: typedef PRINTER_INFO_2 infotype; };
|
| +template <> class _printer_info<3> { public: typedef PRINTER_INFO_3 infotype; };
|
| +template <> class _printer_info<4> { public: typedef PRINTER_INFO_4 infotype; };
|
| +template <> class _printer_info<5> { public: typedef PRINTER_INFO_5 infotype; };
|
| +template <> class _printer_info<6> { public: typedef PRINTER_INFO_6 infotype; };
|
| +template <> class _printer_info<7> { public: typedef PRINTER_INFO_7 infotype; };
|
| +// these are not in the old (vc6.0) headers
|
| +#ifdef _ATL_USE_NEW_PRINTER_INFO
|
| +template <> class _printer_info<8> { public: typedef PRINTER_INFO_8 infotype; };
|
| +template <> class _printer_info<9> { public: typedef PRINTER_INFO_9 infotype; };
|
| +#endif // _ATL_USE_NEW_PRINTER_INFO
|
| +
|
| +
|
| +template <unsigned int t_nInfo>
|
| +class CPrinterInfo
|
| +{
|
| +public:
|
| +// Data members
|
| + typename _printer_info<t_nInfo>::infotype* m_pi;
|
| +
|
| +// Constructor/destructor
|
| + CPrinterInfo() : m_pi(NULL)
|
| + { }
|
| +
|
| + CPrinterInfo(HANDLE hPrinter) : m_pi(NULL)
|
| + {
|
| + GetPrinterInfo(hPrinter);
|
| + }
|
| +
|
| + ~CPrinterInfo()
|
| + {
|
| + Cleanup();
|
| + }
|
| +
|
| +// Operations
|
| + bool GetPrinterInfo(HANDLE hPrinter)
|
| + {
|
| + Cleanup();
|
| + return GetPrinterInfoHelper(hPrinter, (BYTE**)&m_pi, t_nInfo);
|
| + }
|
| +
|
| +// Implementation
|
| + void Cleanup()
|
| + {
|
| + delete [] (BYTE*)m_pi;
|
| + m_pi = NULL;
|
| + }
|
| +
|
| + static bool GetPrinterInfoHelper(HANDLE hPrinter, BYTE** pi, int nIndex)
|
| + {
|
| + ATLASSERT(pi != NULL);
|
| + DWORD dw = 0;
|
| + BYTE* pb = NULL;
|
| + ::GetPrinter(hPrinter, nIndex, NULL, 0, &dw);
|
| + if (dw > 0)
|
| + {
|
| + ATLTRY(pb = new BYTE[dw]);
|
| + if (pb != NULL)
|
| + {
|
| + memset(pb, 0, dw);
|
| + DWORD dwNew;
|
| + if (!::GetPrinter(hPrinter, nIndex, pb, dw, &dwNew))
|
| + {
|
| + delete [] pb;
|
| + pb = NULL;
|
| + }
|
| + }
|
| + }
|
| + *pi = pb;
|
| + return (pb != NULL);
|
| + }
|
| +};
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrinter - Wrapper class for a HANDLE to a printer
|
| +
|
| +template <bool t_bManaged>
|
| +class CPrinterT
|
| +{
|
| +public:
|
| +// Data members
|
| + HANDLE m_hPrinter;
|
| +
|
| +// Constructor/destructor
|
| + CPrinterT(HANDLE hPrinter = NULL) : m_hPrinter(hPrinter)
|
| + { }
|
| +
|
| + ~CPrinterT()
|
| + {
|
| + ClosePrinter();
|
| + }
|
| +
|
| +// Operations
|
| + CPrinterT& operator =(HANDLE hPrinter)
|
| + {
|
| + if (hPrinter != m_hPrinter)
|
| + {
|
| + ClosePrinter();
|
| + m_hPrinter = hPrinter;
|
| + }
|
| + return *this;
|
| + }
|
| +
|
| + bool IsNull() const { return (m_hPrinter == NULL); }
|
| +
|
| + bool OpenPrinter(HANDLE hDevNames, const DEVMODE* pDevMode = NULL)
|
| + {
|
| + bool b = false;
|
| + DEVNAMES* pdn = (DEVNAMES*)::GlobalLock(hDevNames);
|
| + if (pdn != NULL)
|
| + {
|
| + LPTSTR lpszPrinterName = (LPTSTR)pdn + pdn->wDeviceOffset;
|
| + b = OpenPrinter(lpszPrinterName, pDevMode);
|
| + ::GlobalUnlock(hDevNames);
|
| + }
|
| + return b;
|
| + }
|
| +
|
| + bool OpenPrinter(LPCTSTR lpszPrinterName, const DEVMODE* pDevMode = NULL)
|
| + {
|
| + ClosePrinter();
|
| + PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE };
|
| + ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs);
|
| +
|
| + return (m_hPrinter != NULL);
|
| + }
|
| +
|
| + bool OpenPrinter(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS* pprintdefs)
|
| + {
|
| + ClosePrinter();
|
| + ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, pprintdefs);
|
| + return (m_hPrinter != NULL);
|
| + }
|
| +
|
| + bool OpenDefaultPrinter(const DEVMODE* pDevMode = NULL)
|
| + {
|
| + ClosePrinter();
|
| + const int cchBuff = 512;
|
| + TCHAR buffer[cchBuff];
|
| + buffer[0] = 0;
|
| + ::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffer, cchBuff);
|
| + int nLen = lstrlen(buffer);
|
| + if (nLen != 0)
|
| + {
|
| + LPTSTR lpsz = buffer;
|
| + while (*lpsz)
|
| + {
|
| + if (*lpsz == _T(','))
|
| + {
|
| + *lpsz = 0;
|
| + break;
|
| + }
|
| + lpsz = CharNext(lpsz);
|
| + }
|
| + PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE };
|
| + ::OpenPrinter(buffer, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs);
|
| + }
|
| + return m_hPrinter != NULL;
|
| + }
|
| +
|
| + void ClosePrinter()
|
| + {
|
| + if (m_hPrinter != NULL)
|
| + {
|
| + if (t_bManaged)
|
| + ::ClosePrinter(m_hPrinter);
|
| + m_hPrinter = NULL;
|
| + }
|
| + }
|
| +
|
| + bool PrinterProperties(HWND hWnd = NULL)
|
| + {
|
| + if (hWnd == NULL)
|
| + hWnd = ::GetActiveWindow();
|
| + return !!::PrinterProperties(hWnd, m_hPrinter);
|
| + }
|
| +
|
| + HANDLE CopyToHDEVNAMES() const
|
| + {
|
| + HANDLE h = NULL;
|
| + CPrinterInfo<5> pinfon5;
|
| + CPrinterInfo<2> pinfon2;
|
| + LPTSTR lpszPrinterName = NULL;
|
| + // Some printers fail for PRINTER_INFO_5 in some situations
|
| + if (pinfon5.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfon5.m_pi->pPrinterName;
|
| + else if (pinfon2.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfon2.m_pi->pPrinterName;
|
| + if (lpszPrinterName != NULL)
|
| + {
|
| + int nLen = sizeof(DEVNAMES) + (lstrlen(lpszPrinterName) + 1) * sizeof(TCHAR);
|
| + h = ::GlobalAlloc(GMEM_MOVEABLE, nLen);
|
| + BYTE* pv = (BYTE*)::GlobalLock(h);
|
| + DEVNAMES* pdev = (DEVNAMES*)pv;
|
| + if (pv != NULL)
|
| + {
|
| + memset(pv, 0, nLen);
|
| + pdev->wDeviceOffset = sizeof(DEVNAMES) / sizeof(TCHAR);
|
| + pv = pv + sizeof(DEVNAMES); // now points to end
|
| + SecureHelper::strcpy_x((LPTSTR)pv, lstrlen(lpszPrinterName) + 1, lpszPrinterName);
|
| + ::GlobalUnlock(h);
|
| + }
|
| + }
|
| + return h;
|
| + }
|
| +
|
| + HDC CreatePrinterDC(const DEVMODE* pdm = NULL) const
|
| + {
|
| + CPrinterInfo<5> pinfo5;
|
| + CPrinterInfo<2> pinfo2;
|
| + HDC hDC = NULL;
|
| + LPTSTR lpszPrinterName = NULL;
|
| + // Some printers fail for PRINTER_INFO_5 in some situations
|
| + if (pinfo5.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfo5.m_pi->pPrinterName;
|
| + else if (pinfo2.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfo2.m_pi->pPrinterName;
|
| + if (lpszPrinterName != NULL)
|
| + hDC = ::CreateDC(NULL, lpszPrinterName, NULL, pdm);
|
| + return hDC;
|
| + }
|
| +
|
| + HDC CreatePrinterIC(const DEVMODE* pdm = NULL) const
|
| + {
|
| + CPrinterInfo<5> pinfo5;
|
| + CPrinterInfo<2> pinfo2;
|
| + HDC hDC = NULL;
|
| + LPTSTR lpszPrinterName = NULL;
|
| + // Some printers fail for PRINTER_INFO_5 in some situations
|
| + if (pinfo5.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfo5.m_pi->pPrinterName;
|
| + else if (pinfo2.GetPrinterInfo(m_hPrinter))
|
| + lpszPrinterName = pinfo2.m_pi->pPrinterName;
|
| + if (lpszPrinterName != NULL)
|
| + hDC = ::CreateIC(NULL, lpszPrinterName, NULL, pdm);
|
| + return hDC;
|
| + }
|
| +
|
| + void Attach(HANDLE hPrinter)
|
| + {
|
| + ClosePrinter();
|
| + m_hPrinter = hPrinter;
|
| + }
|
| +
|
| + HANDLE Detach()
|
| + {
|
| + HANDLE hPrinter = m_hPrinter;
|
| + m_hPrinter = NULL;
|
| + return hPrinter;
|
| + }
|
| +
|
| + operator HANDLE() const { return m_hPrinter; }
|
| +};
|
| +
|
| +typedef CPrinterT<false> CPrinterHandle;
|
| +typedef CPrinterT<true> CPrinter;
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CDevMode - Wrapper class for DEVMODE
|
| +
|
| +template <bool t_bManaged>
|
| +class CDevModeT
|
| +{
|
| +public:
|
| +// Data members
|
| + HANDLE m_hDevMode;
|
| + DEVMODE* m_pDevMode;
|
| +
|
| +// Constructor/destructor
|
| + CDevModeT(HANDLE hDevMode = NULL) : m_hDevMode(hDevMode)
|
| + {
|
| + m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL;
|
| + }
|
| +
|
| + ~CDevModeT()
|
| + {
|
| + Cleanup();
|
| + }
|
| +
|
| +// Operations
|
| + CDevModeT<t_bManaged>& operator =(HANDLE hDevMode)
|
| + {
|
| + Attach(hDevMode);
|
| + return *this;
|
| + }
|
| +
|
| + void Attach(HANDLE hDevModeNew)
|
| + {
|
| + Cleanup();
|
| + m_hDevMode = hDevModeNew;
|
| + m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL;
|
| + }
|
| +
|
| + HANDLE Detach()
|
| + {
|
| + if (m_hDevMode != NULL)
|
| + ::GlobalUnlock(m_hDevMode);
|
| + HANDLE hDevMode = m_hDevMode;
|
| + m_hDevMode = NULL;
|
| + return hDevMode;
|
| + }
|
| +
|
| + bool IsNull() const { return (m_hDevMode == NULL); }
|
| +
|
| + bool CopyFromPrinter(HANDLE hPrinter)
|
| + {
|
| + CPrinterInfo<2> pinfo;
|
| + bool b = pinfo.GetPrinterInfo(hPrinter);
|
| + if (b)
|
| + b = CopyFromDEVMODE(pinfo.m_pi->pDevMode);
|
| + return b;
|
| + }
|
| +
|
| + bool CopyFromDEVMODE(const DEVMODE* pdm)
|
| + {
|
| + if (pdm == NULL)
|
| + return false;
|
| + int nSize = pdm->dmSize + pdm->dmDriverExtra;
|
| + HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
|
| + if (h != NULL)
|
| + {
|
| + void* p = ::GlobalLock(h);
|
| + SecureHelper::memcpy_x(p, nSize, pdm, nSize);
|
| + ::GlobalUnlock(h);
|
| + }
|
| + Attach(h);
|
| + return (h != NULL);
|
| + }
|
| +
|
| + bool CopyFromHDEVMODE(HANDLE hdm)
|
| + {
|
| + bool b = false;
|
| + if (hdm != NULL)
|
| + {
|
| + DEVMODE* pdm = (DEVMODE*)::GlobalLock(hdm);
|
| + b = CopyFromDEVMODE(pdm);
|
| + ::GlobalUnlock(hdm);
|
| + }
|
| + return b;
|
| + }
|
| +
|
| + HANDLE CopyToHDEVMODE()
|
| + {
|
| + if ((m_hDevMode == NULL) || (m_pDevMode == NULL))
|
| + return NULL;
|
| + int nSize = m_pDevMode->dmSize + m_pDevMode->dmDriverExtra;
|
| + HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
|
| + if (h != NULL)
|
| + {
|
| + void* p = ::GlobalLock(h);
|
| + SecureHelper::memcpy_x(p, nSize, m_pDevMode, nSize);
|
| + ::GlobalUnlock(h);
|
| + }
|
| + return h;
|
| + }
|
| +
|
| + // If this devmode was for another printer, this will create a new devmode
|
| + // based on the existing devmode, but retargeted at the new printer
|
| + bool UpdateForNewPrinter(HANDLE hPrinter)
|
| + {
|
| + bool bRet = false;
|
| + LONG nLen = ::DocumentProperties(NULL, hPrinter, NULL, NULL, NULL, 0);
|
| + CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
|
| + DEVMODE* pdm = buff.AllocateBytes(nLen);
|
| + if(pdm != NULL)
|
| + {
|
| + memset(pdm, 0, nLen);
|
| + LONG l = ::DocumentProperties(NULL, hPrinter, NULL, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
|
| + if (l == IDOK)
|
| + bRet = CopyFromDEVMODE(pdm);
|
| + }
|
| +
|
| + return bRet;
|
| + }
|
| +
|
| + bool DocumentProperties(HANDLE hPrinter, HWND hWnd = NULL)
|
| + {
|
| + CPrinterInfo<1> pi;
|
| + pi.GetPrinterInfo(hPrinter);
|
| + if (hWnd == NULL)
|
| + hWnd = ::GetActiveWindow();
|
| +
|
| + bool bRet = false;
|
| + LONG nLen = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, NULL, NULL, 0);
|
| + CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
|
| + DEVMODE* pdm = buff.AllocateBytes(nLen);
|
| + if(pdm != NULL)
|
| + {
|
| + memset(pdm, 0, nLen);
|
| + LONG l = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_PROMPT);
|
| + if (l == IDOK)
|
| + bRet = CopyFromDEVMODE(pdm);
|
| + }
|
| +
|
| + return bRet;
|
| + }
|
| +
|
| + operator HANDLE() const { return m_hDevMode; }
|
| +
|
| + operator DEVMODE*() const { return m_pDevMode; }
|
| +
|
| +// Implementation
|
| + void Cleanup()
|
| + {
|
| + if (m_hDevMode != NULL)
|
| + {
|
| + ::GlobalUnlock(m_hDevMode);
|
| + if(t_bManaged)
|
| + ::GlobalFree(m_hDevMode);
|
| + m_hDevMode = NULL;
|
| + }
|
| + }
|
| +};
|
| +
|
| +typedef CDevModeT<false> CDevModeHandle;
|
| +typedef CDevModeT<true> CDevMode;
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrinterDC
|
| +
|
| +class CPrinterDC : public CDC
|
| +{
|
| +public:
|
| +// Constructors/destructor
|
| + CPrinterDC()
|
| + {
|
| + CPrinter printer;
|
| + printer.OpenDefaultPrinter();
|
| + Attach(printer.CreatePrinterDC());
|
| + ATLASSERT(m_hDC != NULL);
|
| + }
|
| +
|
| + CPrinterDC(HANDLE hPrinter, const DEVMODE* pdm = NULL)
|
| + {
|
| + CPrinterHandle p;
|
| + p.Attach(hPrinter);
|
| + Attach(p.CreatePrinterDC(pdm));
|
| + ATLASSERT(m_hDC != NULL);
|
| + }
|
| +
|
| + ~CPrinterDC()
|
| + {
|
| + DeleteDC();
|
| + }
|
| +};
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrintJob - Wraps a set of tasks for a specific printer (StartDoc/EndDoc)
|
| +// Handles aborting, background printing
|
| +
|
| +// Defines callbacks used by CPrintJob (not a COM interface)
|
| +class ATL_NO_VTABLE IPrintJobInfo
|
| +{
|
| +public:
|
| + virtual void BeginPrintJob(HDC hDC) = 0; // allocate handles needed, etc.
|
| + virtual void EndPrintJob(HDC hDC, bool bAborted) = 0; // free handles, etc.
|
| + virtual void PrePrintPage(UINT nPage, HDC hDC) = 0;
|
| + virtual bool PrintPage(UINT nPage, HDC hDC) = 0;
|
| + virtual void PostPrintPage(UINT nPage, HDC hDC) = 0;
|
| + // If you want per page devmodes, return the DEVMODE* to use for nPage.
|
| + // You can optimize by only returning a new DEVMODE* when it is different
|
| + // from the one for nLastPage, otherwise return NULL.
|
| + // When nLastPage==0, the current DEVMODE* will be the default passed to
|
| + // StartPrintJob.
|
| + // Note: During print preview, nLastPage will always be "0".
|
| + virtual DEVMODE* GetNewDevModeForPage(UINT nLastPage, UINT nPage) = 0;
|
| + virtual bool IsValidPage(UINT nPage) = 0;
|
| +};
|
| +
|
| +// Provides a default implementatin for IPrintJobInfo
|
| +// Typically, MI'd into a document or view class
|
| +class ATL_NO_VTABLE CPrintJobInfo : public IPrintJobInfo
|
| +{
|
| +public:
|
| + virtual void BeginPrintJob(HDC /*hDC*/) // allocate handles needed, etc
|
| + {
|
| + }
|
| +
|
| + virtual void EndPrintJob(HDC /*hDC*/, bool /*bAborted*/) // free handles, etc
|
| + {
|
| + }
|
| +
|
| + virtual void PrePrintPage(UINT /*nPage*/, HDC hDC)
|
| + {
|
| + m_nPJState = ::SaveDC(hDC);
|
| + }
|
| +
|
| + virtual bool PrintPage(UINT /*nPage*/, HDC /*hDC*/) = 0;
|
| +
|
| + virtual void PostPrintPage(UINT /*nPage*/, HDC hDC)
|
| + {
|
| + RestoreDC(hDC, m_nPJState);
|
| + }
|
| +
|
| + virtual DEVMODE* GetNewDevModeForPage(UINT /*nLastPage*/, UINT /*nPage*/)
|
| + {
|
| + return NULL;
|
| + }
|
| +
|
| + virtual bool IsValidPage(UINT /*nPage*/)
|
| + {
|
| + return true;
|
| + }
|
| +
|
| +// Implementation - data
|
| + int m_nPJState;
|
| +};
|
| +
|
| +
|
| +class CPrintJob
|
| +{
|
| +public:
|
| +// Data members
|
| + CPrinterHandle m_printer;
|
| + IPrintJobInfo* m_pInfo;
|
| + DEVMODE* m_pDefDevMode;
|
| + DOCINFO m_docinfo;
|
| + int m_nJobID;
|
| + bool m_bCancel;
|
| + bool m_bComplete;
|
| + unsigned long m_nStartPage;
|
| + unsigned long m_nEndPage;
|
| +
|
| +// Constructor/destructor
|
| + CPrintJob() : m_nJobID(0), m_bCancel(false), m_bComplete(true)
|
| + { }
|
| +
|
| + ~CPrintJob()
|
| + {
|
| + ATLASSERT(IsJobComplete()); // premature destruction?
|
| + }
|
| +
|
| +// Operations
|
| + bool IsJobComplete() const
|
| + {
|
| + return m_bComplete;
|
| + }
|
| +
|
| + bool StartPrintJob(bool bBackground, HANDLE hPrinter, DEVMODE* pDefaultDevMode,
|
| + IPrintJobInfo* pInfo, LPCTSTR lpszDocName,
|
| + unsigned long nStartPage, unsigned long nEndPage,
|
| + bool bPrintToFile = false, LPCTSTR lpstrOutputFile = NULL)
|
| + {
|
| + ATLASSERT(m_bComplete); // previous job not done yet?
|
| + if (pInfo == NULL)
|
| + return false;
|
| +
|
| + memset(&m_docinfo, 0, sizeof(m_docinfo));
|
| + m_docinfo.cbSize = sizeof(m_docinfo);
|
| + m_docinfo.lpszDocName = lpszDocName;
|
| + m_pInfo = pInfo;
|
| + m_nStartPage = nStartPage;
|
| + m_nEndPage = nEndPage;
|
| + m_printer.Attach(hPrinter);
|
| + m_pDefDevMode = pDefaultDevMode;
|
| + m_bComplete = false;
|
| +
|
| + if(bPrintToFile)
|
| + m_docinfo.lpszOutput = (lpstrOutputFile != NULL) ? lpstrOutputFile : _T("FILE:");
|
| +
|
| + if (!bBackground)
|
| + {
|
| + m_bComplete = true;
|
| + return StartHelper();
|
| + }
|
| +
|
| + // Create a thread and return
|
| + DWORD dwThreadID = 0;
|
| +#if !defined(_ATL_MIN_CRT) && defined(_MT)
|
| + HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))StartProc, this, 0, (UINT*)&dwThreadID);
|
| +#else
|
| + HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID);
|
| +#endif
|
| + if (hThread == NULL)
|
| + return false;
|
| +
|
| + ::CloseHandle(hThread);
|
| +
|
| + return true;
|
| + }
|
| +
|
| +// Implementation
|
| + static DWORD WINAPI StartProc(void* p)
|
| + {
|
| + CPrintJob* pThis = (CPrintJob*)p;
|
| + pThis->StartHelper();
|
| + pThis->m_bComplete = true;
|
| + return 0;
|
| + }
|
| +
|
| + bool StartHelper()
|
| + {
|
| + CDC dcPrinter;
|
| + dcPrinter.Attach(m_printer.CreatePrinterDC(m_pDefDevMode));
|
| + if (dcPrinter.IsNull())
|
| + return false;
|
| +
|
| + m_nJobID = ::StartDoc(dcPrinter, &m_docinfo);
|
| + if (m_nJobID <= 0)
|
| + return false;
|
| +
|
| + m_pInfo->BeginPrintJob(dcPrinter);
|
| +
|
| + // print all the pages now
|
| + unsigned long nLastPage = 0;
|
| + for (unsigned long nPage = m_nStartPage; nPage <= m_nEndPage; nPage++)
|
| + {
|
| + if (!m_pInfo->IsValidPage(nPage))
|
| + break;
|
| + DEVMODE* pdm = m_pInfo->GetNewDevModeForPage(nLastPage, nPage);
|
| + if (pdm != NULL)
|
| + dcPrinter.ResetDC(pdm);
|
| + dcPrinter.StartPage();
|
| + m_pInfo->PrePrintPage(nPage, dcPrinter);
|
| + if (!m_pInfo->PrintPage(nPage, dcPrinter))
|
| + m_bCancel = true;
|
| + m_pInfo->PostPrintPage(nPage, dcPrinter);
|
| + dcPrinter.EndPage();
|
| + if (m_bCancel)
|
| + break;
|
| + nLastPage = nPage;
|
| + }
|
| +
|
| + m_pInfo->EndPrintJob(dcPrinter, m_bCancel);
|
| + if (m_bCancel)
|
| + ::AbortDoc(dcPrinter);
|
| + else
|
| + ::EndDoc(dcPrinter);
|
| + m_nJobID = 0;
|
| + return true;
|
| + }
|
| +
|
| + // Cancels a print job. Can be called asynchronously.
|
| + void CancelPrintJob()
|
| + {
|
| + m_bCancel = true;
|
| + }
|
| +};
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrintPreview - Adds print preview support to an existing window
|
| +
|
| +class CPrintPreview
|
| +{
|
| +public:
|
| +// Data members
|
| + IPrintJobInfo* m_pInfo;
|
| + CPrinterHandle m_printer;
|
| + CEnhMetaFile m_meta;
|
| + DEVMODE* m_pDefDevMode;
|
| + DEVMODE* m_pCurDevMode;
|
| + SIZE m_sizeCurPhysOffset;
|
| +
|
| +// Constructor
|
| + CPrintPreview() : m_pInfo(NULL), m_pDefDevMode(NULL), m_pCurDevMode(NULL)
|
| + {
|
| + m_sizeCurPhysOffset.cx = 0;
|
| + m_sizeCurPhysOffset.cy = 0;
|
| + }
|
| +
|
| +// Operations
|
| + void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, IPrintJobInfo* pji)
|
| + {
|
| + m_printer.Attach(hPrinter);
|
| + m_pDefDevMode = pDefaultDevMode;
|
| + m_pInfo = pji;
|
| + m_nCurPage = 0;
|
| + m_pCurDevMode = NULL;
|
| + }
|
| +
|
| + void SetEnhMetaFile(HENHMETAFILE hEMF)
|
| + {
|
| + m_meta = hEMF;
|
| + }
|
| +
|
| + void SetPage(int nPage)
|
| + {
|
| + if (!m_pInfo->IsValidPage(nPage))
|
| + return;
|
| + m_nCurPage = nPage;
|
| + m_pCurDevMode = m_pInfo->GetNewDevModeForPage(0, nPage);
|
| + if (m_pCurDevMode == NULL)
|
| + m_pCurDevMode = m_pDefDevMode;
|
| + CDC dcPrinter = m_printer.CreatePrinterDC(m_pCurDevMode);
|
| +
|
| + int iWidth = dcPrinter.GetDeviceCaps(PHYSICALWIDTH);
|
| + int iHeight = dcPrinter.GetDeviceCaps(PHYSICALHEIGHT);
|
| + int nLogx = dcPrinter.GetDeviceCaps(LOGPIXELSX);
|
| + int nLogy = dcPrinter.GetDeviceCaps(LOGPIXELSY);
|
| +
|
| + RECT rcMM = { 0, 0, ::MulDiv(iWidth, 2540, nLogx), ::MulDiv(iHeight, 2540, nLogy) };
|
| +
|
| + m_sizeCurPhysOffset.cx = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX);
|
| + m_sizeCurPhysOffset.cy = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY);
|
| +
|
| + CEnhMetaFileDC dcMeta(dcPrinter, &rcMM);
|
| + m_pInfo->PrePrintPage(nPage, dcMeta);
|
| + m_pInfo->PrintPage(nPage, dcMeta);
|
| + m_pInfo->PostPrintPage(nPage, dcMeta);
|
| + m_meta.Attach(dcMeta.Close());
|
| + }
|
| +
|
| + void GetPageRect(RECT& rc, LPRECT prc)
|
| + {
|
| + int x1 = rc.right-rc.left;
|
| + int y1 = rc.bottom - rc.top;
|
| + if ((x1 < 0) || (y1 < 0))
|
| + return;
|
| +
|
| + CEnhMetaFileInfo emfinfo(m_meta);
|
| + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
|
| +
|
| + // Compute whether we are OK vertically or horizontally
|
| + int x2 = pmh->szlDevice.cx;
|
| + int y2 = pmh->szlDevice.cy;
|
| + int y1p = MulDiv(x1, y2, x2);
|
| + int x1p = MulDiv(y1, x2, y2);
|
| + ATLASSERT((x1p <= x1) || (y1p <= y1));
|
| + if (x1p <= x1)
|
| + {
|
| + prc->left = rc.left + (x1 - x1p) / 2;
|
| + prc->right = prc->left + x1p;
|
| + prc->top = rc.top;
|
| + prc->bottom = rc.bottom;
|
| + }
|
| + else
|
| + {
|
| + prc->left = rc.left;
|
| + prc->right = rc.right;
|
| + prc->top = rc.top + (y1 - y1p) / 2;
|
| + prc->bottom = prc->top + y1p;
|
| + }
|
| + }
|
| +
|
| +// Painting helpers
|
| + void DoPaint(CDCHandle dc)
|
| + {
|
| + // this one is not used
|
| + }
|
| +
|
| + void DoPaint(CDCHandle dc, RECT& rc)
|
| + {
|
| + CEnhMetaFileInfo emfinfo(m_meta);
|
| + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
|
| + int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
|
| + int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
|
| +
|
| + dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
|
| + dc.PlayMetaFile(m_meta, &rc);
|
| + }
|
| +
|
| +// Implementation - data
|
| + int m_nCurPage;
|
| +};
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CPrintPreviewWindow - Implements a print preview window
|
| +
|
| +template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
|
| +class ATL_NO_VTABLE CPrintPreviewWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTraits>, public CPrintPreview
|
| +{
|
| +public:
|
| + DECLARE_WND_CLASS_EX(NULL, CS_VREDRAW | CS_HREDRAW, -1)
|
| +
|
| + enum { m_cxOffset = 10, m_cyOffset = 10 };
|
| +
|
| +// Constructor
|
| + CPrintPreviewWindowImpl() : m_nMaxPage(0), m_nMinPage(0)
|
| + { }
|
| +
|
| +// Operations
|
| + void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode,
|
| + IPrintJobInfo* pji, int nMinPage, int nMaxPage)
|
| + {
|
| + CPrintPreview::SetPrintPreviewInfo(hPrinter, pDefaultDevMode, pji);
|
| + m_nMinPage = nMinPage;
|
| + m_nMaxPage = nMaxPage;
|
| + }
|
| +
|
| + bool NextPage()
|
| + {
|
| + if (m_nCurPage == m_nMaxPage)
|
| + return false;
|
| + SetPage(m_nCurPage + 1);
|
| + Invalidate();
|
| + return true;
|
| + }
|
| +
|
| + bool PrevPage()
|
| + {
|
| + if (m_nCurPage == m_nMinPage)
|
| + return false;
|
| + if (m_nCurPage == 0)
|
| + return false;
|
| + SetPage(m_nCurPage - 1);
|
| + Invalidate();
|
| + return true;
|
| + }
|
| +
|
| +// Message map and handlers
|
| + BEGIN_MSG_MAP(CPrintPreviewWindowImpl)
|
| + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
|
| + MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
| + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
|
| + END_MSG_MAP()
|
| +
|
| + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
| + {
|
| + return 1; // no need for the background
|
| + }
|
| +
|
| + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
| + {
|
| + T* pT = static_cast<T*>(this);
|
| + RECT rc = { 0 };
|
| +
|
| + if(wParam != NULL)
|
| + {
|
| + pT->DoPrePaint((HDC)wParam, rc);
|
| + pT->DoPaint((HDC)wParam, rc);
|
| + }
|
| + else
|
| + {
|
| + CPaintDC dc(m_hWnd);
|
| + pT->DoPrePaint(dc.m_hDC, rc);
|
| + pT->DoPaint(dc.m_hDC, rc);
|
| + }
|
| +
|
| + return 0;
|
| + }
|
| +
|
| +// Painting helper
|
| + void DoPrePaint(CDCHandle dc, RECT& rc)
|
| + {
|
| + RECT rcClient = { 0 };
|
| + GetClientRect(&rcClient);
|
| + RECT rcArea = rcClient;
|
| + T* pT = static_cast<T*>(this);
|
| + pT; // avoid level 4 warning
|
| + ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
|
| + if (rcArea.left > rcArea.right)
|
| + rcArea.right = rcArea.left;
|
| + if (rcArea.top > rcArea.bottom)
|
| + rcArea.bottom = rcArea.top;
|
| + GetPageRect(rcArea, &rc);
|
| + CRgn rgn1, rgn2;
|
| + rgn1.CreateRectRgnIndirect(&rc);
|
| + rgn2.CreateRectRgnIndirect(&rcClient);
|
| + rgn2.CombineRgn(rgn1, RGN_DIFF);
|
| + dc.SelectClipRgn(rgn2);
|
| + dc.FillRect(&rcClient, COLOR_BTNSHADOW);
|
| + dc.SelectClipRgn(NULL);
|
| + dc.FillRect(&rc, (HBRUSH)::GetStockObject(WHITE_BRUSH));
|
| + }
|
| +
|
| +// Implementation - data
|
| + int m_nMinPage;
|
| + int m_nMaxPage;
|
| +};
|
| +
|
| +
|
| +class CPrintPreviewWindow : public CPrintPreviewWindowImpl<CPrintPreviewWindow>
|
| +{
|
| +public:
|
| + DECLARE_WND_CLASS_EX(_T("WTL_PrintPreview"), CS_VREDRAW | CS_HREDRAW, -1)
|
| +};
|
| +
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// CZoomPrintPreviewWindowImpl - Implements print preview window with zooming
|
| +
|
| +#ifdef __ATLSCRL_H__
|
| +
|
| +template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
|
| +class ATL_NO_VTABLE CZoomPrintPreviewWindowImpl : public CPrintPreviewWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T >
|
| +{
|
| +public:
|
| + bool m_bSized;
|
| +
|
| + CZoomPrintPreviewWindowImpl()
|
| + {
|
| + SetScrollExtendedStyle(SCRL_DISABLENOSCROLL);
|
| + InitZoom();
|
| + }
|
| +
|
| + // should be called to reset data members before recreating window
|
| + void InitZoom()
|
| + {
|
| + m_bSized = false;
|
| + m_nZoomMode = ZOOMMODE_OFF;
|
| + m_fZoomScaleMin = 1.0;
|
| + m_fZoomScale = 1.0;
|
| + }
|
| +
|
| + BEGIN_MSG_MAP(CZoomPrintPreviewWindowImpl)
|
| + MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
|
| + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
|
| + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
|
| + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
|
| +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
|
| + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
|
| +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
|
| + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
|
| + MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown)
|
| + MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
|
| + MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
|
| + MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged)
|
| + MESSAGE_HANDLER(WM_SIZE, OnSize)
|
| + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
|
| + MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
| + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
|
| + ALT_MSG_MAP(1)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
|
| + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
|
| + END_MSG_MAP()
|
| +
|
| + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
| + {
|
| + SIZE sizeClient = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
| + POINT ptOffset = m_ptOffset;
|
| + SIZE sizeAll = m_sizeAll;
|
| + SetScrollSize(sizeClient);
|
| + if(sizeAll.cx > 0)
|
| + ptOffset.x = ::MulDiv(ptOffset.x, m_sizeAll.cx, sizeAll.cx);
|
| + if(sizeAll.cy > 0)
|
| + ptOffset.y = ::MulDiv(ptOffset.y, m_sizeAll.cy, sizeAll.cy);
|
| + SetScrollOffset(ptOffset);
|
| + CScrollImpl< T >::OnSize(uMsg, wParam, lParam, bHandled);
|
| + if(!m_bSized)
|
| + {
|
| + m_bSized = true;
|
| + T* pT = static_cast<T*>(this);
|
| + pT->ShowScrollBar(SB_HORZ, TRUE);
|
| + pT->ShowScrollBar(SB_VERT, TRUE);
|
| + }
|
| + return 0;
|
| + }
|
| +
|
| + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
| + {
|
| + return 1;
|
| + }
|
| +
|
| + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
| + {
|
| + T* pT = static_cast<T*>(this);
|
| + RECT rc = { 0 };
|
| +
|
| + if(wParam != NULL)
|
| + {
|
| + CDCHandle dc = (HDC)wParam;
|
| + int nMapModeSav = dc.GetMapMode();
|
| + dc.SetMapMode(MM_ANISOTROPIC);
|
| + SIZE szWindowExt = { 0, 0 };
|
| + dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
|
| + SIZE szViewportExt = { 0, 0 };
|
| + dc.SetViewportExt(m_sizeAll, &szViewportExt);
|
| + POINT ptViewportOrg = { 0, 0 };
|
| + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
|
| +
|
| + pT->DoPrePaint(dc, rc);
|
| + pT->DoPaint(dc, rc);
|
| +
|
| + dc.SetMapMode(nMapModeSav);
|
| + dc.SetWindowExt(szWindowExt);
|
| + dc.SetViewportExt(szViewportExt);
|
| + dc.SetViewportOrg(ptViewportOrg);
|
| + }
|
| + else
|
| + {
|
| + CPaintDC dc(pT->m_hWnd);
|
| + pT->PrepareDC(dc.m_hDC);
|
| + pT->DoPrePaint(dc.m_hDC, rc);
|
| + pT->DoPaint(dc.m_hDC, rc);
|
| + }
|
| +
|
| + return 0;
|
| + }
|
| +
|
| + // Painting helpers
|
| + void DoPaint(CDCHandle dc)
|
| + {
|
| + // this one is not used
|
| + }
|
| +
|
| + void DoPrePaint(CDCHandle dc, RECT& rc)
|
| + {
|
| + RECT rcClient;
|
| + GetClientRect(&rcClient);
|
| + RECT rcArea = rcClient;
|
| + T* pT = static_cast<T*>(this);
|
| + pT; // avoid level 4 warning
|
| + ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
|
| + if (rcArea.left > rcArea.right)
|
| + rcArea.right = rcArea.left;
|
| + if (rcArea.top > rcArea.bottom)
|
| + rcArea.bottom = rcArea.top;
|
| + GetPageRect(rcArea, &rc);
|
| + HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW));
|
| + dc.PatBlt(rcClient.left, rcClient.top, rc.left - rcClient.left, rcClient.bottom - rcClient.top, PATCOPY);
|
| + dc.PatBlt(rc.left, rcClient.top, rc.right - rc.left, rc.top - rcClient.top, PATCOPY);
|
| + dc.PatBlt(rc.right, rcClient.top, rcClient.right - rc.right, rcClient.bottom - rcClient.top, PATCOPY);
|
| + dc.PatBlt(rc.left, rc.bottom, rc.right - rc.left, rcClient.bottom - rc.bottom, PATCOPY);
|
| + dc.SelectBrush((HBRUSH)::GetStockObject(WHITE_BRUSH));
|
| + dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
|
| + dc.SelectBrush(::GetSysColorBrush(COLOR_3DDKSHADOW));
|
| + dc.PatBlt(rc.right, rc.top + 4, 4, rc.bottom - rc.top, PATCOPY);
|
| + dc.PatBlt(rc.left + 4, rc.bottom, rc.right - rc.left, 4, PATCOPY);
|
| + dc.SelectBrush(hbrOld);
|
| + }
|
| +
|
| + void DoPaint(CDCHandle dc, RECT& rc)
|
| + {
|
| + CEnhMetaFileInfo emfinfo(m_meta);
|
| + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
|
| + int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
|
| + int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
|
| +
|
| + dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
|
| + dc.PlayMetaFile(m_meta, &rc);
|
| + }
|
| +};
|
| +
|
| +class CZoomPrintPreviewWindow : public CZoomPrintPreviewWindowImpl<CZoomPrintPreviewWindow>
|
| +{
|
| +public:
|
| + DECLARE_WND_CLASS_EX(_T("WTL_ZoomPrintPreview"), CS_VREDRAW | CS_HREDRAW, -1)
|
| +};
|
| +
|
| +#endif // __ATLSCRL_H__
|
| +
|
| +}; // namespace WTL
|
| +
|
| +#endif // __ATLPRINT_H__
|
|
|