📄 prspoolerdatafile.cpp
字号:
/* * prspoolerdatafile.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 */// 6/25 DEBUG / FIX DONT SAVE A SEP COPY OF TARGET PRINTER DEVMODE, SINCE WE ARE TOO LAZY// TO DO THIS PROPERLY FOR EACH PAGE AS NEEDED#include "prspoolerdatafile.h"#include "buffer.h"#include "devmode.h"#include "printResizerCommon.h"#include "renderpages.h"#include <windows.h>static const DWORD PRSPOOLERDATAFILE_VERSION = 0x100;#define PRSPOOLERDATAFILE_MAGIC { 'P', 'R', 'S', 'P', 'O', 'O', 'L', 'E', 'R', 'D', 'A', 'T', 'A', 'F', 'I', 'L', 'E' }// ********************************************************************// ** MODULE PRIVATE TYPES *****************************************// ********************************************************************struct PRDataFileHeader { char acMagic[17]; DWORD dwVersion; BOOL operator ==(const PRDataFileHeader& prdfh) const { return memcmp(this, &prdfh, sizeof(*this)) == 0; } BOOL operator !=(const PRDataFileHeader& prdfh) const { return ! ( *this == prdfh ); }};struct SplFileIterator { DWORD dwSize; DWORD dwOffset; union { PCBYTE pb; PCSPL_HEADER psplheader; PCSMR psmr; PCSMR_PAGE psmrpage; PCSMR_DEVMODE psmrdm; }; SplFileIterator(IN const MyFileMap& mfm, IN DWORD dwOffset) ; BOOL Next(void) ;};// ********************************************************************// ** MODULE PRIVATE GLOBALS ****************************************// ********************************************************************static const PRDataFileHeader g_prdfHeader = { PRSPOOLERDATAFILE_MAGIC, PRSPOOLERDATAFILE_VERSION };static const ::MarginSpec g_msOriginal = { 0, 0, 0, 0, 0, 0 };// ********************************************************************// ** MODULE PRIVATE PROTOTYPES *************************************// ********************************************************************BOOL MyWriteFile(HANDLE hFile, LPCVOID lpData, DWORD dwcData) ;BOOL MyWriteFile(HANDLE hFile, LPCTSTR lptstr) ;// ********************************************************************// ** MODULE PUBLIC ROUTINES ****************************************// ********************************************************************BOOL PRSpoolerDataFile::WriteUserInterfaceData(const tstring& tstrFileName, LPCTSTR lptstrPrinterName, PCEXTDEVMODE pextdm) { BOOL bRetValue = FALSE; HANDLE hFile = ::CreateFile( tstrFileName.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile != INVALID_HANDLE_VALUE) { try { if (::MyWriteFile(hFile, &g_prdfHeader, sizeof(g_prdfHeader))) { if (::MyWriteFile(hFile, lptstrPrinterName)) { if (::MyWriteFile(hFile, (LPCVOID) pextdm, (DWORD) EXTDM_Sizeof())) { bRetValue = TRUE; } } } ::CloseHandle(hFile); } catch(...) { bRetValue = FALSE; ::CloseHandle(hFile); ::DeleteFile(tstrFileName.c_str()); } } return bRetValue;}BOOL PRSpoolerDataFile::WritePrintProcessorData(const tstring& tstrFileName, HANDLE hPrinter) { BOOL bRetValue = FALSE; HANDLE hAppend = CreateFile( tstrFileName.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hAppend != INVALID_HANDLE_VALUE) { try { const DWORD dwcBuff = (DWORD) 1 << 16; Buffer buff((DWORD) 1 << 16); BOOL bIOError = FALSE; DWORD dwcRead = 0; do { dwcRead = 1; BOOL b = ReadPrinter(hPrinter, buff.GetPtr(), buff.GetSize(), &dwcRead); if (!b && dwcRead != 0) { // IT MAY CONSIDER A NO DATA CONDITION TO BE A FAIL bIOError = TRUE; break; } if (dwcRead != 0) { if (! MyWriteFile(hAppend, buff.GetPtr(), dwcRead)) { bIOError = TRUE; break; } } } while(dwcRead != 0); CloseHandle(hAppend); bRetValue = ! bIOError; } catch(...) { bRetValue = FALSE; CloseHandle(hAppend); } } return bRetValue;}// ***// *** PRSpoolerDataFile// ***PRSpoolerDataFile::PRSpoolerDataFile(void) { // NOTHING TO DO}PRSpoolerDataFile::~PRSpoolerDataFile() { // 6/2 if (this->IsOpen()) { this->Close(); } // FIX - MAYBE THIS SHOULD JUST CLOSE IF STILL OPEN ASSERT(!IsOpen()); ASSERT(this->m_vdmPages.size() == 0); ASSERT(m_tstrFileName.empty());}BOOL PRSpoolerDataFile::Open(const tstring& tstrFileName) { BOOL bRetValue = FALSE; ASSERT(!this->IsOpen()); ASSERT(m_vpi.size() == 0); ASSERT(m_vdmPages.size() == 0); ASSERT(m_tstrFileName.empty()); // DEBUG / FIX //::DebugBreak(); m_tstrFileName = tstrFileName; try { BOOL bIOError = FALSE; if (!m_mfm.Open(tstrFileName)) { bIOError = TRUE; } DWORD dwOffset = 0; if (!bIOError) { const PRDataFileHeader header = * (const PRDataFileHeader *) m_mfm.GetOffsetPtr(dwOffset); dwOffset += sizeof(header); if (header != g_prdfHeader) { bIOError = TRUE; } } if (!bIOError) { m_tstrPrinterName = (LPTSTR) m_mfm.GetOffsetPtr(dwOffset); dwOffset += (DWORD) ::StringBufferSize( m_tstrPrinterName.c_str() ); // DEBUG / FIX EVENTUALLY MAY NEED SOME KIND OF CONVERT DEVMODE CALL HERE, IF VERSION CHANGES PCEXTDEVMODE pextdmRead = (PCEXTDEVMODE) m_mfm.GetOffsetPtr(dwOffset); dwOffset += ::DM_GetTotalSize( (PCDEVMODE) pextdmRead); { PEXTDEVMODE pextdmTemp = (PEXTDEVMODE) DM_Duplicate( (PCDEVMODE) (PVOID) pextdmRead ); m_vdmPages.push_back(pextdmTemp); } SplFileIterator iter(m_mfm, dwOffset); if (iter.psplheader->SIGNATURE != SPLMETA_SIGNATURE) { bIOError = TRUE; } if (!bIOError) { m_tstrJobName = (LPCTSTR) (iter.pb + iter.psplheader->offDocumentName); uint nPages = 0; while(iter.Next()) { DWORD dwType = iter.psmr->iType; switch(dwType) { case SRT_PAGE: { PageInfo pi; pi.dwOffset = iter.dwOffset; pi.uiDMIndex = (uint) m_vdmPages.size() - 1; m_vpi.push_back(pi); } break; case SRT_DEVMODE: { ::PCSMR_DEVMODE p = iter.psmrdm; PDEVMODE pdmTemp = DM_Duplicate( (PCDEVMODE) p->DEVMODEData); m_vdmPages.push_back( (PEXTDEVMODE) pdmTemp ); // DEVMODE RECORD SEEMS TO FOLLOW THE EMF if (m_vpi.size() != 0) { uint uiPage = (uint) m_vpi.size() - 1; PageInfo& pi = m_vpi[uiPage]; pi.uiDMIndex = (uint) m_vdmPages.size() - 1; } } break; default: break; } } } } bRetValue = ! bIOError; } catch(...) { bRetValue = FALSE; } return bRetValue;}void PRSpoolerDataFile::Close(void) { ASSERT(IsOpen()); m_vpi.clear(); m_tstrJobName.erase(); for(uint k = 0; k < m_vdmPages.size(); ++k) { free(m_vdmPages[k]); } m_vdmPages.clear(); m_mfm.Close(); if (! m_tstrFileName.empty()) { ::DeleteFile(m_tstrFileName.c_str()); m_tstrFileName.erase(); }}const tstring &PRSpoolerDataFile::GetJobName(void) const { ASSERT(IsOpen()); return m_tstrJobName;}const tstring & PRSpoolerDataFile::GetPrinterName(void) const { ASSERT(IsOpen()); return m_tstrPrinterName;}uint PRSpoolerDataFile::GetPageCount(void) const { ASSERT(IsOpen()); uint ui = (uint) m_vpi.size(); return ui;}HENHMETAFILE PRSpoolerDataFile::GetPageEMF(uint uiPage) const { HENHMETAFILE hMeta = NULL; ASSERT(IsOpen()); ASSERT(uiPage < m_vpi.size()); try { PageInfo pi = m_vpi[uiPage]; PCSMR_PAGE psmrpage = (PCSMR_PAGE) m_mfm.GetOffsetPtr(pi.dwOffset); hMeta = SetEnhMetaFileBits(psmrpage->smr.nSize, psmrpage->EMFData); } catch( ... ) { // RETURN FAILURE CODE OF NULL } return hMeta;}BOOL PRSpoolerDataFile::GetSourcePageSpec(IN uint uiPage, OUT ::PageSpec& ps) const { BOOL bRetValue = FALSE; const tstring& tstrPrinterName = this->GetPrinterName(); PCDEVMODE pdm = (PCDEVMODE) this->GetPRDevMode(uiPage); if (pdm != NULL) { ::PageSpec psTemp; if (::GetPageSpec(psTemp, g_msOriginal, pdm, tstrPrinterName.c_str(), FALSE, FALSE)) { ps = psTemp; bRetValue = TRUE; } } return bRetValue;}PDEVMODE PRSpoolerDataFile::GetTargetPrinter(IN uint uiPage, OUT tstring& tstrTargetPrinterName) const { PDEVMODE pdmRetValue; PCEXTDEVMODE pextdm = GetPRDevMode(uiPage); LPCTSTR lptstrTargetPrinterName = ::EXTDM_GetTargetPrinterName(pextdm); PCDEVMODE pdmTarget = ::EXTDM_GetTargetPrinterDevMode(pextdm); if (pdmTarget != NULL) { pdmRetValue = ::DM_Duplicate(pdmTarget); if (pdmRetValue != NULL) { tstrTargetPrinterName = lptstrTargetPrinterName; } } return pdmRetValue;}BOOL PRSpoolerDataFile::GetResizedRenderSpec(IN uint uiPage, OUT ::RenderSpec& rs) const { // NO RENDERSPEC INFO STORED IN OUR SPOOLER DATA FILE CURRENTLY return FALSE;}//BOOL PRSpoolerDataFile::GetSourceSelection(IN uint uiPage, OUT ::RECTD& rdSourceSelection_Inches) const {// return FALSE;//}BOOL PRSpoolerDataFile::GetResizedSourceSpec(IN uint uiPage, OUT ::SourceSpec& ssResized) const { // NO SOURCESPEC INFO STORED IN OUR SPOOLER DATA FILE CURRENTLY return FALSE;}PCEXTDEVMODE PRSpoolerDataFile::GetPRHeaderDevMode(void) const { ASSERT(IsOpen()); PCEXTDEVMODE pextdm = m_vdmPages[0]; return pextdm;}PCEXTDEVMODE PRSpoolerDataFile::GetPRDevMode(uint uiPage) const { ASSERT(IsOpen()); ASSERT(uiPage < m_vpi.size()); PageInfo pi = m_vpi[uiPage]; PCEXTDEVMODE pextdm = m_vdmPages[pi.uiDMIndex]; return pextdm;}// ************************************************************************// ** PRIVATE TO MODULE ************************************************// ************************************************************************// ***// *** SplFileIterator// ***SplFileIterator::SplFileIterator(IN const MyFileMap& mfm, IN DWORD dwOffset) { this->dwSize = mfm.GetSize(); ASSERT(dwOffset < this->dwSize); this->pb = (PCBYTE) mfm.GetBasePtr() + dwOffset; this->dwOffset = dwOffset;}BOOL SplFileIterator::Next(void) { BOOL bRetValue = FALSE; DWORD dwNewOffset; DWORD dwcInc; // (SPL FILE HEADER RECORD ALSO STARTS W/SMR, WITH "iType" BEING THE SIGNATURE) dwcInc = this->psmr->nSize; if (this->psmr->iType != SPLMETA_SIGNATURE) { dwcInc += sizeof(SMR); } dwNewOffset = this->dwOffset + dwcInc; if (dwNewOffset < this->dwSize) { this->dwOffset = dwNewOffset; this->pb += dwcInc; if (this->psmr->iType != SRT_PAGE || this->psmr->nSize != 0 ) { bRetValue = TRUE; } } return bRetValue;}// ***// *** UTILITY ROUTINES// ***BOOL MyWriteFile(HANDLE hFile, LPCVOID lpData, DWORD dwcData) { BOOL bRetValue = FALSE; DWORD dwcWritten; BOOL b = WriteFile(hFile, lpData, dwcData, &dwcWritten, NULL); if (b && dwcData == dwcWritten) { bRetValue = TRUE; } return bRetValue;}BOOL MyWriteFile(HANDLE hFile, LPCTSTR lptstr) { DWORD dwCb = (DWORD) ::StringBufferSize(lptstr); BOOL bRetValue = MyWriteFile(hFile, (LPCVOID) lptstr, dwCb); return bRetValue;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -