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

📄 atlprint.h

📁 文件加密器使用说明 本软件可以加密需要保护的数据文件
💻 H
📖 第 1 页 / 共 2 页
字号:
	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;
		HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID);
		::CloseHandle(hThread);

		return (hThread != NULL);
	}

// 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 helper
	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)
	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);
		CPaintDC dc(m_hWnd);
		RECT rcClient;
		GetClientRect(&rcClient);
		RECT rcArea = rcClient;
		::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;
		RECT rc;
		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));
		pT->DoPaint(dc.m_hDC, rc);
		return 0;
	}

// 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)
};

}; //namespace WTL

#endif // __ATLPRINT_H__

⌨️ 快捷键说明

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