Source code of Windows XP (NT5)
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.

1008 lines
27 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: printopt.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 10/18/00
  12. *
  13. * DESCRIPTION: Implements code for the print options page of the
  14. * print photos wizard...
  15. *
  16. *****************************************************************************/
  17. #include <precomp.h>
  18. #pragma hdrstop
  19. #define LENGTH_OF_MEDIA_NAME 64
  20. /*****************************************************************************
  21. EnumPrintersWrap -- Wrapper function for spooler API EnumPrinters
  22. Arguments:
  23. pServerName - Specifies the name of the print server
  24. level - Level of PRINTER_INFO_x structure
  25. pcPrinters - Returns the number of printers enumerated
  26. dwFlags - Flag bits passed to EnumPrinters
  27. Return Value:
  28. Pointer to an array of PRINTER_INFO_x structures
  29. NULL if there is an error
  30. *****************************************************************************/
  31. PVOID
  32. EnumPrintersWrap(
  33. LPTSTR pServerName,
  34. DWORD level,
  35. PDWORD pcPrinters,
  36. DWORD dwFlags
  37. )
  38. {
  39. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::EnumPrintersWrap()")));
  40. PBYTE pPrinterInfo = NULL;
  41. int iTry = -1;
  42. DWORD cbNeeded = 0;
  43. BOOL bStatus = FALSE;
  44. for( ;; )
  45. {
  46. if( iTry++ >= ENUM_MAX_RETRY )
  47. {
  48. // max retry count reached. this is also
  49. // considered out of memory case
  50. break;
  51. }
  52. // call EnumPrinters...
  53. bStatus = EnumPrinters(dwFlags, pServerName, level, pPrinterInfo, cbNeeded, &cbNeeded, pcPrinters);
  54. if( !bStatus && (ERROR_INSUFFICIENT_BUFFER == GetLastError()) && cbNeeded )
  55. {
  56. // buffer too small case
  57. if (pPrinterInfo)
  58. {
  59. delete [] pPrinterInfo;
  60. }
  61. WIA_TRACE((TEXT("EnumPrintersWrap: trying to allocate %d bytes"),cbNeeded));
  62. if( pPrinterInfo = (PBYTE) new BYTE[cbNeeded] )
  63. {
  64. continue;
  65. }
  66. }
  67. break;
  68. }
  69. if( bStatus )
  70. {
  71. return pPrinterInfo;
  72. }
  73. //
  74. // clean up if fail
  75. //
  76. if (pPrinterInfo)
  77. {
  78. delete [] pPrinterInfo;
  79. }
  80. return NULL;
  81. }
  82. /*****************************************************************************
  83. GetPrinterWrap -- Wrapper function for GetPrinter spooler API
  84. Arguments:
  85. szPrinterName - Printer name
  86. dwLevel - Specifies the level of PRINTER_INFO_x structure requested
  87. Return Value:
  88. Pointer to a PRINTER_INFO_x structure, NULL if there is an error
  89. *****************************************************************************/
  90. PVOID
  91. GetPrinterWrap(
  92. LPTSTR szPrinterName,
  93. DWORD dwLevel
  94. )
  95. {
  96. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::GetPrinterWrap()")));
  97. int iTry = -1;
  98. HANDLE hPrinter = NULL;
  99. PBYTE pPrinterInfo = NULL;
  100. DWORD cbNeeded = 0;
  101. BOOL bStatus = FALSE;
  102. PRINTER_DEFAULTS PrinterDefaults;
  103. PrinterDefaults.pDatatype = NULL;
  104. PrinterDefaults.pDevMode = NULL;
  105. PrinterDefaults.DesiredAccess = PRINTER_READ; //PRINTER_ALL_ACCESS;
  106. if (!OpenPrinter( szPrinterName, &hPrinter, &PrinterDefaults )) {
  107. return NULL;
  108. }
  109. for( ;; )
  110. {
  111. if( iTry++ >= ENUM_MAX_RETRY )
  112. {
  113. // max retry count reached. this is also
  114. // considered out of memory case
  115. WIA_TRACE(("Exceed max retries..."));
  116. break;
  117. }
  118. // call EnumPrinters...
  119. bStatus = GetPrinter( hPrinter, dwLevel, pPrinterInfo, cbNeeded, &cbNeeded );
  120. if( !bStatus && (ERROR_INSUFFICIENT_BUFFER == GetLastError()) && cbNeeded )
  121. {
  122. // buffer too small case
  123. if (pPrinterInfo)
  124. {
  125. delete [] pPrinterInfo;
  126. }
  127. WIA_TRACE((TEXT("GetPrinterWrap: trying to allocate %d bytes"),cbNeeded));
  128. if( pPrinterInfo = (PBYTE) new BYTE[cbNeeded] )
  129. {
  130. continue;
  131. }
  132. }
  133. break;
  134. }
  135. ClosePrinter( hPrinter );
  136. if( bStatus )
  137. {
  138. return pPrinterInfo;
  139. }
  140. //
  141. // clean up if fail
  142. //
  143. if (pPrinterInfo)
  144. {
  145. delete [] pPrinterInfo;
  146. }
  147. return NULL;
  148. }
  149. #ifdef FILTER_OUT_FAX_PRINTER
  150. #include <faxreg.h>
  151. /*****************************************************************************
  152. IsFaxPrinter -- test whether the given printer is a fax printer
  153. Arguments:
  154. szPrinterName - Printer name
  155. pPrinterInfo - PRINTER_INFO_2 printer info of given printer
  156. if they both have value, we only check szPrinterName.
  157. Return Value:
  158. TRUE if given printer is a fax printer, FALSE otherwise
  159. *****************************************************************************/
  160. BOOL
  161. IsFaxPrinter (
  162. LPTSTR szPrinterName,
  163. PPRINTER_INFO_2 pPrinterInfo
  164. )
  165. {
  166. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::IsFaxPrinter( %s )"),szPrinterName ? szPrinterName : TEXT("NULL POINTER!")));
  167. BOOL bRet = FALSE;
  168. if( !szPrinterName && !pPrinterInfo )
  169. {
  170. return FALSE;
  171. }
  172. if( szPrinterName )
  173. {
  174. pPrinterInfo = (PPRINTER_INFO_2)GetPrinterWrap( szPrinterName, 2 );
  175. if( pPrinterInfo )
  176. {
  177. bRet = (0 == lstrcmp( pPrinterInfo->pDriverName, FAX_DRIVER_NAME )) ||
  178. ( pPrinterInfo->Attributes & PRINTER_ATTRIBUTE_FAX );
  179. delete [] pPrinterInfo;
  180. return bRet;
  181. }
  182. else
  183. {
  184. WIA_ERROR((TEXT("Can't get printer info for %s!"), szPrinterName));
  185. }
  186. }
  187. return ((0 == lstrcmp(pPrinterInfo->pDriverName, FAX_DRIVER_NAME)) ||
  188. (pPrinterInfo->Attributes & PRINTER_ATTRIBUTE_FAX));
  189. }
  190. #endif
  191. /*****************************************************************************
  192. CPrintOptionsPage -- constructor/desctructor
  193. <Notes>
  194. *****************************************************************************/
  195. CPrintOptionsPage::CPrintOptionsPage( CWizardInfoBlob * pBlob ) :
  196. _hLibrary( NULL ),
  197. _pfnPrinterSetup( NULL )
  198. {
  199. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::CPrintOptionsPage()")));
  200. _pWizInfo = pBlob;
  201. if (_pWizInfo)
  202. {
  203. _pWizInfo->AddRef();
  204. }
  205. }
  206. CPrintOptionsPage::~CPrintOptionsPage()
  207. {
  208. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::~CPrintOptionsPage()")));
  209. if (_pWizInfo)
  210. {
  211. _pWizInfo->Release();
  212. _pWizInfo = NULL;
  213. }
  214. _FreePrintUI();
  215. }
  216. /*****************************************************************************
  217. CPrintOptionsPage::_bLoadLibrary -- load library printui.dll
  218. Return value: TRUE for success, FALSE for error
  219. *****************************************************************************/
  220. BOOL CPrintOptionsPage::_LoadPrintUI( )
  221. {
  222. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_LoadPrintUI()")));
  223. if (_hLibrary && _pfnPrinterSetup)
  224. {
  225. WIA_TRACE((TEXT("_LoadPrintUI: already loaded printui, returning TRUE")));
  226. return TRUE;
  227. }
  228. if (!_hLibrary)
  229. {
  230. _hLibrary = LoadLibrary( g_szPrintLibraryName );
  231. if (!_hLibrary)
  232. {
  233. WIA_ERROR((TEXT("_LoadPrintUI: Can't load library printui.dll!")));
  234. }
  235. }
  236. if( _hLibrary && !_pfnPrinterSetup )
  237. {
  238. _pfnPrinterSetup = (PF_BPRINTERSETUP) ::GetProcAddress( _hLibrary, g_szPrinterSetup );
  239. if( _pfnPrinterSetup )
  240. {
  241. return TRUE;
  242. }
  243. else
  244. {
  245. WIA_ERROR((TEXT("_LoadPrintUI: Can't get correct proc address for %s!"),g_szPrinterSetup));
  246. }
  247. }
  248. if( _hLibrary )
  249. {
  250. FreeLibrary( _hLibrary );
  251. _hLibrary = NULL;
  252. _pfnPrinterSetup = NULL;
  253. }
  254. return FALSE;
  255. }
  256. /*****************************************************************************
  257. CPrintOptionsPage::_FreePrintUI -- release library printui.dll
  258. Return value: no return value
  259. *****************************************************************************/
  260. VOID CPrintOptionsPage::_FreePrintUI( )
  261. {
  262. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_FreePrintUI()")));
  263. if( _hLibrary )
  264. {
  265. FreeLibrary( _hLibrary );
  266. _hLibrary = NULL;
  267. _pfnPrinterSetup = NULL;
  268. }
  269. return;
  270. }
  271. /*****************************************************************************
  272. CPrintOptionsPage::_ValidateControls -- validate controls in this page
  273. depending on printer selection
  274. Arguments:
  275. None
  276. Return value: no return value
  277. *****************************************************************************/
  278. VOID CPrintOptionsPage::_ValidateControls( )
  279. {
  280. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_ValidateControls()")));
  281. HWND hCtrl;
  282. LRESULT iCount;
  283. BOOL bEnabled = TRUE;
  284. if( hCtrl = GetDlgItem( _hDlg, IDC_CHOOSE_PRINTER ))
  285. {
  286. iCount = SendMessage( hCtrl, CB_GETCOUNT, 0, 0L );
  287. if( iCount == CB_ERR )
  288. {
  289. // no change ?
  290. return;
  291. }
  292. else if( iCount == 0 )
  293. {
  294. bEnabled = FALSE;
  295. }
  296. ShowWindow( GetDlgItem( _hDlg, IDC_NO_PRINTER_TEXT), bEnabled ? SW_HIDE : SW_SHOW);
  297. EnableWindow( GetDlgItem(_hDlg, IDC_PRINTER_PREFERENCES), bEnabled );
  298. PropSheet_SetWizButtons( GetParent(_hDlg), PSWIZB_BACK | ( bEnabled ? PSWIZB_NEXT : 0 ));
  299. }
  300. return;
  301. }
  302. /*****************************************************************************
  303. CPrintOptionsPage::_HandleSelectPrinter -- reset the combo box content
  304. when user changes the printer selection
  305. Arguments:
  306. None
  307. Return value: no return value
  308. *****************************************************************************/
  309. VOID CPrintOptionsPage::_HandleSelectPrinter()
  310. {
  311. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_HandleSelectPrinter()")));
  312. HWND hCtrl;
  313. LRESULT iCurSel;
  314. TCHAR szPrinterName[MAX_PATH];
  315. hCtrl = GetDlgItem( _hDlg, IDC_CHOOSE_PRINTER );
  316. if( hCtrl )
  317. {
  318. //
  319. // this also takes care of empty combo box situation,
  320. // the function will return CB_ERR if the combo box is
  321. // empty.
  322. //
  323. iCurSel = SendMessage( hCtrl, CB_GETCURSEL, 0, 0L );
  324. if( iCurSel == CB_ERR )
  325. {
  326. return;
  327. }
  328. *szPrinterName = 0;
  329. SendMessage( hCtrl, CB_GETLBTEXT, (WPARAM)iCurSel, (LPARAM)szPrinterName );
  330. _strPrinterName.Assign(szPrinterName);
  331. //
  332. // change the hDevMode for selected printer
  333. //
  334. PPRINTER_INFO_2 pPrinterInfo2;
  335. pPrinterInfo2 = (PPRINTER_INFO_2)GetPrinterWrap( szPrinterName, 2 );
  336. if( pPrinterInfo2 )
  337. {
  338. //
  339. // update cached information...
  340. //
  341. _UpdateCachedInfo( pPrinterInfo2->pDevMode );
  342. //
  343. // Save port name...
  344. //
  345. _strPortName.Assign( pPrinterInfo2->pPortName );
  346. delete [] pPrinterInfo2;
  347. }
  348. else
  349. {
  350. WIA_ERROR((TEXT("Can't get printer info for %s!"), szPrinterName));
  351. }
  352. }
  353. //
  354. // refresh the content of media type list
  355. //
  356. _ShowCurrentMedia( _strPrinterName.String(), _strPortName.String() );
  357. return;
  358. }
  359. /*****************************************************************************
  360. CPrintOptionsPage::_ShowCurrentMedia -- modify the combobox list of
  361. the media type.
  362. Return value: None.
  363. *****************************************************************************/
  364. VOID CPrintOptionsPage::_ShowCurrentMedia( LPCTSTR pszPrinterName, LPCTSTR pszPortName )
  365. {
  366. BOOL bEnable = FALSE;
  367. DWORD dwCountType = DeviceCapabilities( pszPrinterName,
  368. pszPortName,
  369. DC_MEDIATYPES,
  370. NULL,
  371. NULL );
  372. DWORD dwCountName = DeviceCapabilities( pszPrinterName,
  373. pszPortName,
  374. DC_MEDIATYPENAMES,
  375. NULL,
  376. NULL );
  377. WIA_ASSERT( dwCountType == dwCountName );
  378. if( ( (dwCountType != (DWORD)-1) && (dwCountType != 0) ) &&
  379. ( (dwCountName != (DWORD)-1) && (dwCountName != 0) ) )
  380. {
  381. LPDWORD pdwMediaType = (LPDWORD) new BYTE[dwCountType * sizeof(DWORD)];
  382. LPTSTR pszMediaType = (LPTSTR) new BYTE[dwCountName * LENGTH_OF_MEDIA_NAME * sizeof(TCHAR)];
  383. if( pdwMediaType && pszMediaType )
  384. {
  385. dwCountType = DeviceCapabilities( pszPrinterName,
  386. pszPortName,
  387. DC_MEDIATYPES,
  388. (LPTSTR)pdwMediaType,
  389. NULL );
  390. dwCountName = DeviceCapabilities( pszPrinterName,
  391. pszPortName,
  392. DC_MEDIATYPENAMES,
  393. (LPTSTR)pszMediaType,
  394. NULL );
  395. WIA_ASSERT( dwCountType == dwCountName );
  396. if ( ( (dwCountType != (DWORD)-1) && (dwCountType != 0) ) &&
  397. ( (dwCountName != (DWORD)-1) && (dwCountName != 0) )
  398. )
  399. {
  400. //
  401. // Find the currently selected media type...
  402. //
  403. if (_pWizInfo)
  404. {
  405. PDEVMODE pDevMode = _pWizInfo->GetDevModeToUse();
  406. if (pDevMode)
  407. {
  408. //
  409. // find index of currently selected item...
  410. //
  411. DWORD dwCurMedia = 0;
  412. for (INT i=0; i < (INT)dwCountType; i++)
  413. {
  414. if (pdwMediaType[i] == pDevMode->dmMediaType)
  415. {
  416. dwCurMedia = i;
  417. }
  418. }
  419. //
  420. // Set the current media type in the control...
  421. //
  422. if (dwCurMedia < dwCountName)
  423. {
  424. SetDlgItemText( _hDlg, IDC_CURRENT_PAPER, (LPCTSTR)&pszMediaType[ dwCurMedia * LENGTH_OF_MEDIA_NAME ] );
  425. bEnable = TRUE;
  426. }
  427. }
  428. }
  429. }
  430. }
  431. if (pdwMediaType)
  432. {
  433. delete [] pdwMediaType;
  434. }
  435. if (pszMediaType)
  436. {
  437. delete [] pszMediaType;
  438. }
  439. }
  440. EnableWindow( GetDlgItem( _hDlg, IDC_CURRENT_PAPER_LABEL ), bEnable );
  441. ShowWindow( GetDlgItem( _hDlg, IDC_CURRENT_PAPER_LABEL ), bEnable ? SW_SHOW : SW_HIDE );
  442. EnableWindow( GetDlgItem( _hDlg, IDC_CURRENT_PAPER ), bEnable );
  443. ShowWindow( GetDlgItem( _hDlg, IDC_CURRENT_PAPER ), bEnable ? SW_SHOW : SW_HIDE );
  444. }
  445. /*****************************************************************************
  446. CPrintOptionsPage::_UpdateCachedInfo
  447. Given a devnode, updates _pWizInfo w/new cached information...
  448. *****************************************************************************/
  449. VOID CPrintOptionsPage::_UpdateCachedInfo( PDEVMODE pDevMode )
  450. {
  451. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_UpdateCachedInfo()")));
  452. //
  453. // New devmode to use, cache it...
  454. //
  455. if (_pWizInfo)
  456. {
  457. //
  458. // User could have changed things which make
  459. // our preview assumptions invalid...
  460. //
  461. _pWizInfo->SetPreviewsAreDirty(TRUE);
  462. //
  463. // Store the devmode to use going forward...
  464. //
  465. WIA_TRACE((TEXT("CPrintOptionsPage::_UpdateCachedInfo - saving pDevMode of 0x%x"),pDevMode));
  466. _pWizInfo->SetDevModeToUse( pDevMode );
  467. //
  468. // Create an HDC that works for this new devmode...
  469. //
  470. HDC hDCPrint = CreateDC( TEXT("WINSPOOL"),
  471. _strPrinterName.String(),
  472. NULL,
  473. pDevMode
  474. );
  475. if (hDCPrint)
  476. {
  477. //
  478. // Turn on ICM for this hDC just for parity's sake with
  479. // final hDC we will use to print...
  480. //
  481. SetICMMode( hDCPrint, ICM_ON );
  482. //
  483. // Hand off DC to pWizInfo
  484. //
  485. _pWizInfo->SetCachedPrinterDC( hDCPrint );
  486. }
  487. }
  488. }
  489. /*****************************************************************************
  490. CPrintOptionsPage::_HandlePrinterPreferences
  491. Handle when "Printer Preferences" is pressed...
  492. *****************************************************************************/
  493. VOID CPrintOptionsPage::_HandlePrinterPreferences()
  494. {
  495. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_HandlePrinterPreferences()")));
  496. //
  497. // Get a handle to the printer...
  498. //
  499. HANDLE hPrinter = NULL;
  500. if (OpenPrinter( (LPTSTR)_strPrinterName.String(), &hPrinter, NULL ) && hPrinter)
  501. {
  502. //
  503. // Get the size of the devmode needed...
  504. //
  505. LONG lSize = DocumentProperties( _hDlg, hPrinter, (LPTSTR)_strPrinterName.String(), NULL, NULL, 0 );
  506. if (lSize)
  507. {
  508. PDEVMODE pDevMode = (PDEVMODE)new BYTE[lSize];
  509. if (pDevMode)
  510. {
  511. WIA_TRACE((TEXT("CPrintOptionsPage::_HandlePrinterPreferences - calling DocumentProperties with DM_IN_BUFFER of 0x%x"),_pWizInfo->GetDevModeToUse() ));
  512. if (IDOK == DocumentProperties( _hDlg, hPrinter, (LPTSTR)_strPrinterName.String(), pDevMode, _pWizInfo->GetDevModeToUse(), DM_OUT_BUFFER | DM_IN_BUFFER | DM_PROMPT))
  513. {
  514. //
  515. // Set these settings as the current ones for this app
  516. //
  517. _UpdateCachedInfo( pDevMode );
  518. }
  519. //
  520. // clean up so we don't leak...
  521. //
  522. delete [] pDevMode;
  523. }
  524. }
  525. }
  526. //
  527. // Get printer info so we have portname...
  528. //
  529. _ShowCurrentMedia( _strPrinterName.String(), _strPortName.String() );
  530. }
  531. /*****************************************************************************
  532. CPrintOptionsPage::_HandleInstallPrinter
  533. Handle when "Install Printer..." is pressed
  534. *****************************************************************************/
  535. VOID CPrintOptionsPage::_HandleInstallPrinter()
  536. {
  537. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_HandleInstallPrinter()")));
  538. if( _LoadPrintUI() && _pfnPrinterSetup )
  539. {
  540. TCHAR szPrinterName[ MAX_PATH ];
  541. *szPrinterName = 0;
  542. UINT iPrinterNameLen = 0;
  543. //
  544. // Invoke the add printer wizard.
  545. //
  546. if( _pfnPrinterSetup( _hDlg, // Parent window handle
  547. 1, // Action code, 1 for modal, 11 for modeless
  548. MAX_PATH, // Length of printer name buffer
  549. szPrinterName, // Pointer to printer name
  550. &iPrinterNameLen, // Return length of printer name.
  551. NULL ) ) // Server name, NULL for local
  552. {
  553. LRESULT iNew;
  554. HWND hCtrl = GetDlgItem( _hDlg, IDC_CHOOSE_PRINTER );
  555. #ifdef FILTER_OUT_FAX_PRINTER
  556. if( hCtrl && !IsFaxPrinter( szPrinterName, NULL ) &&
  557. #else
  558. if( hCtrl &&
  559. #endif
  560. CB_ERR == SendMessage( hCtrl, CB_FINDSTRINGEXACT, 0, (LPARAM)szPrinterName ) )
  561. {
  562. iNew = SendMessage( hCtrl, CB_ADDSTRING, 0, (LPARAM)szPrinterName );
  563. if( iNew != CB_ERR )
  564. {
  565. SendMessage( hCtrl, CB_SETCURSEL, iNew, 0L );
  566. _strPrinterName = szPrinterName;
  567. }
  568. //
  569. // reset the dropped width if necessary
  570. //
  571. WiaUiUtil::ModifyComboBoxDropWidth( hCtrl );
  572. _ValidateControls();
  573. _HandleSelectPrinter();
  574. }
  575. }
  576. }
  577. }
  578. /*****************************************************************************
  579. CPrintOptionsPage::OnInitDialog
  580. Handle initializing the wizard page...
  581. *****************************************************************************/
  582. LRESULT CPrintOptionsPage::_OnInitDialog()
  583. {
  584. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_OnInitDialog()")));
  585. HWND hCtrl;
  586. TCHAR szPrinterName[ MAX_PATH ];
  587. PPRINTER_INFO_2 pPrinterInfo = NULL;
  588. DWORD dwCountPrinters;
  589. DWORD i;
  590. DWORD dwPrinterNameLen;
  591. hCtrl = GetDlgItem( _hDlg, IDC_CHOOSE_PRINTER );
  592. if( !hCtrl )
  593. {
  594. return FALSE;
  595. }
  596. pPrinterInfo = (PPRINTER_INFO_2) EnumPrintersWrap( NULL, 2, &dwCountPrinters,
  597. PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS );
  598. if( pPrinterInfo )
  599. {
  600. for( i = 0; i < dwCountPrinters; i++)
  601. {
  602. #ifdef FILTER_OUT_FAX_PRINTER
  603. if( !IsFaxPrinter( NULL, &pPrinterInfo[i] ) )
  604. {
  605. SendMessage( hCtrl, CB_ADDSTRING, 0, (LPARAM)pPrinterInfo[i].pPrinterName );
  606. }
  607. #else
  608. SendMessage( hCtrl, CB_ADDSTRING, 0, (LPARAM)pPrinterInfo[i].pPrinterName );
  609. #endif
  610. }
  611. //
  612. // select the default printer if possible
  613. //
  614. szPrinterName[0] = '\0';
  615. dwPrinterNameLen = MAX_PATH;
  616. //
  617. // if fax printer is default printer, we'll select the first printer in the list
  618. //
  619. SendMessage( hCtrl, CB_SETCURSEL, 0, 0L );
  620. if( GetDefaultPrinter( (LPTSTR)szPrinterName, &dwPrinterNameLen ) )
  621. {
  622. SendMessage( hCtrl, CB_SELECTSTRING, -1, (LPARAM)szPrinterName );
  623. }
  624. delete [] pPrinterInfo;
  625. }
  626. else
  627. {
  628. WIA_ERROR((TEXT("Can't enumerate printer info!")));
  629. }
  630. WiaUiUtil::ModifyComboBoxDropWidth( hCtrl );
  631. _HandleSelectPrinter();
  632. return TRUE;
  633. }
  634. /*****************************************************************************
  635. CPrintOptionsPage::OnCommand
  636. Handle WM_COMMAND for this dlg page
  637. *****************************************************************************/
  638. LRESULT CPrintOptionsPage::_OnCommand( WPARAM wParam, LPARAM lParam )
  639. {
  640. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_OnCommand()")));
  641. switch (LOWORD(wParam))
  642. {
  643. case IDC_PRINTER_PREFERENCES:
  644. {
  645. _HandlePrinterPreferences();
  646. break;
  647. }
  648. case IDC_INSTALL_PRINTER:
  649. {
  650. _HandleInstallPrinter();
  651. break;
  652. }
  653. case IDC_CHOOSE_PRINTER:
  654. {
  655. if( HIWORD(wParam) == CBN_SELCHANGE )
  656. {
  657. //
  658. // change the combobox content of the media type
  659. //
  660. _HandleSelectPrinter();
  661. }
  662. break;
  663. }
  664. }
  665. return 0;
  666. }
  667. /*****************************************************************************
  668. CPrintOptions::_OnKillActive
  669. Save settings into the wizard info blob when the page changes away from
  670. us...
  671. *****************************************************************************/
  672. VOID CPrintOptionsPage::_OnKillActive()
  673. {
  674. WIA_PUSH_FUNCTION_MASK((TRACE_PAGE_PRINT_OPT, TEXT("CPrintOptionsPage::_OnKillActive()")));
  675. //
  676. // set the printer to use for later retrieval
  677. //
  678. if (_pWizInfo)
  679. {
  680. _pWizInfo->SetPrinterToUse( _strPrinterName.String() );
  681. }
  682. }
  683. /*****************************************************************************
  684. CPrintOptions::_OnNotify
  685. Handles WM_NOTIFY for this page...
  686. *****************************************************************************/
  687. LRESULT CPrintOptionsPage::_OnNotify( WPARAM wParam, LPARAM lParam )
  688. {
  689. WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CPrintOptionsPage::_OnNotify()")));
  690. LONG_PTR lpRes = 0;
  691. LPNMHDR pnmh = (LPNMHDR)lParam;
  692. switch (pnmh->code)
  693. {
  694. case PSN_SETACTIVE:
  695. WIA_TRACE((TEXT("got PSN_SETACTIVE")));
  696. PropSheet_SetWizButtons( GetParent(_hDlg), PSWIZB_BACK | PSWIZB_NEXT );
  697. //
  698. // disable the Next button if the printer list is empty
  699. //
  700. _ValidateControls();
  701. lpRes = 0;
  702. break;
  703. case PSN_WIZNEXT:
  704. WIA_TRACE((TEXT("CPrintOptionsPage: got PSN_WIZNEXT")));
  705. lpRes = IDD_SELECT_TEMPLATE;
  706. break;
  707. case PSN_WIZBACK:
  708. WIA_TRACE((TEXT("CPrintOptionsPage: got PSN_WIZBACK")));
  709. if (_pWizInfo && (_pWizInfo->CountOfPhotos(FALSE)==1))
  710. {
  711. lpRes = IDD_START_PAGE;
  712. }
  713. else
  714. {
  715. lpRes = IDD_PICTURE_SELECTION;
  716. }
  717. break;
  718. case PSN_KILLACTIVE:
  719. WIA_TRACE((TEXT("CPrintOptionsPage: got PSN_KILLACTIVE")));
  720. _OnKillActive();
  721. break;
  722. case PSN_QUERYCANCEL:
  723. WIA_TRACE((TEXT("CPrintOptionsPage: got PSN_QUERYCANCEL")));
  724. if (_pWizInfo)
  725. {
  726. lpRes = _pWizInfo->UserPressedCancel();
  727. }
  728. break;
  729. }
  730. SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, lpRes );
  731. return TRUE;
  732. }
  733. /*****************************************************************************
  734. CPrintOptionsPage::DoHandleMessage
  735. Hanlder for messages sent to this page...
  736. *****************************************************************************/
  737. INT_PTR CPrintOptionsPage::DoHandleMessage( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  738. {
  739. HWND hCtrl;
  740. TCHAR szPrinterName[ MAX_PATH ];
  741. WIA_PUSH_FUNCTION_MASK((TRACE_DLGPROC, TEXT("CPrintOptionsPage::DoHandleMessage( uMsg = 0x%x, wParam = 0x%x, lParam = 0x%x )"),uMsg,wParam,lParam));
  742. switch ( uMsg )
  743. {
  744. case WM_INITDIALOG:
  745. _hDlg = hDlg;
  746. return _OnInitDialog();
  747. case WM_COMMAND:
  748. return _OnCommand(wParam, lParam);
  749. case WM_NOTIFY:
  750. return _OnNotify(wParam, lParam);
  751. }
  752. return FALSE;
  753. }