/***************************************************************************** * * (C) COPYRIGHT MICROSOFT CORPORATION, 2000 * * TITLE: status.cpp * * VERSION: 1.0 * * AUTHOR: RickTu * * DATE: 11/7/00 * * DESCRIPTION: Implements code for the printing status page of the * print photos wizard... * *****************************************************************************/ #include #pragma hdrstop BOOL g_bCancelPrintJob = FALSE; /***************************************************************************** PhotoPrintAbortProc Called by GDI to see if the print job should be canceled. *****************************************************************************/ BOOL CALLBACK PhotoPrintAbortProc( HDC hDC, INT iError ) { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("PhotoPrintAbortProc(0x%x, %d)"),hDC,iError)); #ifdef DEBUG if (g_bCancelPrintJob) { WIA_TRACE((TEXT("PhotoPrintAbortProc: attempting to cancel print job..."))) } #endif return (!g_bCancelPrintJob); } /***************************************************************************** CStatusPage -- constructor/desctructor *****************************************************************************/ CStatusPage::CStatusPage( CWizardInfoBlob * pBlob ) : _hDlg(NULL), _hWorkerThread(NULL), _dwWorkerThreadId(0) { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::CStatusPage()"))); _pWizInfo = pBlob; _pWizInfo->AddRef(); // // Create worker thread // _hWorkerThread = CreateThread( NULL, 0, CStatusPage::s_StatusWorkerThreadProc, (LPVOID)this, CREATE_SUSPENDED, &_dwWorkerThreadId ); // // If we created the thread, set it's priority to slight below normal so other // things run okay. This can be a CPU intensive task... // if (_hWorkerThread) { SetThreadPriority( _hWorkerThread, THREAD_PRIORITY_BELOW_NORMAL ); ResumeThread( _hWorkerThread ); } } CStatusPage::~CStatusPage() { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::~CStatusPage()"))); if (_pWizInfo) { _pWizInfo->Release(); _pWizInfo = NULL; } } VOID CStatusPage::ShutDownBackgroundThreads() { // // Shutdown the background thread... // _OnDestroy(); // // Signify that we've shutdown our threads... // if (_pWizInfo) { _pWizInfo->StatusIsShutDown(); } } /***************************************************************************** CStatusPage::_DoHandleThreadMessage Depending on the message received, does the work for the given message... *****************************************************************************/ VOID CStatusPage::_DoHandleThreadMessage( LPMSG pMSG ) { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_DoHandleThreadMessage()"))); if (!pMSG) { WIA_ERROR((TEXT("pMSG is NULL, returning early!"))); return; } switch (pMSG->message) { case PP_STATUS_PRINT: WIA_TRACE((TEXT("Got PP_STATUS_PRINT message"))); if (_pWizInfo) { BOOL bDeleteDC = FALSE; // // Create an hDC for the printer... // HDC hDC = _pWizInfo->GetCachedPrinterDC(); if (!hDC) { hDC = CreateDC( TEXT("WINSPOOL"), _pWizInfo->GetPrinterToUse(), NULL, _pWizInfo->GetDevModeToUse() ); bDeleteDC = TRUE; } if (hDC) { DOCINFO di = {0}; BOOL bCancel = FALSE; HWND hwndProgress = GetDlgItem( _hDlg, IDC_PRINT_PROGRESS ); // // Set the progress meter to 0 // if (hwndProgress) { PostMessage( hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100) ); PostMessage( hwndProgress, PBM_SETPOS, 0, 0 ); } // // turn on ICM for this hDC // SetICMMode( hDC, ICM_ON ); di.cbSize = sizeof(DOCINFO); // // Lets use the template name for the document name... // CSimpleString strTitle; CTemplateInfo * pTemplateInfo = NULL; if (SUCCEEDED(_pWizInfo->GetTemplateByIndex( _pWizInfo->GetCurrentTemplateIndex() ,&pTemplateInfo)) && pTemplateInfo) { pTemplateInfo->GetTitle( &strTitle ); } // // Let's remove the ':' at the end if there is one // INT iLen = strTitle.Length(); if (iLen && (strTitle[(INT)iLen-1] == TEXT(':'))) { strTitle.Truncate(iLen); } di.lpszDocName = strTitle; if (!_pWizInfo->IsWizardShuttingDown()) { if (StartDoc( hDC, &di ) > 0) { HRESULT hr; INT iPageCount = 0; float fPercent = 0.0; MSG msg; g_bCancelPrintJob = FALSE; // // Set the abort proc... // if (SP_ERROR == SetAbortProc( hDC, PhotoPrintAbortProc )) { WIA_ERROR((TEXT("Got SP_ERROR trying to set AbortProc!"))); } // // Loop through until we've printed all the photos... // if (SUCCEEDED(hr = _pWizInfo->GetCountOfPrintedPages( _pWizInfo->GetCurrentTemplateIndex(), &iPageCount ))) { float fPageCount = (float)iPageCount; for (INT iPage = 0; !g_bCancelPrintJob && (iPage < iPageCount); iPage++) { // // Set which page we are on... // PostMessage( _hDlg, SP_MSG_UPDATE_PROGRESS_TEXT, (WPARAM)(iPage+1), (LPARAM)iPageCount ); // // Print the page... // if (StartPage( hDC ) > 0) { // // Ensure that ICM mode stays on. Per MSDN docs // ICM mode gets reset after each StartPage call. // SetICMMode( hDC, ICM_ON ); hr = _pWizInfo->RenderPrintedPage( _pWizInfo->GetCurrentTemplateIndex(), iPage, hDC, hwndProgress, (float)((float)100.0 / fPageCount), &fPercent ); if ((hr != S_OK) && (hr != S_FALSE)) { g_bCancelPrintJob = TRUE; } EndPage( hDC ); } else { _pWizInfo->ShowError( _hDlg, HRESULT_FROM_WIN32(GetLastError()), IDS_ERROR_WHILE_PRINTING ); WIA_ERROR((TEXT("PrintThread: StartPage failed w/GLE=%d"),GetLastError())); g_bCancelPrintJob = TRUE; } if (_pWizInfo->IsWizardShuttingDown()) { g_bCancelPrintJob = TRUE; } } } } else { _pWizInfo->ShowError( _hDlg, HRESULT_FROM_WIN32(GetLastError()), IDS_ERROR_WHILE_PRINTING ); WIA_ERROR((TEXT("PrintThread: StartDoc failed w/GLE = %d"),GetLastError())); g_bCancelPrintJob = TRUE; } } INT iOffset = -1; if (g_bCancelPrintJob) { // // If there was an error, or the job was cancelled, then abort it... // AbortDoc( hDC ); } else { // // If printing succeeded, then end the job so it can be printed... // EndDoc( hDC ); // // Set progress to 100 percent // if (hwndProgress) { PostMessage( hwndProgress, PBM_SETPOS, 100, 0 ); Sleep(250); } // // Jump to next page... // iOffset = 1; } if (bDeleteDC) { DeleteDC( hDC ); } WIA_TRACE((TEXT("iOffset from current page %d"),iOffset)); PostMessage( _hDlg, SP_MSG_JUMP_TO_PAGE, 0, iOffset ); } else { _pWizInfo->ShowError( _hDlg, (HRESULT)GetLastError(), IDS_ERROR_CREATEDC_FAILED ); // // Jump back to printer selection page... (back 2 pages, thus -2) // PostMessage( _hDlg, SP_MSG_JUMP_TO_PAGE, 0, -2 ); } } break; } } /***************************************************************************** CStatusPage::_OnInitDialog Handle initializing the wizard page... *****************************************************************************/ LRESULT CStatusPage::_OnInitDialog() { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_OnInitDialog()"))); if (!_pWizInfo) { WIA_ERROR((TEXT("FATAL: _pWizInfo is NULL, exiting early"))); return FALSE; } _pWizInfo->SetStatusWnd( _hDlg ); _pWizInfo->SetStatusPageClass( this ); return TRUE; } /***************************************************************************** CStatusPage::CancelPrinting Called to stop the print job... *****************************************************************************/ VOID CStatusPage::_CancelPrinting() { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage:_CancelPrinting()"))); // // Pause the worker thread while we ask about cancelling printing... // if (_hWorkerThread) { SuspendThread( _hWorkerThread ); } // // Check to see if the user wants to cancel printing... // INT iRes; CSimpleString strMessage(IDS_CANCEL_PRINT_MESSAGE, g_hInst); CSimpleString strCaption(IDS_CANCEL_PRINT_CAPTION, g_hInst); iRes = MessageBox( _hDlg, strMessage, strCaption, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2 | MB_APPLMODAL | MB_SETFOREGROUND ); g_bCancelPrintJob = (iRes == IDYES); // // Resume the thread now that the user has responded... // if (_hWorkerThread) { ResumeThread( _hWorkerThread ); } } /***************************************************************************** CStatusPage::_OnDestroy Handles WM_DESTROY for printing status page... *****************************************************************************/ LRESULT CStatusPage::_OnDestroy() { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_OnDestroy()"))); if (_hWorkerThread && _dwWorkerThreadId) { WIA_TRACE((TEXT("Sending WM_QUIT to worker thread proc"))); PostThreadMessage( _dwWorkerThreadId, WM_QUIT, 0, 0 ); WiaUiUtil::MsgWaitForSingleObject( _hWorkerThread, INFINITE ); WIA_TRACE((TEXT("_hWorkerThread handle signal'd, closing handle..."))); CloseHandle( _hWorkerThread ); _hWorkerThread = NULL; _dwWorkerThreadId = 0; } return FALSE; } /***************************************************************************** CStatusPage::_OnNotify Handle WM_NOTIFY *****************************************************************************/ LRESULT CStatusPage::_OnNotify( WPARAM wParam, LPARAM lParam ) { WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CStatusPage::_OnNotify()"))); LONG_PTR lpRes = 0; LPNMHDR pnmh = (LPNMHDR)lParam; switch (pnmh->code) { case PSN_SETACTIVE: { WIA_TRACE((TEXT("CStatusPage: got PSN_SETACTIVE"))); PropSheet_SetWizButtons( GetParent(_hDlg), 0 ); // // Reset items // SendDlgItemMessage( _hDlg, IDC_PRINT_PROGRESS, PBM_SETPOS, 0, 0 ); CSimpleString str( IDS_READY_TO_PRINT, g_hInst ); SetDlgItemText( _hDlg, IDC_PRINT_PROGRESS_TEXT, str.String() ); // // Start printing... // if (_hWorkerThread && _dwWorkerThreadId) { // // Start printing... // WIA_TRACE((TEXT("CStatusPage: posting PP_STATUS_PRINT message"))); PostThreadMessage( _dwWorkerThreadId, PP_STATUS_PRINT, 0, 0 ); } lpRes = 0; } break; case PSN_WIZBACK: case PSN_WIZNEXT: WIA_TRACE((TEXT("CStatusPage: got PSN_WIZBACK or PSN_WIZNEXT"))); lpRes = -1; break; case PSN_QUERYCANCEL: { WIA_TRACE((TEXT("CStatusPage: got PSN_QUERYCANCEL"))); _CancelPrinting(); if (pnmh->code == PSN_QUERYCANCEL) { lpRes = (!g_bCancelPrintJob); if (!lpRes) { // // We're cancelling the dialog, so do cleanup... // if (_pWizInfo) { _pWizInfo->ShutDownWizard(); } } } else { lpRes = -1; } } break; } SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, lpRes ); return TRUE; } /***************************************************************************** CStatusPage::DoHandleMessage Hanlder for messages sent to this page... *****************************************************************************/ INT_PTR CStatusPage::DoHandleMessage( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CStatusPage::DoHandleMessage( uMsg = 0x%x, wParam = 0x%x, lParam = 0x%x )"),uMsg,wParam,lParam)); static CSimpleString strFormat(IDS_PRINTING_PROGRESS,g_hInst); static CSimpleString strProgress; switch ( uMsg ) { case WM_INITDIALOG: _hDlg = hDlg; return _OnInitDialog(); case WM_COMMAND: if (LOWORD(wParam)==IDC_CANCEL_PRINTING) { if (HIWORD(wParam)==BN_CLICKED) { _CancelPrinting(); } } break; case WM_DESTROY: return _OnDestroy(); case WM_NOTIFY: return _OnNotify(wParam,lParam); case SP_MSG_UPDATE_PROGRESS_TEXT: strProgress.Format( strFormat, wParam, lParam ); strProgress.SetWindowText( GetDlgItem( _hDlg, IDC_PRINT_PROGRESS_TEXT ) ); break; case SP_MSG_JUMP_TO_PAGE: { HWND hwndCurrent = PropSheet_GetCurrentPageHwnd( GetParent(_hDlg) ); INT iIndex = PropSheet_HwndToIndex( GetParent(_hDlg), hwndCurrent ); PropSheet_SetCurSel( GetParent(_hDlg), NULL, iIndex + (INT)lParam ); } break; } return FALSE; }