📄 prposterdatafile.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 + -