📄 previewdialog_printpages.cpp
字号:
uint uiStartPage = 0; uint nPages = m_pDataSource->GetPageCount(); ASSERT(nPages != 0); tstring tstrDocName = m_pDataSource->GetJobName(); tstrDocName += TEXT(" all pages"); tstring tstrTitle; { tstring tstrTemp = TEXT("Printing "); tstrTemp += tstrDocName; this->ComposeDialogTitle(tstrTitle, tstrTemp.c_str()); } ::DOCINFO di; ::ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = tstrDocName.c_str(); di.fwType = 0; tstring tstrTargetPrinterName; PDEVMODE pdmTargetPrinter = m_pDataSource->GetTargetPrinter(uiStartPage, tstrTargetPrinterName); if (pdmTargetPrinter != NULL) { free(pdmTargetPrinter); if (::IsPrinterInstalled(tstrTargetPrinterName.c_str())) { BOOL bPrintInitialized = FALSE; ProgressDialogWindow *pdw = new ProgressDialogWindow(this->hinst(), tstrTitle, di.lpszDocName); ::PrintOriginalPages *ppop = new ::PrintOriginalPages( uiStartPage, nPages, (PRSpoolerDataFile*) m_pDataSource, tstrTargetPrinterName.c_str(), di, pdw ); if (ppop->StartNewDoWorkThread()) { bPrintInitialized = TRUE; pdw->DoModalDialog(this->hdlg()); } // pprp HAS A REFERENCE TO pdw, DELETE IT FIRST delete ppop; // THIS DIALOG WINDOW AN EXCEPTION, WAS SET NOT TO AUTOMATICALLY DELETE ITSELF delete pdw; if (! bPrintInitialized ) { this->ErrorMessage(TEXT("Error initializing print.")); } } else { tstring tstrMessage = TEXT("Original target printer "); tstrMessage += tstrTargetPrinterName; tstrMessage += TEXT(" is not accessible"); this->ErrorMessage(tstrMessage.c_str()); } } else { this->ErrorMessage(TEXT("Unexpected error, unable to determine original target printer")); } } break; case PrintOptionsDialog::eError: // FALL THRU break; default: this->ErrorMessage(TEXT("There was an error.")); break; } } else { //7/13 // THE ONLY WAY THERE WOULD BE NO TARGET PRINTER SELECTED IS IF THERE ARE NO PRINTERS INSTALLED AT ALL this->ErrorMessage(TEXT("No printers appear to be installed on this system.")); }}// **********************************************************************************// ** MODULE PRIVATE CLASS: PrintPages *******************************************// **********************************************************************************PrintPages::PrintPages( //IN HINSTANCE hinst, //tstring& tstrTitle, uint nPages, LPCTSTR lptstrPrinterName, //PCDEVMODE pdm, const ::DOCINFO& docinfo, class ProgressDialogWindow *pdw ) //: ::ProgressDialogWindow(hinst, tstrTitle, tstring(docinfo.lpszDocName)){ m_nPages = nPages; //m_pdm = ::DM_Duplicate(pdm); m_tstrPrinterName = lptstrPrinterName; m_di = docinfo; //m_hdc = NULL; m_pdw = pdw; this->MySetStatusString(PrintPages::eStartingUp, FALSE, 0);}PrintPages::~PrintPages() { this->PeekMessagesUntilTerminate(); //if (m_pdm != NULL) { // free(m_pdm); //}}PrintPages::PrintResultCode PrintPages::DoPrint(void /*HWND hwndParent*/) { uint ui = 0; BOOL bSomePrinted = FALSE; this->MySetStatusString(PrintPages::eInitializing, bSomePrinted, 0); //this->DoCreateDialog(hwndParent); // FIX - MAYBE THE PRINTING SHOUDL BE THE NEW THREAD AND NOT THE DIALOG // THIS WAY WE ARE TYING UP PART OF THE UI THREAD, IF PRINTING IS NEW THREAD // ALL UI IS IN A SEP THREAD //this->DoNewThreadModalDialog(hwndParent); // FIX / DEBUG //this->ShowWindow(SW_NORMAL); ASSERT(m_nPages > 0); PDEVMODE pdm = this->GetDevModeForPage(0); if (pdm != NULL) { HDC hdc = ::CreateDC(pdm, FALSE); if (hdc != NULL) { ::SetAbortProc(hdc, AbortProc); SIZE szPrintable = { ::GetDeviceCaps(hdc, HORZRES), ::GetDeviceCaps(hdc, VERTRES) }; int iStartDocResult = ::StartDoc(hdc, &m_di); if (iStartDocResult > 0) { this->MySetStatusString(PrintPages::ePrintingPages, bSomePrinted, 0); for(ui = 0; ui < m_nPages; ++ui) { { PDEVMODE pdmNew = this->GetDevModeForPage(ui); if (pdmNew != NULL) { DWORD dwCbNew = ::DM_GetTotalSize(pdmNew); DWORD dwCbOld = ::DM_GetTotalSize(pdm); if (dwCbNew != dwCbOld || memcmp(pdm, pdmNew, dwCbOld) != 0) { ::ResetDC(hdc, pdmNew); swap(pdm, pdmNew); } free(pdmNew); } else { break; } } this->MySetStatusString(PrintPages::ePrintingPages, bSomePrinted, ui); int iStartPageResult = ::StartPage(hdc); if (iStartPageResult <= 0 || m_pdw->GetStatusUserCanceled()) { break; } int iRenderResult = this->RenderPrintedPage(hdc, szPrintable, ui); if (iRenderResult <= 0 || m_pdw->GetStatusUserCanceled()) { break; } int iEndPageResult = ::EndPage(hdc); if (iEndPageResult <= 0 || m_pdw->GetStatusUserCanceled()) { break; } bSomePrinted = TRUE; } if (ui != m_nPages) { m_pdw->SetStatusErrors(); } this->MySetStatusString(PrintPages::eDonePrintingPages, bSomePrinted, ui); int iEndDocResult = ::EndDoc(hdc); if (iEndDocResult <= 0) { m_pdw->SetStatusErrors(); this->MySetStatusString(PrintPages::eDonePrintingPages, bSomePrinted, ui); } } else { m_pdw->SetStatusErrors(); } ::DeleteDC(hdc); hdc = NULL; } else { // if (hdc != NULL) m_pdw->SetStatusErrors(); } free(pdm); } m_pdw->SetStatusAllDone(); this->MySetStatusString(PrintPages::eAllDone, bSomePrinted, ui); m_pdw->CenterWindowAboveParent(); m_pdw->SetForegroundWindow(); ProgressDialogWindow::Status status = m_pdw->GetStatus(); PrintPages::PrintResultCode retValue; if (status.bUserCanceled) { retValue = PrintPages::eUserCanceled; } else if (status.bErrors) { if (bSomePrinted) { retValue = PrintPages::eSomePrintedWithErrors; } else { retValue = PrintPages::eFailed; } } else { retValue = PrintPages::eSucceeded; } return retValue;}// ****// **** protected: class PrintPages// ****void PrintPages::MySetStatusString(PrintPages::PrintState code, BOOL bSomePrinted, uint uiPage) { TCHAR atstrBuff[MAX_STATUS_CCH]; atstrBuff[0] = 0; // IN CASE WE WANT TO CONCATENATE INTO BUFFER W/O HAVING WRITTEN ANTYHING ELSE TO IT ::ProgressDialogWindow::Status status = m_pdw->GetStatus(); switch(code) { case eStartingUp: // FALL THRU case eInitializing: ::StringCchPrintf(atstrBuff, ARRCOUNT(atstrBuff), TEXT("Initializing. Preparing to print %d pages."), m_nPages); break; // uiPage + 1 IS PAGE WE ARE WORKING ON case ePrintingPages: ::StringCchPrintf(atstrBuff, ARRCOUNT(atstrBuff), TEXT("Printing page %d of %d"), uiPage+1, m_nPages); if (status.bErrors) { ::StringCchCat(atstrBuff, ARRCOUNT(atstrBuff), TEXT("\n\nErrors occured.")); } break; // uiPage IS NUMBER OF PAGES COMPLETED case eDonePrintingPages: if (bSomePrinted) { ::StringCchPrintf(atstrBuff, ARRCOUNT(atstrBuff), TEXT("Printing of %d pages of %d complete. Finalizing print."), uiPage, m_nPages); } if (status.bErrors) { ::StringCchCat(atstrBuff, ARRCOUNT(atstrBuff), TEXT("\n\nErrors occured.")); } break; // uiPage IS NUMBER OF PAGES COMPLETED case eAllDone: if (bSomePrinted) { ::StringCchPrintf(atstrBuff, ARRCOUNT(atstrBuff), TEXT("Completed. Printed %d pages of %d."), uiPage, m_nPages); if (status.bUserCanceled) { ::StringCchCat(atstrBuff, ARRCOUNT(atstrBuff), TEXT("\n\nCanceled by user.")); } else if (status.bErrors) { ::StringCchCat(atstrBuff, ARRCOUNT(atstrBuff), TEXT("\n\nErrors occured.")); } } else { ::StringCchCopy(atstrBuff, ARRCOUNT(atstrBuff), TEXT("Print FAILED.")); } break; default: ASSERTFAIL(); break; } tstring tstrStatus = atstrBuff; m_pdw->SetStatusString(tstrStatus);}// **********************************************************************************// ** MODULE PRIVATE CLASS: PrintrEesizedPages ***********************************// **********************************************************************************PrintResizedPages::PrintResizedPages( //IN HINSTANCE hinst, HENHMETAFILE hMeta, const ::RenderSpec& rs, const ::PageSpec& ps, const ::SourceSpec& ss, const std::vector<POINT>& vptPages, //tstring& tstrTitle, LPCTSTR lptstrPrinterName, PCDEVMODE pdm, const ::DOCINFO& docinfo, class ProgressDialogWindow *pdw) : PrintPages(/*hinst, tstrTitle,*/ (uint) vptPages.size(), lptstrPrinterName, /*pdm, */ docinfo, pdw){ m_hMeta = hMeta; m_rs = rs; m_ps = ps; m_ss = ss; m_vptPages = vptPages; m_pdm = ::DM_Duplicate(pdm);}PrintResizedPages::~PrintResizedPages() { ::DeleteEnhMetaFile(m_hMeta); if (m_pdm != NULL) { free(m_pdm); }}// *****// ***** protected: PrintResizedPages// *****PDEVMODE PrintResizedPages::GetDevModeForPage(uint uiPage) { PDEVMODE pdmRetValue = NULL; if (m_pdm != NULL) { pdmRetValue = ::DM_Duplicate(m_pdm); } return pdmRetValue;}int PrintResizedPages::RenderPrintedPage(HDC hdc, IN const SIZE& szPrintable, uint uiPage) { RECT rDest = { 0, 0, szPrintable.cx, szPrintable.cy }; POINT ptPage = m_vptPages[uiPage]; ::RenderMosaicPage(hdc, rDest, ptPage, m_rs, m_ps, m_hMeta, m_ss); return 1;}// **********************************************************************************// ** MODULE PRIVATE CLASS: PrintOriginalPages ***********************************// **********************************************************************************PrintOriginalPages::PrintOriginalPages( uint uiFirstPage, uint nPages, class PRSpoolerDataFile *pprsdf, LPCTSTR lptstrPrinterName, const ::DOCINFO& di, class ProgressDialogWindow *pdw) : PrintPages(nPages, lptstrPrinterName, di, pdw){ m_uiFirstPage = uiFirstPage; m_pprsdf = pprsdf;}PrintOriginalPages::~PrintOriginalPages() { // NOTHING TO DELETE}PDEVMODE PrintOriginalPages::GetDevModeForPage(uint uiPage) { uint uiActualPage = m_uiFirstPage + uiPage; tstring tstrTargetPrinterName; PDEVMODE pdmRetValue = m_pprsdf->GetTargetPrinter(uiActualPage, tstrTargetPrinterName); return pdmRetValue;}int PrintOriginalPages::RenderPrintedPage(HDC hdc, IN const SIZE& szPrintable, uint uiPage) { int iRetValue = 0; // FAILURE BY DEFAULT PDEVMODE pdm = this->GetDevModeForPage(uiPage); if (pdm != NULL) { uint uiActualPage = m_uiFirstPage + uiPage; HENHMETAFILE hMeta = m_pprsdf->GetPageEMF(uiActualPage); if (hMeta != NULL) { try { RECTD rdFrame_Inches; if (::GetEnhMetafileFrame_Inches(rdFrame_Inches, hMeta)) { ::SourceSpec ss = { rdFrame_Inches, rdFrame_Inches }; ::MarginSpec ms; ::ZeroMemory(&ms, sizeof(ms)); // GetPageSpec AUTOMATICALLY WILL USE SMALLEST POSSIBLE MARGINS ::PageSpec ps; const tstring& tstrPrinterName = this->GetPrinterName(); if (::GetPageSpec(ps, ms, pdm, tstrPrinterName.c_str(), FALSE, FALSE)) { ::RenderSpec rs; rs.bCenter = FALSE; rs.bCutGuides = FALSE; rs.dZoom = 1; rs.mode = ::RenderSpec::eZoom; rs.szMosaic.cx = 1; rs.szMosaic.cy = 1; RECT rDest = { 0, 0, szPrintable.cx, szPrintable.cy }; POINT ptPage = { 0, 0 }; ::RenderMosaicPage(hdc, rDest, ptPage, rs, ps, hMeta, ss); iRetValue = 1; } // if (::GetPageSpec(ps, ms, pdm, tstrPrinterName.c_str(), FALSE, FALSE)) } // if (::GetEnhMetafileFrame_Inches(rdFrame_Inches, hMeta)) ::DeleteEnhMetaFile(hMeta); } catch(...) { ::DeleteEnhMetaFile(hMeta); throw; } } // if (hMeta != NULL) free(pdm); } // if (pdm != NULL) return iRetValue;}// **********************************************************************************// ** MODULE PRIVATE ROUTINES *****************************************************// **********************************************************************************static BOOL CALLBACK AbortProc(HDC hdc, int nCode) { BOOL bRetValue = TRUE; MSG msg; if (nCode == 0 || nCode == SP_OUTOFDISK) { while (PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE)) { if ( ! ::DialogWindow::TheirIsDialogMessage(msg) ) { TranslateMessage(&msg); DispatchMessage(&msg); } } } else { bRetValue = FALSE; } return bRetValue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -