⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlprint.h

📁 一个与传统电子字典不同的字典
💻 H
📖 第 1 页 / 共 2 页
字号:
// 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -