📄 previewdialog_printpages.cpp
字号:
/* * * previewdialog_printpages.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 "previewdialog_printpages.h"#include "previewdialog.h"#include "previewdialog_switches.h"#include "prlistviewdialog.h"#include "prpreviewutils.h"#include "resource.h"#include "..\lib\dialogwindow.h"#include "..\lib\devmode.h"#include "..\lib\gdiutils.h"#include "..\lib\mathutils.h"#include "..\lib\progressdialog.h"#include "..\lib\prspoolerdatafile.h"#include "..\lib\renderpages.h"#include "..\lib\spoolutils.h"#include "..\lib\types.h"#include "..\lib\workerthread.h"#include <strsafe.h>#include <vector>#define TIMER_ID 100#define STATUSUPDATE_TIMER_MS 100#define PROGRESS_RADIOBUTTON_NUMBER 6#define PROGRESS_RADIOBUTTON_FIRST IDC_RADIO_PROGRESS_1#define MAX_STATUS_CCH 128BOOL CALLBACK AbortProc(HDC hdc, int nCode) ;// *************************************************************************************************// ** MODULE PRIVATE TYPEDEFS ********************************************************************// *************************************************************************************************class PrintOptionsDialog : public DialogWindow {public: enum UserSelection { eError, eCancel, ePrintResizedAll, ePrintResizedSelection, ePrintCurrentOriginal, ePrintAllOriginal }; PrintOptionsDialog( IN HINSTANCE hinst, const tstring& tstrTitle, BOOL bOriginalButtons, BOOL bResizedSelectionButton, const tstring& tstrOriginalTargetPrinterName ) : DialogWindow(hinst, IDD_DIALOG_PRINT_OPTIONS), m_tstrTitle(tstrTitle), m_bOriginalButtons(bOriginalButtons), m_bResizedSelectionButton(bResizedSelectionButton), m_tstrOriginalTargetPrinterName(tstrOriginalTargetPrinterName) {}protected: BOOL InitMsg(WPARAM wParam, LPARAM lParam) { DialogWindow::InitMsg(wParam, lParam); this->EnableDlgItem(IDC_BUTTON_PRINT_PAGE_ORIGINAL, m_bOriginalButtons); this->EnableDlgItem(IDC_BUTTON_PRINT_ALL_ORIGINAL, m_bOriginalButtons); if (m_bOriginalButtons) { HWND hwndOriginalTargetPrinter = this->GetDlgItem(IDC_STATIC_ORIGINAL_TARGETPRINTER_NAME); this->SetDlgItemText(IDC_STATIC_ORIGINAL_TARGETPRINTER_NAME, m_tstrOriginalTargetPrinterName.c_str()); } else { HWND hwndOriginalInfo = this->GetDlgItem(IDC_STATIC_ORIGINALPAGES_INFO); ::ShowWindow(hwndOriginalInfo, SW_HIDE); } this->EnableDlgItem(IDC_BUTTON_PRINT_PAGE_RESIZED_SELECTION, m_bResizedSelectionButton); this->CenterWindowAboveParent(); this->SetWindowText(m_tstrTitle.c_str()); return TRUE; } BOOL CommandMsg(WPARAM wParam, LPARAM lParam) { WORD wID = LOWORD(wParam); switch(wID) { case IDC_BUTTON_PRINT_PAGE_RESIZED: this->EndDialog( PrintOptionsDialog::ePrintResizedAll ); break; case IDC_BUTTON_PRINT_PAGE_RESIZED_SELECTION: this->EndDialog( PrintOptionsDialog::ePrintResizedSelection ); break; case IDC_BUTTON_PRINT_PAGE_ORIGINAL: this->EndDialog( PrintOptionsDialog::ePrintCurrentOriginal ); break; case IDC_BUTTON_PRINT_ALL_ORIGINAL: this->EndDialog( PrintOptionsDialog::ePrintAllOriginal ); break; case IDCANCEL: // FALL THRU case IDC_BUTTON_CANCEL: this->EndDialog( PrintOptionsDialog::eCancel ); break; default: ASSERTFAIL(); break; } return TRUE; }private: tstring m_tstrTitle; BOOL m_bOriginalButtons; BOOL m_bResizedSelectionButton; tstring m_tstrOriginalTargetPrinterName;};class PrintPages : public WorkerThread { //: private ProgressDialogWindow {public: enum PrintResultCode { eSucceeded, eSomePrintedWithErrors, eFailed, eUserCanceled }; PrintPages( //IN HINSTANCE hinst, //tstring& tstrTitle, uint nPages, LPCTSTR lptstrPrinterName, //PCDEVMODE pdm, const ::DOCINFO& docinfo, class ProgressDialogWindow *pdw ); virtual ~PrintPages(); PrintPages::PrintResultCode DoPrint(void /*HWND hwndParent*/); uint GetCount(void) const { return m_nPages; }protected: enum PrintState { eStartingUp, eInitializing, ePrintingPages, eDonePrintingPages, eAllDone }; const tstring& GetPrinterName(void) const { return m_tstrPrinterName; } // *** REQUIRED WorkerThread INTERFACE **** virtual void DoWork(void) { this->DoPrint(); } // *** END OF REQUIRED WorkerThread INTERFACE **** void MySetStatusString(PrintPages::PrintState code, BOOL bSomePrinted, uint uiPage) ; virtual PDEVMODE GetDevModeForPage(uint uiPage) = 0; virtual int RenderPrintedPage(HDC hdc, IN const SIZE& szPrintable, uint uiPage) = 0; // //DEBUG // DWORD dw1 = ::GetTickCount(); // while(GetTickCount() < dw1 + 3000) { // MSG msg; // if (PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE)) { // // COMPLER BUG?? // //if ( ! ::DialogWindow::TheirIsDialogMessage(msg) ) { // TranslateMessage(&msg); // DispatchMessage(&msg); // //} // } // } // return 1; //}private: //PrintPages::Status m_status; uint m_nPages; //::PDEVMODE m_pdm; tstring m_tstrPrinterName; ::DOCINFO m_di; //HDC m_hdc; class ProgressDialogWindow *m_pdw;};class PrintResizedPages : public PrintPages {public: 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 ); virtual ~PrintResizedPages();protected: // *** REQUIRED PrintPages INTERFACE *** virtual PDEVMODE GetDevModeForPage(uint uiPage) ; virtual int RenderPrintedPage(HDC hdc, IN const SIZE& szPrintable, uint uiPage) ; // *** END OF REQUIRED PrintPages INTERFACE ***private: HENHMETAFILE m_hMeta; ::RenderSpec m_rs; ::PageSpec m_ps; ::SourceSpec m_ss; std::vector<POINT> m_vptPages; PDEVMODE m_pdm;};class PrintOriginalPages : public PrintPages {public: // WE SHARE, DON'T OWN, THE SPOOLER DATA FILE // THREAD SAFENESS DEPENDS ON THE FACT ALL CALLS WE WILL MAKE ARE 'CONST' // AND THE FACT THAT MAPPED MEMORY FROM A FILE IS GUARANTEED COHERENT FOR ALL PROCESSES // ON A SINGLE MACHINE ALSO CAN'T HURT PrintOriginalPages( uint uiFirstPage, uint nPages, class PRSpoolerDataFile *pprsdf, LPCTSTR lptstrPrinterName, const ::DOCINFO& docinfo, class ProgressDialogWindow *pdw ); virtual ~PrintOriginalPages();protected: // *** REQUIRED PrintPages INTERFACE *** virtual PDEVMODE GetDevModeForPage(uint uiPage) ; virtual int RenderPrintedPage(HDC hdc, IN const SIZE& szPrintable, uint uiPage) ; // *** END OF REQUIRED PrintPages INTERFACE ***private: uint m_uiFirstPage; class PRSpoolerDataFile *m_pprsdf;};// ************************************************************************************************// ** class PreviewDialog members **************************************************************// ************************************************************************************************void PreviewDialog::OnPrintCommand(void) { PRListViewDialog* pprlvdResized = this->GetResizedDialog(); tstring tstrPrinterName; if (this->ReadSelectedPrinter(tstrPrinterName)) { BOOL bOriginalButtons = (m_pDataSource->GetDataSourceType() == ::PrintPreviewDataSources::ePrintSpoolerDataFile); BOOL bResizedSelectionButton = pprlvdResized->HasSelectionItems(); tstring tstrTitle; this->ComposeDialogTitle(tstrTitle, TEXT("Print Options")); tstring tstrOriginalTargetPrinterName; if (bOriginalButtons) { // FOR SPOOLER DATA THE TARGET PRINTER NAME CANNOT CHANGE FROM PAGE TO PAGE, ALTHOUGH // THE DEVMODE CAN -- SO IT'S OK TO USE PAGE NUMBER 0 HERE PDEVMODE pdmTargetPrinter = m_pDataSource->GetTargetPrinter(0, tstrOriginalTargetPrinterName); if (pdmTargetPrinter == NULL) { this->ErrorMessage(TEXT("Unexpected error:Unable to determine original output printer.\n\nOriginal pages cannot be printed.")); bOriginalButtons = FALSE; } else { free(pdmTargetPrinter); } } PrintOptionsDialog *ppod = new PrintOptionsDialog(this->hinst(), tstrTitle, bOriginalButtons, bResizedSelectionButton, tstrOriginalTargetPrinterName); PrintOptionsDialog::UserSelection sel = (PrintOptionsDialog::UserSelection) ppod->DoModalDialog(this->hdlg()); switch(sel) { case PrintOptionsDialog::eCancel: // DO NOTHING break; case PrintOptionsDialog::ePrintResizedSelection: case PrintOptionsDialog::ePrintResizedAll: { BOOL bResizedAll = (sel == PrintOptionsDialog::ePrintResizedAll); uint uiPage; if (this->ReadSelectedPage(uiPage)) { tstring tstrDocName; if (bResizedAll) { tstrDocName = TEXT("Poster Pages"); } else { tstrDocName = TEXT("Selected Poster Pages"); } tstring tstrTitle; tstring tstrTemp = TEXT("Printing "); tstrTemp += tstrDocName; this->ComposeDialogTitle(tstrTitle, tstrTemp.c_str()); PDEVMODE pdm = m_pdmKeeper->GetDevMode(tstrPrinterName); BOOL bPrintInitialized = FALSE; if (pdm != NULL) { pdm->dmOrientation = m_psResized.bLandscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; if (m_pdmKeeper->SetDevMode()) { std::vector<POINT> vptPages; pprlvdResized->GetItemPointsInMosaic(vptPages, ! bResizedAll); tstrDocName += TEXT(" of "); tstrDocName += m_pDataSource->GetJobName(); ::DOCINFO di; ::ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = tstrDocName.c_str(); di.fwType = 0; // DEBUG / FIX SHOULD DEAL WITH FAILURE HEAR // DEBUG / FIX MAY WANT TO USE m_hMetaForPage INSTEAD (IF MODAL) HENHMETAFILE hMeta = m_pDataSource->GetPageEMF(uiPage); if (hMeta != NULL) { ProgressDialogWindow *pdw = new ProgressDialogWindow(this->hinst(), tstrTitle, di.lpszDocName); PrintResizedPages *pprp = new PrintResizedPages( //this->hinst(), hMeta, m_rsResized, m_psResized, m_ssResized, vptPages, //tstrTitle, tstrPrinterName.c_str(), pdm, di, pdw ); // DEBUG / FIX //::DebugBreak(); bPrintInitialized = TRUE; //pprp->DoPrint(this->hdlg()); // DEBUG / FIX ERROR TEST THE BOOL HERE pprp->StartNewDoWorkThread(); pdw->DoModalDialog(this->hdlg()); // pprp HAS A REFERENCE TO pdw, DELETE IT FIRST delete pprp; // THIS DIALOG WINDOW AN EXCEPTION, WAS SET NOT TO AUTOMATICALLY DELETE ITSELF delete pdw; } } } if (! bPrintInitialized ) { this->ErrorMessage(TEXT("Error initializing print.")); } } else { this->ErrorMessage(TEXT("No page selected to print.")); } } break; case PrintOptionsDialog::ePrintCurrentOriginal: { ASSERT(m_pDataSource->GetDataSourceType() == ::PrintPreviewDataSources::ePrintSpoolerDataFile); // BUG / FIX - BUTTONS SHOULD BE DISABLED uint uiPage; if (this->ReadSelectedPage(uiPage)) { tstring tstrDocName = m_pDataSource->GetJobName(); tstrDocName += TEXT(" page "); { TCHAR atstrBuff[MAX_LISTBOX_PAGES_CCH]; ::StringCchPrintf(atstrBuff, ARRCOUNT(atstrBuff), TEXT("%ld"), uiPage+1); tstrDocName += atstrBuff; } 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(uiPage, 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( uiPage, 1, (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")); } } else { this->ErrorMessage(TEXT("No page selected to print.")); } } break; case PrintOptionsDialog::ePrintAllOriginal: { ASSERT(m_pDataSource->GetDataSourceType() == ::PrintPreviewDataSources::ePrintSpoolerDataFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -