611 lines
16 KiB
C++
611 lines
16 KiB
C++
/*****************************************************************************
|
|
*
|
|
* (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)
|
|
{
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|