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

📄 prposterdatafile.cpp

📁 虚拟打印机
💻 CPP
字号:
/* * * prposterdatafile.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com * */#include "prposterdatafile.h"#include "..\lib\crc.h"#include "..\lib\devmode.h"#include "..\lib\gdiutils.h"#include "..\lib\renderpages.h"#include "..\lib\utils.h"#define MAGIC_CCH			16	static const DWORD PRPOSTERDATAFILE_VERSION = 0x100;extern const char g_achMagic[];// ********************************************************************// **  MODULE PRIVATE TYPES  ******************************************// ********************************************************************struct PRPosterDataFileRef {	PRPosterDataFileRef(void) { hFile = INVALID_HANDLE_VALUE; ulCrc = 0; nPageCount = nPagesWritten = 0; }	HANDLE hFile;	uint nPageCount;	uint nPagesWritten;	unsigned long ulCrc;			// CALCULATED FOR THE ENTIRE FILE EXCEPTING THE FINAL									// UNSIGNED LONG CRC VALUE ITSELF	tstring tstrFileName;};struct PRPosterDataFileHeader {	char achMagic[MAGIC_CCH];	DWORD dwVersion;	uint nPageCount;	BOOL CheckMagic(void) const { return memcmp(achMagic, g_achMagic, sizeof(achMagic)) == 0; }};// ********************************************************************// **  MODULE PRIVATE PROTOTYPES  *************************************// ********************************************************************BOOL MyWriteFile(HANDLE hFile, IN PCBYTE pData, IN size_t szCbData, IN OUT unsigned long& ulCrc) ;BOOL MyWriteFile(HANDLE hFile, IN const tstring& tstr, IN OUT unsigned long& ulCrc);// ********************************************************************// **  MODULE PRIVATE GLOBAL VARIABLES  *******************************// ********************************************************************static const char g_achMagic[MAGIC_CCH] = { 'P', 'R', 'P', 'O', 'S', 'T', 'E', 'R', 'D', 'A', 'T', 'A', 'F', 'I', 'L', 'E' };// ********************************************************************// **  class PRPosterDataFile  ****************************************// ********************************************************************PRPosterDataFile::PRPosterDataFile() {	// NOTHING TO DO}// DEBUG/FIX DOES THE BASE CLASS NEED TO HAVE A DESTRUCTOR FOR THIS TO BE SAFE??PRPosterDataFile::~PRPosterDataFile() {	if (this->IsOpen()) {		this->Close();	}	ASSERT(!IsOpen());	ASSERT(this->m_vpi.size() == 0);}BOOL PRPosterDataFile::Open(const tstring& tstrFileName)  {	BOOL bRetValue = FALSE;	try {		BOOL bIOError = FALSE;		if (!m_mfm.Open(tstrFileName)) {			bIOError = TRUE;		}		// CHECK THE CRC		if (!bIOError) {			DWORD dwCbFile = m_mfm.GetSize();			if (dwCbFile >= sizeof(unsigned long)) {				LPCVOID lpv = m_mfm.GetBasePtr();				unsigned long ulCrcCalculated = ::CalculateCrc( (const unsigned char*) lpv, dwCbFile - sizeof(unsigned long));				unsigned long ulCrcStored = * (const unsigned long *) m_mfm.GetOffsetPtr(dwCbFile - sizeof(unsigned long));				if (ulCrcCalculated != ulCrcStored) {					bIOError = TRUE;				}			} else {				bIOError = TRUE;			}		}		// CHECK THE HEADER		DWORD dwOffset = 0;		uint nPageCount = 0;		if (!bIOError) {			const PRPosterDataFileHeader header = * (const PRPosterDataFileHeader *) m_mfm.GetOffsetPtr(dwOffset);			dwOffset += sizeof(header);			if (header.CheckMagic()) {				nPageCount = header.nPageCount;			} else {				bIOError = TRUE;			}		}		if (! bIOError) {			m_tstrJobName = (LPCTSTR) m_mfm.GetOffsetPtr(dwOffset);			dwOffset += (DWORD) ::StringBufferSize(m_tstrJobName.c_str());			for(uint kPage = 0; kPage < nPageCount; ++kPage) {				PRPosterDataFile::PageInfo &pi = *m_vpi.insert(m_vpi.end(), PRPosterDataFile::PageInfo());				pi.tstrTargetPrinterName = (LPCTSTR) m_mfm.GetOffsetPtr(dwOffset);				dwOffset += (DWORD) ::StringBufferSize(pi.tstrTargetPrinterName.c_str());				pi.spd = * (const PRPosterDataFile::SimplePageData *) m_mfm.GetOffsetPtr(dwOffset);				dwOffset += sizeof(pi.spd);				if (pi.spd.bHasTargetPrinterDM) {					PCDEVMODE pdmTemp = (PCDEVMODE) m_mfm.GetOffsetPtr(dwOffset);					pi.pdmTargetPrinter = ::DM_Duplicate(pdmTemp);					dwOffset += ::DM_GetTotalSize(pi.pdmTargetPrinter);				}				pi.dwEMFOffset = dwOffset;				dwOffset += pi.spd.dwCbMetaFile;			}			bRetValue = TRUE;		}	} catch( ... ) {		bRetValue = FALSE;	}	return bRetValue;}void PRPosterDataFile::Close(void) {	ASSERT(this->IsOpen());	m_tstrJobName.erase();	m_vpi.clear();	m_mfm.Close();}BOOL PRPosterDataFile::IsOpen(void) const {	return m_mfm.IsOpen();}BOOL PRPosterDataFile::GetAutoRotate(IN uint uiPage, OUT BOOL& bAutoRotate) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	bAutoRotate = pi.spd.bAutoRotate;	return TRUE;}BOOL PRPosterDataFile::GetEvenPageMargins(IN uint uiPage, OUT BOOL& bEvenPageMargins) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	bEvenPageMargins = pi.spd.bEvenPageMargins;	return TRUE;}const tstring & PRPosterDataFile::GetJobName(void) const {	ASSERT(this->IsOpen());	return m_tstrJobName;}BOOL PRPosterDataFile::GetLandscape(IN uint uiPage, OUT BOOL& bLandscape) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	bLandscape = pi.spd.bLandscape;	return TRUE;}//BOOL PRPosterDataFile::GetNoCutGuidelines(IN uint uiPage, OUT BOOL& bNoCutGuidelines) const {//	ASSERT(this->IsOpen());//	ASSERT(uiPage < this->GetPageCount());//	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];//	bNoCutGuidelines = pi.spd.bNoCutGuides;//	return TRUE;//}uint PRPosterDataFile::GetPageCount(void) const {	ASSERT(this->IsOpen());	uint nPageCount = (uint) m_vpi.size();	return nPageCount;}HENHMETAFILE PRPosterDataFile::GetPageEMF(uint uiPage) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	HENHMETAFILE hMeta = ::SetEnhMetaFileBits(pi.spd.dwCbMetaFile, (PCBYTE) m_mfm.GetOffsetPtr(pi.dwEMFOffset));	return hMeta;}BOOL PRPosterDataFile::GetSourcePageSpec(IN uint uiPage, OUT ::PageSpec& ps) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	ps = pi.spd.psOriginal;	return TRUE;}BOOL PRPosterDataFile::GetResizedSourceSpec(IN uint uiPage, OUT ::SourceSpec& ssResized) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	ssResized = pi.spd.ssResized;	return TRUE;}// CALLER IS RESPONSIBLE FOR FREEING RETURNED MALLOC'D BUFFER . NULL INDICATES ERRORPDEVMODE PRPosterDataFile::GetTargetPrinter(IN uint uiPage, OUT tstring& tstrTargetPrinterName) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	PDEVMODE pdm = NULL;	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	//7/13	//tstrTargetPrinterName = pi.tstrTargetPrinterName;	//PDEVMODE pdm = ::DM_Duplicate(pi.pdmTargetPrinter);	//return pdm;	if (pi.pdmTargetPrinter != NULL) {		tstrTargetPrinterName = pi.tstrTargetPrinterName;		pdm = ::DM_Duplicate(pi.pdmTargetPrinter);	}	return pdm;}BOOL PRPosterDataFile::GetResizedRenderSpec(IN uint uiPage, OUT ::RenderSpec& rs) const {	ASSERT(this->IsOpen());	ASSERT(uiPage < this->GetPageCount());	const PRPosterDataFile::PageInfo& pi = m_vpi[uiPage];	rs = pi.spd.rsResized;	return TRUE;}// ****// **** static routines:  class PRPosterDataFile // ****PRPosterDataFileHandle PRPosterDataFile::TheirWritePosterDataFileHeader(	IN const tstring& tstrFileName, 	IN const tstring& tstrJobName,	IN uint nPageCount) {	PRPosterDataFileHandle h = new PRPosterDataFileRef;	if (h != NULL) {				h->tstrFileName = tstrFileName;		h->nPageCount = nPageCount;		try {			BOOL bSuccess = FALSE;			h->hFile = CreateFile( 				h->tstrFileName.c_str(),				GENERIC_WRITE,           				FILE_SHARE_READ,        				NULL,                   				CREATE_ALWAYS,          				FILE_ATTRIBUTE_NORMAL,  				NULL                     				);			if (h->hFile != INVALID_HANDLE_VALUE) {				::PRPosterDataFileHeader header;				CopyMemory(header.achMagic, g_achMagic, sizeof(header.achMagic));				header.dwVersion = PRPOSTERDATAFILE_VERSION;				header.nPageCount = h->nPageCount;				if (::MyWriteFile(h->hFile, (PCBYTE) &header, sizeof(header), h->ulCrc)) {					if (::MyWriteFile(h->hFile, tstrJobName, h->ulCrc)) {							bSuccess = TRUE;					}				}			}			if (!bSuccess) {				if (h->hFile != INVALID_HANDLE_VALUE) {					::DeleteFile(tstrFileName.c_str());				}				delete h;				h = NULL;			}		} catch(...) {			if (h != NULL) {				if (h->hFile != INVALID_HANDLE_VALUE) {					::CloseHandle(h->hFile);				}				delete h;				h = NULL;			}		}	}	return h;}BOOL PRPosterDataFile::TheirWritePosterDataFilePage(	PRPosterDataFileHandle h,	IN const tstring& tstrTargetPrinterName,	IN PCDEVMODE pdmTargetPrinter,	IN BOOL bLandscape,	//IN BOOL bNoCutGuides,	IN BOOL bAutoRotate,	IN BOOL bEvenPageMargins,	IN const ::PageSpec& psOriginal,	//IN const ::RECTD& rdSourceSelection_Inches,	IN const ::SourceSpec& ssResized, 	IN const ::RenderSpec& rsResized,	IN HENHMETAFILE hMeta) {	PRPosterDataFile::SimplePageData spd;	spd.bAutoRotate = bAutoRotate;	spd.bEvenPageMargins = bEvenPageMargins;	spd.bHasTargetPrinterDM = (pdmTargetPrinter != NULL);	spd.bLandscape = bLandscape;	//spd.bNoCutGuides = bNoCutGuides;	spd.psOriginal = psOriginal;	spd.rsResized = rsResized;	spd.ssResized = ssResized;	ASSERT(h != NULL && h->hFile != INVALID_HANDLE_VALUE);	BOOL bRetValue = FALSE;	PVOID pvMetaData = ::MyGetEnhMetaFileBits(hMeta, spd.dwCbMetaFile);	if (pvMetaData != NULL) {		try {			if (::MyWriteFile(h->hFile, tstrTargetPrinterName, h->ulCrc)) {				if (::MyWriteFile(h->hFile, (PCBYTE) &spd, sizeof(spd), h->ulCrc)) {					if ( ! spd.bHasTargetPrinterDM || ::MyWriteFile(h->hFile, (PCBYTE) pdmTargetPrinter, ::DM_GetTotalSize(pdmTargetPrinter), h->ulCrc)) {						if (::MyWriteFile(h->hFile, (PCBYTE) pvMetaData, spd.dwCbMetaFile, h->ulCrc)) {							bRetValue = TRUE;						}					}				}			}			free(pvMetaData);		} catch(...) {			free(pvMetaData);		}	}	if (bRetValue) {		++ h->nPagesWritten;	}	return bRetValue;}BOOL PRPosterDataFile::TheirClosePosterDataFile(PRPosterDataFileHandle h, BOOL bSuccess) {	BOOL bRetValue = TRUE;	ASSERT(h != NULL && h->hFile != INVALID_HANDLE_VALUE);	ASSERT(	!bSuccess || h->nPageCount == h->nPagesWritten );	if (bSuccess) {		unsigned long ulTemp = h->ulCrc;		try {			if ( ! ::MyWriteFile(h->hFile, (PCBYTE) &h->ulCrc, sizeof(h->ulCrc), ulTemp)) {				bSuccess = FALSE;				bRetValue = FALSE;			}		} catch(...) {			bSuccess = FALSE;			bRetValue = FALSE;		}	}	::CloseHandle(h->hFile);	if (! bSuccess) {		::DeleteFile(h->tstrFileName.c_str());	}	delete h;	return bRetValue;}// **********************************************************************************// **  MODULE PRIVATE ROUTINES  ****************************************************// **********************************************************************************static BOOL MyWriteFile(HANDLE hFile, IN PCBYTE pData, IN size_t szCbData, IN OUT unsigned long& ulCrc) {	BOOL bRetValue = FALSE;	DWORD dwCbWritten;	BOOL b = WriteFile(hFile, pData, (DWORD) szCbData, &dwCbWritten, NULL);	if (b && szCbData == dwCbWritten) {		ulCrc = ::CalculateCrc(pData, szCbData, ulCrc);		bRetValue = TRUE;	}	return bRetValue;}BOOL MyWriteFile(HANDLE hFile, IN const tstring& tstr, IN OUT unsigned long& ulCrc) {	BOOL b = ::MyWriteFile(hFile, (PCBYTE) tstr.c_str(), ::StringBufferSize(tstr.c_str()), ulCrc);	return b;}

⌨️ 快捷键说明

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