Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

620 lines
17 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: status.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 11/7/00
  12. *
  13. * DESCRIPTION: Implements code for the printing status page of the
  14. * print photos wizard...
  15. *
  16. *****************************************************************************/
  17. #include <precomp.h>
  18. #pragma hdrstop
  19. BOOL g_bCancelPrintJob = FALSE;
  20. /*****************************************************************************
  21. PhotoPrintAbortProc
  22. Called by GDI to see if the print job should be canceled.
  23. *****************************************************************************/
  24. BOOL CALLBACK PhotoPrintAbortProc( HDC hDC, INT iError )
  25. {
  26. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("PhotoPrintAbortProc(0x%x, %d)"),hDC,iError));
  27. #ifdef DEBUG
  28. if (g_bCancelPrintJob)
  29. {
  30. WIA_TRACE((TEXT("PhotoPrintAbortProc: attempting to cancel print job...")))
  31. }
  32. #endif
  33. return (!g_bCancelPrintJob);
  34. }
  35. /*****************************************************************************
  36. CStatusPage -- constructor/desctructor
  37. <Notes>
  38. *****************************************************************************/
  39. CStatusPage::CStatusPage( CWizardInfoBlob * pBlob )
  40. : _hDlg(NULL),
  41. _hWorkerThread(NULL),
  42. _dwWorkerThreadId(0),
  43. _pWizInfo(pBlob)
  44. {
  45. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::CStatusPage()")));
  46. if (_pWizInfo)
  47. {
  48. _pWizInfo->AddRef();
  49. //
  50. // Create worker thread
  51. //
  52. _hWorkerThread = CreateThread( NULL,
  53. 0,
  54. CStatusPage::s_StatusWorkerThreadProc,
  55. (LPVOID)this,
  56. CREATE_SUSPENDED,
  57. &_dwWorkerThreadId );
  58. //
  59. // If we created the thread, set it's priority to slight below normal so other
  60. // things run okay. This can be a CPU intensive task...
  61. //
  62. if (_hWorkerThread)
  63. {
  64. SetThreadPriority( _hWorkerThread, THREAD_PRIORITY_BELOW_NORMAL );
  65. ResumeThread( _hWorkerThread );
  66. }
  67. }
  68. }
  69. CStatusPage::~CStatusPage()
  70. {
  71. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::~CStatusPage()")));
  72. if (_pWizInfo)
  73. {
  74. _pWizInfo->Release();
  75. _pWizInfo = NULL;
  76. }
  77. }
  78. VOID CStatusPage::ShutDownBackgroundThreads()
  79. {
  80. //
  81. // Shutdown the background thread...
  82. //
  83. _OnDestroy();
  84. //
  85. // Signify that we've shutdown our threads...
  86. //
  87. if (_pWizInfo)
  88. {
  89. _pWizInfo->StatusIsShutDown();
  90. }
  91. }
  92. /*****************************************************************************
  93. CStatusPage::_DoHandleThreadMessage
  94. Depending on the message received, does the work for the given message...
  95. *****************************************************************************/
  96. VOID CStatusPage::_DoHandleThreadMessage( LPMSG pMSG )
  97. {
  98. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_DoHandleThreadMessage()")));
  99. if (!pMSG)
  100. {
  101. WIA_ERROR((TEXT("pMSG is NULL, returning early!")));
  102. return;
  103. }
  104. switch (pMSG->message)
  105. {
  106. case PP_STATUS_PRINT:
  107. WIA_TRACE((TEXT("Got PP_STATUS_PRINT message")));
  108. if (_pWizInfo)
  109. {
  110. BOOL bDeleteDC = FALSE;
  111. //
  112. // Create an hDC for the printer...
  113. //
  114. HDC hDC = _pWizInfo->GetCachedPrinterDC();
  115. if (!hDC)
  116. {
  117. hDC = CreateDC( TEXT("WINSPOOL"), _pWizInfo->GetPrinterToUse(), NULL, _pWizInfo->GetDevModeToUse() );
  118. bDeleteDC = TRUE;
  119. }
  120. if (hDC)
  121. {
  122. DOCINFO di = {0};
  123. BOOL bCancel = FALSE;
  124. HWND hwndProgress = GetDlgItem( _hDlg, IDC_PRINT_PROGRESS );
  125. //
  126. // Set the progress meter to 0
  127. //
  128. if (hwndProgress)
  129. {
  130. PostMessage( hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0,100) );
  131. PostMessage( hwndProgress, PBM_SETPOS, 0, 0 );
  132. }
  133. //
  134. // turn on ICM for this hDC
  135. //
  136. SetICMMode( hDC, ICM_ON );
  137. di.cbSize = sizeof(DOCINFO);
  138. //
  139. // Lets use the template name for the document name...
  140. //
  141. CSimpleString strTitle;
  142. CTemplateInfo * pTemplateInfo = NULL;
  143. if (SUCCEEDED(_pWizInfo->GetTemplateByIndex( _pWizInfo->GetCurrentTemplateIndex() ,&pTemplateInfo)) && pTemplateInfo)
  144. {
  145. pTemplateInfo->GetTitle( &strTitle );
  146. }
  147. //
  148. // Let's remove the ':' at the end if there is one
  149. //
  150. INT iLen = strTitle.Length();
  151. if (iLen && (strTitle[(INT)iLen-1] == TEXT(':')))
  152. {
  153. strTitle.Truncate(iLen);
  154. }
  155. di.lpszDocName = strTitle;
  156. if (!_pWizInfo->IsWizardShuttingDown())
  157. {
  158. if (StartDoc( hDC, &di ) > 0)
  159. {
  160. HRESULT hr;
  161. INT iPageCount = 0;
  162. float fPercent = 0.0;
  163. MSG msg;
  164. g_bCancelPrintJob = FALSE;
  165. //
  166. // Set the abort proc...
  167. //
  168. if (SP_ERROR == SetAbortProc( hDC, PhotoPrintAbortProc ))
  169. {
  170. WIA_ERROR((TEXT("Got SP_ERROR trying to set AbortProc!")));
  171. }
  172. //
  173. // Loop through until we've printed all the photos...
  174. //
  175. if (SUCCEEDED(hr = _pWizInfo->GetCountOfPrintedPages( _pWizInfo->GetCurrentTemplateIndex(), &iPageCount )))
  176. {
  177. float fPageCount = (float)iPageCount;
  178. for (INT iPage = 0; !g_bCancelPrintJob && (iPage < iPageCount); iPage++)
  179. {
  180. //
  181. // Set which page we are on...
  182. //
  183. PostMessage( _hDlg, SP_MSG_UPDATE_PROGRESS_TEXT, (WPARAM)(iPage+1), (LPARAM)iPageCount );
  184. //
  185. // Print the page...
  186. //
  187. if (StartPage( hDC ) > 0)
  188. {
  189. //
  190. // Ensure that ICM mode stays on. Per MSDN docs
  191. // ICM mode gets reset after each StartPage call.
  192. //
  193. SetICMMode( hDC, ICM_ON );
  194. hr = _pWizInfo->RenderPrintedPage( _pWizInfo->GetCurrentTemplateIndex(), iPage, hDC, hwndProgress, (float)((float)100.0 / fPageCount), &fPercent );
  195. if ((hr != S_OK) && (hr != S_FALSE))
  196. {
  197. g_bCancelPrintJob = TRUE;
  198. }
  199. EndPage( hDC );
  200. }
  201. else
  202. {
  203. _pWizInfo->ShowError( _hDlg, HRESULT_FROM_WIN32(GetLastError()), IDS_ERROR_WHILE_PRINTING );
  204. WIA_ERROR((TEXT("PrintThread: StartPage failed w/GLE=%d"),GetLastError()));
  205. g_bCancelPrintJob = TRUE;
  206. }
  207. if (_pWizInfo->IsWizardShuttingDown())
  208. {
  209. g_bCancelPrintJob = TRUE;
  210. }
  211. }
  212. }
  213. }
  214. else
  215. {
  216. _pWizInfo->ShowError( _hDlg, HRESULT_FROM_WIN32(GetLastError()), IDS_ERROR_WHILE_PRINTING );
  217. WIA_ERROR((TEXT("PrintThread: StartDoc failed w/GLE = %d"),GetLastError()));
  218. g_bCancelPrintJob = TRUE;
  219. }
  220. }
  221. INT iOffset = -1;
  222. if (g_bCancelPrintJob)
  223. {
  224. //
  225. // If there was an error, or the job was cancelled, then abort it...
  226. //
  227. AbortDoc( hDC );
  228. }
  229. else
  230. {
  231. //
  232. // If printing succeeded, then end the job so it can be printed...
  233. //
  234. EndDoc( hDC );
  235. //
  236. // Set progress to 100 percent
  237. //
  238. if (hwndProgress)
  239. {
  240. PostMessage( hwndProgress, PBM_SETPOS, 100, 0 );
  241. Sleep(250);
  242. }
  243. //
  244. // Jump to next page...
  245. //
  246. iOffset = 1;
  247. }
  248. if (bDeleteDC)
  249. {
  250. DeleteDC( hDC );
  251. }
  252. WIA_TRACE((TEXT("iOffset from current page %d"),iOffset));
  253. PostMessage( _hDlg, SP_MSG_JUMP_TO_PAGE, 0, iOffset );
  254. }
  255. else
  256. {
  257. _pWizInfo->ShowError( _hDlg, (HRESULT)GetLastError(), IDS_ERROR_CREATEDC_FAILED );
  258. //
  259. // Jump back to printer selection page... (back 2 pages, thus -2)
  260. //
  261. PostMessage( _hDlg, SP_MSG_JUMP_TO_PAGE, 0, -2 );
  262. }
  263. }
  264. break;
  265. }
  266. }
  267. /*****************************************************************************
  268. CStatusPage::_OnInitDialog
  269. Handle initializing the wizard page...
  270. *****************************************************************************/
  271. LRESULT CStatusPage::_OnInitDialog()
  272. {
  273. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_OnInitDialog()")));
  274. if (!_pWizInfo)
  275. {
  276. WIA_ERROR((TEXT("FATAL: _pWizInfo is NULL, exiting early")));
  277. return FALSE;
  278. }
  279. _pWizInfo->SetStatusWnd( _hDlg );
  280. _pWizInfo->SetStatusPageClass( this );
  281. return TRUE;
  282. }
  283. /*****************************************************************************
  284. CStatusPage::CancelPrinting
  285. Called to stop the print job...
  286. *****************************************************************************/
  287. VOID CStatusPage::_CancelPrinting()
  288. {
  289. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage:_CancelPrinting()")));
  290. //
  291. // Pause the worker thread while we ask about cancelling printing...
  292. //
  293. if (_hWorkerThread)
  294. {
  295. SuspendThread( _hWorkerThread );
  296. }
  297. //
  298. // Check to see if the user wants to cancel printing...
  299. //
  300. INT iRes;
  301. CSimpleString strMessage(IDS_CANCEL_PRINT_MESSAGE, g_hInst);
  302. CSimpleString strCaption(IDS_CANCEL_PRINT_CAPTION, g_hInst);
  303. iRes = MessageBox( _hDlg,
  304. strMessage,
  305. strCaption,
  306. MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2 | MB_APPLMODAL | MB_SETFOREGROUND
  307. );
  308. g_bCancelPrintJob = (iRes == IDYES);
  309. //
  310. // Resume the thread now that the user has responded...
  311. //
  312. if (_hWorkerThread)
  313. {
  314. ResumeThread( _hWorkerThread );
  315. }
  316. }
  317. /*****************************************************************************
  318. CStatusPage::_OnDestroy
  319. Handles WM_DESTROY for printing status page...
  320. *****************************************************************************/
  321. LRESULT CStatusPage::_OnDestroy()
  322. {
  323. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_STATUS, TEXT("CStatusPage::_OnDestroy()")));
  324. if (_hWorkerThread && _dwWorkerThreadId)
  325. {
  326. WIA_TRACE((TEXT("Sending WM_QUIT to worker thread proc")));
  327. PostThreadMessage( _dwWorkerThreadId, WM_QUIT, 0, 0 );
  328. WiaUiUtil::MsgWaitForSingleObject( _hWorkerThread, INFINITE );
  329. WIA_TRACE((TEXT("_hWorkerThread handle signal'd, closing handle...")));
  330. CloseHandle( _hWorkerThread );
  331. _hWorkerThread = NULL;
  332. _dwWorkerThreadId = 0;
  333. }
  334. return FALSE;
  335. }
  336. /*****************************************************************************
  337. CStatusPage::_OnNotify
  338. Handle WM_NOTIFY
  339. *****************************************************************************/
  340. LRESULT CStatusPage::_OnNotify( WPARAM wParam, LPARAM lParam )
  341. {
  342. WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CStatusPage::_OnNotify()")));
  343. LONG_PTR lpRes = 0;
  344. LPNMHDR pnmh = (LPNMHDR)lParam;
  345. if (pnmh)
  346. {
  347. switch (pnmh->code)
  348. {
  349. case PSN_SETACTIVE:
  350. {
  351. WIA_TRACE((TEXT("CStatusPage: got PSN_SETACTIVE")));
  352. PropSheet_SetWizButtons( GetParent(_hDlg), 0 );
  353. //
  354. // Reset items
  355. //
  356. SendDlgItemMessage( _hDlg, IDC_PRINT_PROGRESS, PBM_SETPOS, 0, 0 );
  357. CSimpleString str( IDS_READY_TO_PRINT, g_hInst );
  358. SetDlgItemText( _hDlg, IDC_PRINT_PROGRESS_TEXT, str.String() );
  359. //
  360. // Start printing...
  361. //
  362. if (_hWorkerThread && _dwWorkerThreadId)
  363. {
  364. //
  365. // Start printing...
  366. //
  367. WIA_TRACE((TEXT("CStatusPage: posting PP_STATUS_PRINT message")));
  368. PostThreadMessage( _dwWorkerThreadId, PP_STATUS_PRINT, 0, 0 );
  369. }
  370. lpRes = 0;
  371. }
  372. break;
  373. case PSN_WIZBACK:
  374. case PSN_WIZNEXT:
  375. WIA_TRACE((TEXT("CStatusPage: got PSN_WIZBACK or PSN_WIZNEXT")));
  376. lpRes = -1;
  377. break;
  378. case PSN_QUERYCANCEL:
  379. {
  380. WIA_TRACE((TEXT("CStatusPage: got PSN_QUERYCANCEL")));
  381. _CancelPrinting();
  382. if (pnmh->code == PSN_QUERYCANCEL)
  383. {
  384. lpRes = (!g_bCancelPrintJob);
  385. if (!lpRes)
  386. {
  387. //
  388. // We're cancelling the dialog, so do cleanup...
  389. //
  390. if (_pWizInfo)
  391. {
  392. _pWizInfo->ShutDownWizard();
  393. }
  394. }
  395. }
  396. else
  397. {
  398. lpRes = -1;
  399. }
  400. }
  401. break;
  402. }
  403. }
  404. SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, lpRes );
  405. return TRUE;
  406. }
  407. /*****************************************************************************
  408. CStatusPage::DoHandleMessage
  409. Hanlder for messages sent to this page...
  410. *****************************************************************************/
  411. INT_PTR CStatusPage::DoHandleMessage( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  412. {
  413. WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CStatusPage::DoHandleMessage( uMsg = 0x%x, wParam = 0x%x, lParam = 0x%x )"),uMsg,wParam,lParam));
  414. static CSimpleString strFormat(IDS_PRINTING_PROGRESS,g_hInst);
  415. static CSimpleString strProgress;
  416. switch ( uMsg )
  417. {
  418. case WM_INITDIALOG:
  419. _hDlg = hDlg;
  420. return _OnInitDialog();
  421. case WM_COMMAND:
  422. if (LOWORD(wParam)==IDC_CANCEL_PRINTING)
  423. {
  424. if (HIWORD(wParam)==BN_CLICKED)
  425. {
  426. _CancelPrinting();
  427. }
  428. }
  429. break;
  430. case WM_DESTROY:
  431. return _OnDestroy();
  432. case WM_NOTIFY:
  433. return _OnNotify(wParam,lParam);
  434. case SP_MSG_UPDATE_PROGRESS_TEXT:
  435. strProgress.Format( strFormat, wParam, lParam );
  436. strProgress.SetWindowText( GetDlgItem( _hDlg, IDC_PRINT_PROGRESS_TEXT ) );
  437. break;
  438. case SP_MSG_JUMP_TO_PAGE:
  439. {
  440. HWND hwndCurrent = PropSheet_GetCurrentPageHwnd( GetParent(_hDlg) );
  441. INT iIndex = PropSheet_HwndToIndex( GetParent(_hDlg), hwndCurrent );
  442. PropSheet_SetCurSel( GetParent(_hDlg), NULL, iIndex + (INT)lParam );
  443. }
  444. break;
  445. }
  446. return FALSE;
  447. }