|
|
/*****************************************************************************
* * (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 <precomp.h>
#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
<Notes>
*****************************************************************************/
CStatusPage::CStatusPage( CWizardInfoBlob * pBlob ) : _hDlg(NULL), _hWorkerThread(NULL), _dwWorkerThreadId(0), _pWizInfo(pBlob) { WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::CStatusPage()"))); if (_pWizInfo) { _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;
if (pnmh) { 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;
}
|