prnsetup.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 263k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*++
  2. Copyright (c) 1990-1995,  Microsoft Corporation  All rights reserved.
  3. Module Name:
  4.     prnsetup.c
  5. Abstract:
  6.     This module implements the Win32 print dialogs.
  7. Revision History:
  8. --*/
  9. //
  10. //  Includes Files.
  11. //
  12. #include <windows.h>
  13. #include <port1632.h>
  14. #include <winspool.h>
  15. #include <commctrl.h>
  16. #include <tchar.h>
  17. #include "privcomd.h"
  18. #include "prnsetup.h"
  19. #ifndef WINNT
  20.   STATIC HCURSOR HourGlass(BOOL bOn)
  21.   {
  22.       return ( SetCursor( LoadCursor(NULL, bOn ? IDC_WAIT : IDC_ARROW) ) );
  23.   }
  24. #endif
  25. #ifdef UNICODE
  26. ////////////////////////////////////////////////////////////////////////////
  27. //
  28. //  PrintDlgA
  29. //
  30. //  ANSI entry point for PrintDlg when this code is built UNICODE.
  31. //
  32. ////////////////////////////////////////////////////////////////////////////
  33. BOOL WINAPI PrintDlgA(
  34.     LPPRINTDLGA pPDA)
  35. {
  36.     PRINTINFO PI;
  37.     BOOL bResult = FALSE;
  38.     ZeroMemory(&PI, sizeof(PRINTINFO));
  39.     if (bResult = ThunkPrintDlg(&PI, pPDA))
  40.     {
  41.         ThunkPrintDlgA2W(&PI);
  42.         if (bResult = PrintDlgX(&PI))
  43.         {
  44.             ThunkPrintDlgW2A(&PI);
  45.         }
  46.     }
  47.     FreeThunkPrintDlg(&PI);
  48.     return (bResult);
  49. }
  50. #else
  51. ////////////////////////////////////////////////////////////////////////////
  52. //
  53. //  PrintDlgW
  54. //
  55. //  Stub UNICODE function for PrintDlg when this code is built ANSI.
  56. //
  57. ////////////////////////////////////////////////////////////////////////////
  58. BOOL WINAPI PrintDlgW(
  59.     LPPRINTDLGW pPDW)
  60. {
  61.     SetLastErrorEx(SLE_WARNING, ERROR_CALL_NOT_IMPLEMENTED);
  62.     return (FALSE);
  63. }
  64. #endif
  65. ////////////////////////////////////////////////////////////////////////////
  66. //
  67. //  PrintDlg
  68. //
  69. //  The PrintDlg function displays a Print dialog box or a Print Setup
  70. //  dialog box.  The Print dialog box enables the user to specify the
  71. //  properties of a particular print job.  The Print Setup dialog box
  72. //  allows the user to select additional job properties and to configure
  73. //  the printer.
  74. //
  75. ////////////////////////////////////////////////////////////////////////////
  76. BOOL WINAPI PrintDlg(
  77.     LPPRINTDLG pPD)
  78. {
  79.     PRINTINFO PI;
  80.     ZeroMemory(&PI, sizeof(PRINTINFO));
  81.     PI.pPD = pPD;
  82.     PI.ApiType = COMDLG_WIDE;
  83.     return ( PrintDlgX(&PI) );
  84. }
  85. ////////////////////////////////////////////////////////////////////////////
  86. //
  87. //  PrintDlgX
  88. //
  89. //  Worker routine for the PrintDlg api.
  90. //
  91. ////////////////////////////////////////////////////////////////////////////
  92. BOOL PrintDlgX(
  93.     PPRINTINFO pPI)
  94. {
  95.     LPPRINTDLG pPD = pPI->pPD;
  96.     LPPAGESETUPDLG pPSD;
  97.     BOOL nResult = -1;                      // <0==error, 0==CANCEL, >0==OK
  98.     LPDEVMODE pDM = NULL;
  99.     LPDEVMODE pDevMode = NULL;
  100.     LPDEVNAMES pDN = NULL;
  101.     DWORD dwFlags;                          // old copy
  102.     WORD nCopies, nFromPage, nToPage;       // old copy
  103.     HGLOBAL hDevNames, hDevMode;            // old copy
  104.     LONG cbNeeded;
  105. #ifndef WINNT
  106.     LPCTSTR pDN_Device = NULL;
  107.     TCHAR szDev[2];
  108. #endif
  109.     if (!pPD)
  110.     {
  111.         StoreExtendedError(CDERR_INITIALIZATION);
  112.         return (FALSE);
  113.     }
  114.     if (pPD->lStructSize != sizeof(PRINTDLG))
  115.     {
  116.         StoreExtendedError(CDERR_STRUCTSIZE);
  117.         return (FALSE);
  118.     }
  119.     if (pPD->hwndOwner && !IsWindow(pPD->hwndOwner))
  120.     {
  121.         StoreExtendedError(CDERR_DIALOGFAILURE);
  122.         return (FALSE);
  123.     }
  124.     //
  125.     //  Get the process version of the app for later use.
  126.     //
  127.     pPI->ProcessVersion = GetProcessVersion(0);
  128. #ifdef UNICODE
  129.     //
  130.     //  Check if we need to use ExtDeviceMode.  We use this
  131.     //  mode only if a 16 bit app is calling us with a NULL
  132.     //  devmode.
  133.     //
  134.     if ((pPD->Flags & CD_WOWAPP) && !pPD->hDevMode)
  135.     {
  136.         pPI->bUseExtDeviceMode = TRUE;
  137.     }
  138.     else
  139.     {
  140.         pPI->bUseExtDeviceMode = FALSE;
  141.     }
  142. #endif
  143. #ifndef WINNT
  144.     //
  145.     //  This should NOT be in NT.  The device name cannot be longer than
  146.     //  32 characters, so it may be truncated.  If we look for it in the
  147.     //  registry and it's supposed to be larger than 32 characters, then
  148.     //  we won't find it and we'll fail.
  149.     //
  150.     //  LATER: It probably shouldn't be in WIN95 either, but I'll leave
  151.     //         it for now.
  152.     //
  153.     if (pPD->hDevMode)
  154.     {
  155.         if (!(pDM = GlobalLock(pPD->hDevMode)))
  156.         {
  157.             StoreExtendedError(CDERR_MEMLOCKFAILURE);
  158.             goto PrintDlgX_DisplayWarning;
  159.         }
  160.     }
  161.     if (pPD->hDevNames)
  162.     {
  163.         if (!(pDN = GlobalLock(pPD->hDevNames)))
  164.         {
  165.             if (pDM)
  166.             {
  167.                 GlobalUnlock(pPD->hDevMode);
  168.             }
  169.             StoreExtendedError(CDERR_MEMLOCKFAILURE);
  170.             goto PrintDlgX_DisplayWarning;
  171.         }
  172.         else
  173.         {
  174.             if (pDN->wDeviceOffset)
  175.             {
  176.                 pDN_Device = (LPCTSTR)pDN + pDN->wDeviceOffset;
  177.             }
  178.         }
  179.     }
  180.     if (pDM && pDM->dmDeviceName[0])
  181.     {
  182.         GetProfileString(szTextDevices, pDM->dmDeviceName, szTextNull, szDev, 2);
  183.         if (!szDev[0])
  184.         {
  185.             GlobalUnlock(pPD->hDevMode);
  186.             if (pDN)
  187.             {
  188.                 GlobalUnlock(pPD->hDevNames);
  189.             }
  190.             StoreExtendedError(PDERR_PRINTERNOTFOUND);
  191.             goto PrintDlgX_DisplayWarning;
  192.         }
  193.     }
  194.     if (pDN_Device && pDN_Device[0])
  195.     {
  196.         GetProfileString(szTextDevices, pDN_Device, szTextNull, szDev, 2);
  197.         if (!szDev[0])
  198.         {
  199.             if (pDM)
  200.             {
  201.                 GlobalUnlock(pPD->hDevMode);
  202.             }
  203.             GlobalUnlock(pPD->hDevNames);
  204.             StoreExtendedError(PDERR_PRINTERNOTFOUND);
  205.             goto PrintDlgX_DisplayWarning;
  206.         }
  207.     }
  208. #if 0   //  If this check is performed, MFC 3.0 (in VC++ 2.0) fails.
  209.     if ( pDM &&
  210.          pDM->dmDeviceName[0] &&
  211.          pDN_Device &&
  212.          pDN_Device[0] &&
  213.          lstrcmp(pDM->dmDeviceName, pDN_Device) )
  214.     {
  215.         GlobalUnlock(pPD->hDevMode);
  216.         GlobalUnlock(pPD->hDevNames);
  217.         StoreExtendedError(PDERR_DNDMMISMATCH);
  218.         goto PrintDlgX_DisplayWarning;
  219.     }
  220. #endif
  221.     if (pDM)
  222.     {
  223.         GlobalUnlock(pPD->hDevMode);
  224.     }
  225.     if (pDN)
  226.     {
  227.         GlobalUnlock(pPD->hDevNames);
  228.     }
  229. #endif
  230.     pPD->hDC = 0;
  231.     //
  232.     //  Load necessary libraries.
  233.     //
  234.     if (!PrintLoadLibraries())
  235.     {
  236.         StoreExtendedError(PDERR_LOADDRVFAILURE);
  237.         goto PrintDlgX_DisplayWarning;
  238.     }
  239.     StoreExtendedError(CDERR_GENERALCODES);
  240.     //
  241.     //  Do minimal work when requesting a default printer.
  242.     //
  243.     if (pPD->Flags & PD_RETURNDEFAULT)
  244.     {
  245.         //
  246.         //  Do not display a warning in this case if it fails.
  247.         //  MFC 3.1 does not specify PD_NOWARNING, but that's what
  248.         //  it really wants.
  249.         //
  250.         nResult = PrintReturnDefault(pPI);
  251.         PrintClosePrinters(pPI);
  252.         return (nResult);
  253.     }
  254.     if (!PrintLoadIcons())
  255.     {
  256.         //
  257.         //  If the icons cannot be loaded, then fail.
  258.         //
  259.         StoreExtendedError(PDERR_SETUPFAILURE);
  260.         goto PrintDlgX_DisplayWarning;
  261.     }
  262.     //
  263.     //  Printer enumeration is delayed until the combobox is dropped down.
  264.     //  However, if a printer is specified, we must force enumeration in
  265.     //  order to find the printer so that the correct devmode can be created.
  266.     //
  267.     //
  268.     //  First : Try to open the printer in the DevMode.
  269.     //
  270.     if ( (!pPI->hCurPrinter) &&
  271.          (pPD->hDevMode) &&
  272.          (pDM = GlobalLock(pPD->hDevMode)) )
  273.     {
  274.         PrintOpenPrinter(pPI, pDM->dmDeviceName);
  275.         GlobalUnlock(pPD->hDevMode);
  276.     }
  277.     //
  278.     //  Second : Try to open the printer in the DevNames.
  279.     //
  280.     if ( (!pPI->hCurPrinter) &&
  281.          (pPD->hDevNames) &&
  282.          (pDN = GlobalLock(pPD->hDevNames)) )
  283.     {
  284.         PrintOpenPrinter(pPI, (LPTSTR)pDN + pDN->wDeviceOffset);
  285.         GlobalUnlock(pPD->hDevNames);
  286.     }
  287.     //
  288.     //  Third : Try to open the Default Printer.
  289.     //
  290.     PrintGetDefaultPrinterName(pPI);
  291.     if (!pPI->hCurPrinter)
  292.     {
  293.         if (pPI->szDefaultPrinter[0])
  294.         {
  295.             PrintOpenPrinter(pPI, pPI->szDefaultPrinter);
  296.         }
  297.     }
  298.     //
  299.     //  Fourth : Enumerate the Printers and try to open one of those.
  300.     //
  301.     if (!pPI->hCurPrinter)
  302.     {
  303.         if (!PrintEnumAndSelect(pPD->hwndOwner, 0, pPI, NULL, TRUE))
  304.         {
  305.             //
  306.             //  There are no printers installed in the system.
  307.             //
  308.             goto PrintDlgX_DisplayWarning;
  309.         }
  310.     }
  311.     //
  312.     //  Save the original information passed in by the app in case the user
  313.     //  hits cancel.
  314.     //
  315.     dwFlags = pPD->Flags;
  316.     nCopies = pPD->nCopies;
  317.     nFromPage = pPD->nFromPage;
  318.     nToPage = pPD->nToPage;
  319.     hDevNames = pPD->hDevNames;
  320.     hDevMode = pPD->hDevMode;
  321.     pPD->hDevNames = NULL;
  322.     pPD->hDevMode = NULL;
  323.     //
  324.     //  Build a copy of the DevNames.
  325.     //
  326.     PrintBuildDevNames(pPI);
  327.     //
  328.     //  Get the *correct* DevMode.
  329.     //
  330.     if (hDevMode)
  331.     {
  332.         pDevMode = GlobalLock(hDevMode);
  333.     }
  334.     cbNeeded = (*WinSpool_DocumentProperties)(
  335.                               pPD->hwndOwner,
  336.                               pPI->hCurPrinter,
  337.                               (pPI->pCurPrinter)
  338.                                   ? pPI->pCurPrinter->pPrinterName
  339.                                   : NULL,
  340.                               NULL,
  341.                               pDevMode,
  342.                               0 );
  343.     if ( (cbNeeded > 0) &&
  344.          (pPD->hDevMode = GlobalAlloc(GHND, cbNeeded)) )
  345.     {
  346.         BOOL fSuccess = FALSE;
  347.         if (pDM = GlobalLock(pPD->hDevMode))
  348.         {
  349.             fSuccess = (*WinSpool_DocumentProperties)(
  350.                                       pPD->hwndOwner,
  351.                                       pPI->hCurPrinter,
  352.                                       (pPI->pCurPrinter)
  353.                                           ? pPI->pCurPrinter->pPrinterName
  354.                                           : NULL,
  355.                                       pDM,
  356.                                       pDevMode,
  357.                                       DM_COPY ) == IDOK;
  358.             if (pDM->dmFields & DM_COPIES)
  359.             {
  360.                 if ((hDevMode) || (pPD->Flags & PD_USEDEVMODECOPIES))
  361.                 {
  362.                     pPD->nCopies = pDM->dmCopies;
  363.                 }
  364.                 else if (pPD->nCopies)
  365.                 {
  366.                     pDM->dmCopies = pPD->nCopies;
  367.                 }
  368.             }
  369.             if (pDM->dmFields & DM_COLLATE)
  370.             {
  371.                 if ((hDevMode) || (pPD->Flags & PD_USEDEVMODECOPIES))
  372.                 {
  373.                     if (pDM->dmCollate == DMCOLLATE_FALSE)
  374.                     {
  375.                         pPD->Flags  &= ~PD_COLLATE;
  376.                         pPI->Status &= ~PI_COLLATE_REQUESTED;
  377.                     }
  378.                     else
  379.                     {
  380.                         pPD->Flags  |= PD_COLLATE;
  381.                         pPI->Status |= PI_COLLATE_REQUESTED;
  382.                     }
  383.                 }
  384.                 else
  385.                 {
  386.                     pDM->dmCollate = (pPD->Flags & PD_COLLATE)
  387.                                          ? DMCOLLATE_TRUE
  388.                                          : DMCOLLATE_FALSE;
  389.                 }
  390.             }
  391.             GlobalUnlock(pPD->hDevMode);
  392.         }
  393.         if (!fSuccess)
  394.         {
  395.             GlobalFree(pPD->hDevMode);
  396.             pPD->hDevMode = NULL;
  397.         }
  398.     }
  399.     if (pDevMode)
  400.     {
  401.         GlobalUnlock(hDevMode);
  402.     }
  403.     //
  404.     //  Get the default source string - "Print Manager Setting".
  405.     //
  406.     LoadString(g_hinst, iszDefaultSource, szDefaultSrc, SCRATCHBUF_SIZE);
  407.     //
  408.     //  Call the appropriate dialog routine.
  409.     //
  410.     switch (pPD->Flags & (PD_PRINTSETUP | PD_PAGESETUP))
  411.     {
  412.         case ( 0 ) :
  413.         {
  414.             nResult = PrintDisplayPrintDlg(pPI);
  415.             break;
  416.         }
  417.         case ( PD_PRINTSETUP ) :
  418.         case ( PD_PAGESETUP ) :
  419.         {
  420.             nResult = PrintDisplaySetupDlg(pPI);
  421.             break;
  422.         }
  423.         default :
  424.         {
  425.             StoreExtendedError(CDERR_INITIALIZATION);
  426.             break;
  427.         }
  428.     }
  429.     if (nResult > 0)
  430.     {
  431.         //
  432.         //  User hit OK, so free the copies of the handles passed in
  433.         //  by the app.
  434.         //
  435.         if (hDevMode)
  436.         {
  437.             GlobalFree(hDevMode);
  438.         }
  439.         if (hDevNames)
  440.         {
  441.             GlobalFree(hDevNames);
  442.         }
  443.     }
  444.     else
  445.     {
  446.         //
  447.         //  User hit CANCEL or there was an error, so restore original
  448.         //  values passed in by the app.
  449.         //
  450.         pPD->Flags = dwFlags;
  451.         pPD->nCopies = nCopies;
  452.         pPD->nFromPage = nFromPage;
  453.         pPD->nToPage = nToPage;
  454.         if (pPD->hDevMode)
  455.         {
  456.             GlobalFree(pPD->hDevMode);
  457.         }
  458.         if (pPD->hDevNames)
  459.         {
  460.             GlobalFree(pPD->hDevNames);
  461.         }
  462.         pPD->hDevNames = hDevNames;
  463.         pPD->hDevMode = hDevMode;
  464.     }
  465.     //
  466.     //  Make sure that we are really supposed to be leaving this function
  467.     //  before we start closing printers and displaying error messages.
  468.     //
  469.     if (pPI->Status & PI_PRINTDLGX_RECURSE)
  470.     {
  471.         return (nResult > 0);
  472.     }
  473.     //
  474.     //  Close the printers that were opened.
  475.     //
  476.     PrintClosePrinters(pPI);
  477.     //
  478.     //  Display any error messages.
  479.     //
  480. PrintDlgX_DisplayWarning:
  481.     if ((nResult < 0) && (!(pPD->Flags & PD_NOWARNING)))
  482.     {
  483.         DWORD dwErr = GetStoredExtendedError();
  484.         //
  485.         //  Only do this for new apps.
  486.         //
  487.         if ( (pPI->ProcessVersion >= 0x40000) ||
  488.              (dwErr == PDERR_NODEFAULTPRN) ||
  489.              (dwErr == PDERR_PRINTERNOTFOUND) )
  490.         {
  491.             TCHAR szWarning[SCRATCHBUF_SIZE];
  492.             TCHAR szTitle[SCRATCHBUF_SIZE];
  493.             int iszWarning;
  494.             szTitle[0] = TEXT('');
  495.             if (pPD->hwndOwner)
  496.             {
  497.                 GetWindowText(pPD->hwndOwner, szTitle, SCRATCHBUF_SIZE);
  498.             }
  499.             if (!szTitle[0])
  500.             {
  501.                 LoadString(g_hinst, iszWarningTitle, szTitle, SCRATCHBUF_SIZE);
  502.             }
  503.             switch (dwErr)
  504.             {
  505.                 case ( PDERR_NODEFAULTPRN ) :
  506.                 {
  507.                     iszWarning = iszNoPrnsInstalled;
  508.                     break;
  509.                 }
  510.                 case ( PDERR_PRINTERNOTFOUND ) :
  511.                 {
  512.                     iszWarning = iszPrnNotFound;
  513.                     break;
  514.                 }
  515.                 case ( CDERR_MEMLOCKFAILURE ) :
  516.                 case ( CDERR_MEMALLOCFAILURE ) :
  517.                 case ( PDERR_LOADDRVFAILURE ) :
  518.                 {
  519.                     iszWarning = iszMemoryError;
  520.                     break;
  521.                 }
  522.                 default :
  523.                 {
  524.                     iszWarning = iszGeneralWarning;
  525.                     break;
  526.                 }
  527.             }
  528.             LoadString(g_hinst, iszWarning, szWarning, SCRATCHBUF_SIZE);
  529.             MessageBeep(MB_ICONEXCLAMATION);
  530.             MessageBox( pPD->hwndOwner,
  531.                         szWarning,
  532.                         szTitle,
  533.                         MB_ICONEXCLAMATION | MB_OK );
  534.         }
  535.     }
  536.     return (nResult > 0);
  537. }
  538. #ifdef UNICODE
  539. ////////////////////////////////////////////////////////////////////////////
  540. //
  541. //  PageSetupDlgA
  542. //
  543. //  ANSI entry point for PageSetupDlg when this code is built UNICODE.
  544. //
  545. ////////////////////////////////////////////////////////////////////////////
  546. BOOL WINAPI PageSetupDlgA(
  547.     LPPAGESETUPDLGA pPSDA)
  548. {
  549.     PRINTINFO PI;
  550.     BOOL bResult = FALSE;
  551.     HANDLE hDevMode;
  552.     HANDLE hDevNames;
  553.     LPCSTR pTemplateName;
  554.     ZeroMemory(&PI, sizeof(PRINTINFO));
  555.     //
  556.     //  Get the pPDA structure from the pPSDA structure.
  557.     //
  558.     if (bResult = ThunkPageSetupDlg(&PI, pPSDA))
  559.     {
  560.         //
  561.         //  Save the original devmode and devnames.
  562.         //
  563.         hDevMode = pPSDA->hDevMode;
  564.         hDevNames = pPSDA->hDevNames;
  565.         pTemplateName = pPSDA->lpPageSetupTemplateName;
  566.         //
  567.         //  Convert the pPDA structure to Unicode (pPI->pPD).
  568.         //
  569.         if (bResult = ThunkPrintDlg(&PI, PI.pPDA))
  570.         {
  571.             //
  572.             //  Fill in the pPI->pPD structure.
  573.             //
  574.             ThunkPrintDlgA2W(&PI);
  575.             //
  576.             //  Copy the Unicode information from the pPD structure to
  577.             //  the pPSD structure for the call to PageSetupDlgX.
  578.             //
  579.             (PI.pPSD)->hDevMode  = (PI.pPD)->hDevMode;
  580.             (PI.pPSD)->hDevNames = (PI.pPD)->hDevNames;
  581.             (PI.pPSD)->lpPageSetupTemplateName = (PI.pPD)->lpSetupTemplateName;
  582.             //
  583.             //  Call the PageSetupDlgX function to do the work.
  584.             //
  585.             if (bResult = PageSetupDlgX(&PI))
  586.             {
  587.                 //
  588.                 //  Success.  Convert the Unicode pPD structure to
  589.                 //  its ANSI equivalent.
  590.                 //
  591.                 ThunkPrintDlgW2A(&PI);
  592.                 //
  593.                 //  Save the ANSI devmode and devnames in the
  594.                 //  pPSD structure to be returned to the caller.
  595.                 //
  596.                 pPSDA->hDevMode  = (PI.pPDA)->hDevMode;
  597.                 pPSDA->hDevNames = (PI.pPDA)->hDevNames;
  598.             }
  599.             else
  600.             {
  601.                 //
  602.                 //  Failure.  Restore the old devmode and devnames.
  603.                 //
  604.                 pPSDA->hDevMode = hDevMode;
  605.                 pPSDA->hDevNames = hDevNames;
  606.             }
  607.             //
  608.             //  Restore the old template name (always).
  609.             //
  610.             pPSDA->lpPageSetupTemplateName = pTemplateName;
  611.         }
  612.         FreeThunkPrintDlg(&PI);
  613.     }
  614.     FreeThunkPageSetupDlg(&PI);
  615.     return (bResult);
  616. }
  617. #else
  618. ////////////////////////////////////////////////////////////////////////////
  619. //
  620. //  PageSetupDlgW
  621. //
  622. //  Stub UNICODE function for PageSetupDlg when this code is built ANSI.
  623. //
  624. ////////////////////////////////////////////////////////////////////////////
  625. BOOL WINAPI PageSetupDlgW(
  626.     LPPAGESETUPDLGW pPSDW)
  627. {
  628.     SetLastErrorEx(SLE_WARNING, ERROR_CALL_NOT_IMPLEMENTED);
  629.     return (FALSE);
  630. }
  631. #endif
  632. ////////////////////////////////////////////////////////////////////////////
  633. //
  634. //  PageSetupDlg
  635. //
  636. //  The PageSetupDlg function displays a Page Setup dialog box.  This
  637. //  dialog box enables the user to specify the page orientation, the
  638. //  paper size, the paper source, and the margin settings.  The
  639. //  appearance of the printed page is shown in the dialog's page preview.
  640. //
  641. ////////////////////////////////////////////////////////////////////////////
  642. BOOL WINAPI PageSetupDlg(
  643.     LPPAGESETUPDLG pPSD)
  644. {
  645.     PRINTINFO PI;
  646.     BOOL bResult;
  647.     ZeroMemory(&PI, sizeof(PRINTINFO));
  648.     PI.pPSD = pPSD;
  649.     PI.ApiType = COMDLG_WIDE;
  650.     bResult = PageSetupDlgX(&PI);
  651.     if (PI.pPD)
  652.     {
  653.         GlobalFree(PI.pPD);
  654.     }
  655.     return (bResult);
  656. }
  657. ////////////////////////////////////////////////////////////////////////////
  658. //
  659. //  PageSetupDlgX
  660. //
  661. //  Worker routine for the PageSetupDlg api.
  662. //
  663. //  NOTE:  Caller of this routine must free pPI->pPD.
  664. //
  665. ////////////////////////////////////////////////////////////////////////////
  666. BOOL PageSetupDlgX(
  667.     PPRINTINFO pPI)
  668. {
  669.     LPPAGESETUPDLG pPSD = pPI->pPSD;
  670.     BOOL bResult = FALSE;
  671.     LPPRINTDLG pPD;
  672.     RECT rtMinMargin;
  673.     RECT rtMargin;
  674.     POINT ptPaperSize;
  675.     DWORD Flags;
  676.     if (!pPSD)
  677.     {
  678.         StoreExtendedError(CDERR_INITIALIZATION);
  679.         return (FALSE);
  680.     }
  681.     if (pPSD->lStructSize != sizeof(PAGESETUPDLG))
  682.     {
  683.         StoreExtendedError(CDERR_STRUCTSIZE);
  684.         return (FALSE);
  685.     }
  686.     if ((pPSD->Flags & PSD_RETURNDEFAULT) &&
  687.         (pPSD->hDevNames || pPSD->hDevMode))
  688.     {
  689.         StoreExtendedError(PDERR_RETDEFFAILURE);
  690.         return (FALSE);
  691.     }
  692.     //
  693.     //  Make sure only the PSD_* bits are on.  Otherwise, bad things
  694.     //  will happen.
  695.     //
  696.     if ((pPSD->Flags & ~(PSD_MINMARGINS |
  697.                          PSD_MARGINS |
  698.                          PSD_INTHOUSANDTHSOFINCHES |
  699.                          PSD_INHUNDREDTHSOFMILLIMETERS |
  700.                          PSD_DISABLEMARGINS |
  701.                          PSD_DISABLEPRINTER |
  702.                          PSD_NOWARNING |                     // must be same as PD_*
  703.                          PSD_DISABLEORIENTATION |
  704.                          PSD_DISABLEPAPER |
  705.                          PSD_RETURNDEFAULT |                 // must be same as PD_*
  706.                          PSD_SHOWHELP |                      // must be same as PD_*
  707.                          PSD_ENABLEPAGESETUPHOOK |           // must be same as PD_*
  708.                          PSD_ENABLEPAGESETUPTEMPLATE |       // must be same as PD_*
  709.                          PSD_ENABLEPAGESETUPTEMPLATEHANDLE | // must be same as PD_*
  710.                          PSD_ENABLEPAGEPAINTHOOK |
  711.                          PSD_DISABLEPAGEPAINTING))  ||
  712.         ((pPSD->Flags & (PSD_INTHOUSANDTHSOFINCHES |
  713.                          PSD_INHUNDREDTHSOFMILLIMETERS)) ==
  714.          (PSD_INTHOUSANDTHSOFINCHES | PSD_INHUNDREDTHSOFMILLIMETERS)))
  715.     {
  716.         StoreExtendedError(PDERR_INITFAILURE);
  717.         return (FALSE);
  718.     }
  719.     if ((pPSD->Flags & PSD_MINMARGINS) && (pPSD->Flags & PSD_MARGINS))
  720.     {
  721.         if ( (pPSD->rtMargin.left   < pPSD->rtMinMargin.left)  ||
  722.              (pPSD->rtMargin.top    < pPSD->rtMinMargin.top)   ||
  723.              (pPSD->rtMargin.right  < pPSD->rtMinMargin.right) ||
  724.              (pPSD->rtMargin.bottom < pPSD->rtMinMargin.bottom) )
  725.         {
  726.             StoreExtendedError(PDERR_INITFAILURE);
  727.             return (FALSE);
  728.         }
  729.     }
  730.     if (pPSD->Flags & PSD_ENABLEPAGESETUPHOOK)
  731.     {
  732.         if (!pPSD->lpfnPageSetupHook)
  733.         {
  734.             StoreExtendedError(CDERR_NOHOOK);
  735.             return (FALSE);
  736.         }
  737.     }
  738.     else
  739.     {
  740.         pPSD->lpfnPageSetupHook = NULL;
  741.     }
  742.     if (pPSD->Flags & PSD_ENABLEPAGEPAINTHOOK)
  743.     {
  744.         if (!pPSD->lpfnPagePaintHook)
  745.         {
  746.             StoreExtendedError(CDERR_NOHOOK);
  747.             return (FALSE);
  748.         }
  749.     }
  750.     else
  751.     {
  752.         pPSD->lpfnPagePaintHook = NULL;
  753.     }
  754.     if ((pPI->pPD) || (pPI->pPD = GlobalAlloc(GPTR, sizeof(PRINTDLG))))
  755.     {
  756.         pPD = pPI->pPD;
  757.         pPD->lStructSize         = sizeof( PRINTDLG );
  758.         pPD->hwndOwner           = pPSD->hwndOwner;
  759.         pPD->Flags               = PD_PAGESETUP |
  760.                                      (pPSD->Flags &
  761.                                        (PSD_NOWARNING |
  762.                                         PSD_SHOWHELP |
  763.                                         PSD_ENABLEPAGESETUPHOOK |
  764.                                         PSD_ENABLEPAGESETUPTEMPLATE |
  765.                                         PSD_ENABLEPAGESETUPTEMPLATEHANDLE));
  766.         pPD->hInstance           = pPSD->hInstance;
  767.         pPD->lCustData           = pPSD->lCustData;
  768.         pPD->lpfnSetupHook       = pPSD->lpfnPageSetupHook;
  769.         pPD->lpSetupTemplateName = pPSD->lpPageSetupTemplateName;
  770.         pPD->hSetupTemplate      = pPSD->hPageSetupTemplate;
  771.         //
  772.         //  Save original settings in case the user hits cancel.
  773.         //
  774.         rtMinMargin = pPSD->rtMinMargin;
  775.         rtMargin    = pPSD->rtMargin;
  776.         ptPaperSize = pPSD->ptPaperSize;
  777.         Flags       = pPSD->Flags;
  778.         //
  779.         //  Make sure the measure choice is set.
  780.         //
  781.         if ((pPSD->Flags & (PSD_INTHOUSANDTHSOFINCHES |
  782.                             PSD_INHUNDREDTHSOFMILLIMETERS)) == 0)
  783.         {
  784.             TCHAR szIMeasure[2];
  785.             GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, szIMeasure, 2);
  786.             if (szIMeasure[0] == TEXT('1'))
  787.             {
  788.                 pPSD->Flags |= PSD_INTHOUSANDTHSOFINCHES;
  789.             }
  790.             else
  791.             {
  792.                 pPSD->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
  793.             }
  794.         }
  795.         //
  796.         //  Set minimum margins to 0 if not passed in.
  797.         //
  798.         if (!(pPSD->Flags & PSD_MINMARGINS))
  799.         {
  800.             pPSD->rtMinMargin.left   = 0;
  801.             pPSD->rtMinMargin.top    = 0;
  802.             pPSD->rtMinMargin.right  = 0;
  803.             pPSD->rtMinMargin.bottom = 0;
  804.         }
  805.         //
  806.         //  Set margins to defaults if not passed in.
  807.         //
  808.         if (!(pPSD->Flags & PSD_MARGINS))
  809.         {
  810.             LONG MarginDefault = (pPSD->Flags & PSD_INTHOUSANDTHSOFINCHES)
  811.                                      ? INCHES_DEFAULT
  812.                                      : MMS_DEFAULT;
  813.             pPSD->rtMargin.left   = MarginDefault;
  814.             pPSD->rtMargin.top    = MarginDefault;
  815.             pPSD->rtMargin.right  = MarginDefault;
  816.             pPSD->rtMargin.bottom = MarginDefault;
  817.         }
  818.         TransferPSD2PD(pPI);
  819.         bResult = PrintDlgX(pPI);
  820.         TransferPD2PSD(pPI);
  821.         if (!bResult)
  822.         {
  823.             //
  824.             //  Restore original settings when the user hits cancel.
  825.             //
  826.             pPSD->rtMinMargin = rtMinMargin;
  827.             pPSD->rtMargin    = rtMargin;
  828.             pPSD->ptPaperSize = ptPaperSize;
  829.             pPSD->Flags       = Flags;
  830.         }
  831.     }
  832.     else
  833.     {
  834.         StoreExtendedError(CDERR_MEMALLOCFAILURE);
  835.     }
  836.     return (bResult);
  837. }
  838. ////////////////////////////////////////////////////////////////////////////
  839. //
  840. //  PrintLoadLibraries
  841. //
  842. //
  843. //
  844. ////////////////////////////////////////////////////////////////////////////
  845. BOOL PrintLoadLibraries()
  846. {
  847.     if (!hWinSpool)
  848.     {
  849.         if ((hWinSpool = LoadLibrary(szWinspool)))
  850.         {
  851.             WinSpool_AdvancedDocProps = (LPFNADVANCEDDOCPROPS)
  852.                           GetProcAddress(hWinSpool, szAdvancedDocProps);
  853.             WinSpool_DeviceCapabilities = (LPFNDEVICECAPABILITIES)
  854.                           GetProcAddress(hWinSpool, szDeviceCapabilities);
  855.             WinSpool_DocumentProperties = (LPFNDOCUMENTPROPERTIES)
  856.                           GetProcAddress(hWinSpool, szDocumentProperties);
  857.             WinSpool_EnumPrinters = (LPFNENUMPRINTERS)
  858.                           GetProcAddress(hWinSpool, szEnumPrinters);
  859.             WinSpool_GetPrinter = (LPFNGETPRINTER)
  860.                           GetProcAddress(hWinSpool, szGetPrinter);
  861.             WinSpool_OpenPrinter = (LPFNOPENPRINTER)
  862.                           GetProcAddress(hWinSpool, szOpenPrinter);
  863.             WinSpool_ClosePrinter = (LPFNCLOSEPRINTER)
  864.                           GetProcAddress(hWinSpool, szClosePrinter);
  865. #ifdef WINNT
  866.             WinSpool_ConnectToPrinterDlg = (LPFNCONNECTTOPRINTERDLG)
  867.                           GetProcAddress(hWinSpool, szConnectToPrinterDlg);
  868. #endif
  869. #ifdef UNICODE
  870.             WinSpool_ExtDeviceMode = (LPFNEXTDEVICEMODE)
  871.                           GetProcAddress(hWinSpool, szExtDeviceMode);
  872. #endif
  873.             if (!WinSpool_AdvancedDocProps ||
  874.                 !WinSpool_DeviceCapabilities ||
  875.                 !WinSpool_DocumentProperties ||
  876.                 !WinSpool_EnumPrinters ||
  877.                 !WinSpool_GetPrinter ||
  878.                 !WinSpool_OpenPrinter ||
  879.                 !WinSpool_ClosePrinter
  880. #ifdef WINNT
  881.                 ||
  882.                 !WinSpool_ConnectToPrinterDlg
  883. #endif
  884. #ifdef UNICODE
  885.                 ||
  886.                 !WinSpool_ExtDeviceMode
  887. #endif
  888.                 )
  889.             {
  890.                 FreeLibrary(hWinSpool);
  891.                 hWinSpool = NULL;
  892.             }
  893.         }
  894.     }
  895.     return (hWinSpool != NULL);
  896. }
  897. ////////////////////////////////////////////////////////////////////////////
  898. //
  899. //  PrintUnloadLibraries
  900. //
  901. //
  902. //
  903. ////////////////////////////////////////////////////////////////////////////
  904. VOID PrintUnloadLibraries()
  905. {
  906.     if (hWinSpool)
  907.     {
  908.         FreeLibrary(hWinSpool);
  909.         hWinSpool = NULL;
  910.     }
  911. }
  912. ////////////////////////////////////////////////////////////////////////////
  913. //
  914. //  PrintLoadIcons
  915. //
  916. //
  917. //
  918. ////////////////////////////////////////////////////////////////////////////
  919. BOOL PrintLoadIcons()
  920. {
  921.     //
  922.     //  Load the orientation icons.
  923.     //
  924.     hIconPortrait = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_PORTRAIT));
  925.     hIconLandscape = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_LANDSCAPE));
  926.     //
  927.     //  Load the duplex icons.
  928.     //
  929.     hIconPDuplexNone = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_P_NONE));
  930.     hIconLDuplexNone = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_L_NONE));
  931.     hIconPDuplexTumble = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_P_HORIZ));
  932.     hIconLDuplexTumble = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_L_VERT));
  933.     hIconPDuplexNoTumble = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_P_VERT));
  934.     hIconLDuplexNoTumble = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_L_HORIZ));
  935.     //
  936.     //  Load the page setup icons.
  937.     //
  938.     hIconPSStampP = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_P_PSSTAMP));
  939.     hIconPSStampL = LoadIcon(g_hinst, MAKEINTRESOURCE(ICO_L_PSSTAMP));
  940.     //
  941.     //  Load the collation images.
  942.     //
  943.     hIconCollate = LoadImage( g_hinst,
  944.                               MAKEINTRESOURCE(ICO_COLLATE),
  945.                               IMAGE_ICON,
  946.                               0,
  947.                               0,
  948.                               LR_LOADREALSIZE );
  949.     hIconNoCollate = LoadImage( g_hinst,
  950.                                 MAKEINTRESOURCE(ICO_NO_COLLATE),
  951.                                 IMAGE_ICON,
  952.                                 0,
  953.                                 0,
  954.                                 LR_LOADREALSIZE );
  955.     //
  956.     //  Return TRUE only if all icons/images were loaded properly.
  957.     //
  958.     return ( hIconPortrait &&
  959.              hIconLandscape &&
  960.              hIconPDuplexNone &&
  961.              hIconLDuplexNone &&
  962.              hIconPDuplexTumble &&
  963.              hIconLDuplexTumble &&
  964.              hIconPDuplexNoTumble &&
  965.              hIconLDuplexNoTumble &&
  966.              hIconPSStampP &&
  967.              hIconPSStampL &&
  968.              hIconCollate &&
  969.              hIconNoCollate );
  970. }
  971. ////////////////////////////////////////////////////////////////////////////
  972. //
  973. //  PrintDisplayPrintDlg
  974. //
  975. //
  976. //
  977. ////////////////////////////////////////////////////////////////////////////
  978. int PrintDisplayPrintDlg(
  979.     PPRINTINFO pPI)
  980. {
  981.     LPPRINTDLG pPD = pPI->pPD;
  982.     int fGotInput = -1;
  983.     HANDLE hDlgTemplate = NULL;
  984.     HANDLE hInstance;
  985. #ifdef UNICODE
  986.     UINT uiWOWFlag = 0;
  987. #endif
  988.     //
  989.     //  NOTE:  The print hook check must be done here rather than in
  990.     //         PrintDlgX.  Old apps that set this flag without the
  991.     //         PrintHook when calling Print Setup will fail - they
  992.     //         used to succeed.
  993.     //
  994.     if (pPD->Flags & PD_ENABLEPRINTHOOK)
  995.     {
  996.         if (!pPD->lpfnPrintHook)
  997.         {
  998.             StoreExtendedError(CDERR_NOHOOK);
  999.             return (FALSE);
  1000.         }
  1001.     }
  1002.     else
  1003.     {
  1004.         pPD->lpfnPrintHook = NULL;
  1005.     }
  1006.     if (pPD->Flags & PD_ENABLEPRINTTEMPLATEHANDLE)
  1007.     {
  1008.         if (pPD->hPrintTemplate)
  1009.         {
  1010.             hDlgTemplate = pPD->hPrintTemplate;
  1011.             hInstance = g_hinst;
  1012.         }
  1013.         else
  1014.         {
  1015.             StoreExtendedError(CDERR_NOTEMPLATE);
  1016.         }
  1017.     }
  1018.     else
  1019.     {
  1020.         LPTSTR pTemplateName = NULL;
  1021.         if (pPD->Flags & PD_ENABLEPRINTTEMPLATE)
  1022.         {
  1023.             if (pPD->lpPrintTemplateName)
  1024.             {
  1025.                 if (pPD->hInstance)
  1026.                 {
  1027.                     pTemplateName = (LPTSTR)pPD->lpPrintTemplateName;
  1028.                     hInstance = pPD->hInstance;
  1029.                 }
  1030.                 else
  1031.                 {
  1032.                     StoreExtendedError(CDERR_NOHINSTANCE);
  1033.                 }
  1034.             }
  1035.             else
  1036.             {
  1037.                 StoreExtendedError(CDERR_NOTEMPLATE);
  1038.             }
  1039.         }
  1040.         else
  1041.         {
  1042.             hInstance = g_hinst;
  1043.             pTemplateName = (LPTSTR)(DWORD)PRINTDLGORD;
  1044.         }
  1045.         if (pTemplateName)
  1046.         {
  1047.             hDlgTemplate = PrintLoadResource( hInstance,
  1048.                                               pTemplateName,
  1049.                                               RT_DIALOG );
  1050.         }
  1051.     }
  1052.     if (!hDlgTemplate)
  1053.     {
  1054.         return (FALSE);
  1055.     }
  1056.     if (LockResource(hDlgTemplate))
  1057.     {
  1058.         glpfnPrintHook = pPD->lpfnPrintHook;
  1059. #ifdef UNICODE
  1060.         if (pPD->Flags & CD_WOWAPP)
  1061.         {
  1062.             uiWOWFlag = SCDLG_16BIT;
  1063.         }
  1064.         fGotInput = DialogBoxIndirectParamAorW( hInstance,
  1065.                                                 (LPDLGTEMPLATE)hDlgTemplate,
  1066.                                                 pPD->hwndOwner,
  1067.                                                 PrintDlgProc,
  1068.                                                 (LPARAM)pPI,
  1069.                                                 uiWOWFlag );
  1070. #else
  1071.         fGotInput = DialogBoxIndirectParam( hInstance,
  1072.                                             (LPDLGTEMPLATE)hDlgTemplate,
  1073.                                             pPD->hwndOwner,
  1074.                                             PrintDlgProc,
  1075.                                             (LPARAM)pPI );
  1076. #endif
  1077.         glpfnPrintHook = NULL;
  1078.         if (fGotInput == -1)
  1079.         {
  1080.             StoreExtendedError(CDERR_DIALOGFAILURE);
  1081.         }
  1082.     }
  1083.     else
  1084.     {
  1085.         StoreExtendedError(CDERR_LOCKRESFAILURE);
  1086.     }
  1087.     return (fGotInput);
  1088. }
  1089. ////////////////////////////////////////////////////////////////////////////
  1090. //
  1091. //  PrintDisplaySetupDlg
  1092. //
  1093. //
  1094. //
  1095. ////////////////////////////////////////////////////////////////////////////
  1096. int PrintDisplaySetupDlg(
  1097.     PPRINTINFO pPI)
  1098. {
  1099.     LPPRINTDLG pPD = pPI->pPD;
  1100.     int fGotInput = -1;
  1101.     HANDLE hDlgTemplate = NULL;
  1102.     HANDLE hInstance;
  1103. #ifdef UNICODE
  1104.     UINT uiWOWFlag = 0;
  1105. #endif
  1106.     //
  1107.     //  NOTE:  The setup hook check must be done here rather than in
  1108.     //         PrintDlgX.  Old apps that set this flag without the
  1109.     //         SetupHook when calling Print will fail - they
  1110.     //         used to succeed.
  1111.     //
  1112.     if (pPD->Flags & PD_ENABLESETUPHOOK)
  1113.     {
  1114.         if (!pPD->lpfnSetupHook)
  1115.         {
  1116.             StoreExtendedError(CDERR_NOHOOK);
  1117.             return (FALSE);
  1118.         }
  1119.     }
  1120.     else
  1121.     {
  1122.         pPD->lpfnSetupHook = NULL;
  1123.     }
  1124.     if (pPD->Flags & PD_ENABLESETUPTEMPLATEHANDLE)
  1125.     {
  1126.         if (pPD->hSetupTemplate)
  1127.         {
  1128.             hDlgTemplate = pPD->hSetupTemplate;
  1129.             hInstance = g_hinst;
  1130.         }
  1131.         else
  1132.         {
  1133.             StoreExtendedError(CDERR_NOTEMPLATE);
  1134.         }
  1135.     }
  1136.     else
  1137.     {
  1138.         LPTSTR pTemplateName = NULL;
  1139.         if (pPD->Flags & PD_ENABLESETUPTEMPLATE)
  1140.         {
  1141.             if (pPD->lpSetupTemplateName)
  1142.             {
  1143.                 if (pPD->hInstance)
  1144.                 {
  1145.                     pTemplateName = (LPTSTR)pPD->lpSetupTemplateName;
  1146.                     hInstance = pPD->hInstance;
  1147.                 }
  1148.                 else
  1149.                 {
  1150.                     StoreExtendedError(CDERR_NOHINSTANCE);
  1151.                 }
  1152.             }
  1153.             else
  1154.             {
  1155.                 StoreExtendedError(CDERR_NOTEMPLATE);
  1156.             }
  1157.         }
  1158.         else
  1159.         {
  1160.             hInstance = g_hinst;
  1161.             pTemplateName = (LPTSTR)(DWORD)( (pPD->Flags & PD_PRINTSETUP)
  1162.                                                  ? PRNSETUPDLGORD
  1163.                                                  : PAGESETUPDLGORD );
  1164.         }
  1165.         if (pTemplateName)
  1166.         {
  1167.             hDlgTemplate = PrintLoadResource( hInstance,
  1168.                                               pTemplateName,
  1169.                                               RT_DIALOG );
  1170.         }
  1171.     }
  1172.     if (!hDlgTemplate)
  1173.     {
  1174.         return (FALSE);
  1175.     }
  1176.     if (LockResource(hDlgTemplate))
  1177.     {
  1178.         glpfnSetupHook = pPD->lpfnSetupHook;
  1179. #ifdef UNICODE
  1180.         if (pPD->Flags & CD_WOWAPP)
  1181.         {
  1182.             uiWOWFlag = SCDLG_16BIT;
  1183.         }
  1184.         fGotInput = DialogBoxIndirectParamAorW( hInstance,
  1185.                                                 (LPDLGTEMPLATE)hDlgTemplate,
  1186.                                                 pPD->hwndOwner,
  1187.                                                 (DLGPROC)PrintSetupDlgProc,
  1188.                                                 (LPARAM)pPI,
  1189.                                                 uiWOWFlag );
  1190. #else
  1191.         fGotInput = DialogBoxIndirectParam( hInstance,
  1192.                                             (LPDLGTEMPLATE)hDlgTemplate,
  1193.                                             pPD->hwndOwner,
  1194.                                             (DLGPROC)PrintSetupDlgProc,
  1195.                                             (LPARAM)pPI );
  1196. #endif
  1197.         glpfnSetupHook = NULL;
  1198.         if (fGotInput == -1)
  1199.         {
  1200.             StoreExtendedError(CDERR_DIALOGFAILURE);
  1201.         }
  1202.     }
  1203.     else
  1204.     {
  1205.         StoreExtendedError(CDERR_LOCKRESFAILURE);
  1206.     }
  1207.     return (fGotInput);
  1208. }
  1209. ////////////////////////////////////////////////////////////////////////////
  1210. //
  1211. //  PrintDlgProc
  1212. //
  1213. //  Print Dialog procedure.
  1214. //
  1215. ////////////////////////////////////////////////////////////////////////////
  1216. BOOL PrintDlgProc(
  1217.     HWND hDlg,
  1218.     UINT wMsg,
  1219.     WPARAM wParam,
  1220.     LONG lParam)
  1221. {
  1222.     PPRINTINFO pPI;
  1223.     LPPRINTDLG pPD;
  1224.     HWND hCtl;
  1225.     BOOL bTest;
  1226.     BOOL bResult;
  1227.     LPDEVMODE pDM;
  1228.     LPDEVNAMES pDN;
  1229.     if (pPI = (PPRINTINFO)GetProp(hDlg, PRNPROP))
  1230.     {
  1231.         if ((pPD = pPI->pPD) && (pPD->lpfnPrintHook))
  1232.         {
  1233. #ifdef UNICODE
  1234.             if (pPI->ApiType == COMDLG_ANSI)
  1235.             {
  1236.                 ThunkPrintDlgW2A(pPI);
  1237.             }
  1238. #endif
  1239.             if ((bResult = (*pPD->lpfnPrintHook)(hDlg, wMsg, wParam, lParam)))
  1240.             {
  1241. #ifdef UNICODE
  1242.                 if (pPI->ApiType == COMDLG_ANSI)
  1243.                 {
  1244.                     ThunkPrintDlgA2W(pPI);
  1245.                 }
  1246. #endif
  1247.                 return (bResult);
  1248.             }
  1249.         }
  1250.     }
  1251.     else if ( glpfnPrintHook &&
  1252.               (wMsg != WM_INITDIALOG) &&
  1253.               (bResult = (*glpfnPrintHook)(hDlg, wMsg, wParam, lParam)) )
  1254.     {
  1255.         return (bResult);
  1256.     }
  1257.     switch (wMsg)
  1258.     {
  1259.         case ( WM_INITDIALOG ) :
  1260.         {
  1261.             DWORD dwResult = 0;
  1262.             HourGlass(TRUE);
  1263. #ifndef WINNT
  1264.             msgHELPA = RegisterWindowMessage(szCommdlgHelp);
  1265. #endif
  1266.             SetProp(hDlg, PRNPROP, (HANDLE)lParam);
  1267.             glpfnPrintHook = NULL;
  1268.             pPI = (PPRINTINFO)lParam;
  1269.             pPD = pPI->pPD;
  1270.             if (pPI->pPSD)
  1271.             {
  1272.                 TCHAR szTitle[32];
  1273.                 RECT aRtDlg;
  1274.                 RECT aRtGrp;
  1275.                 RECT aRtYep;
  1276.                 RECT aRtCan;
  1277.                 HWND hBtnYep;
  1278.                 HWND hBtnCan;
  1279.                 RECT aRtWhere;
  1280.                 RECT aRtCmmnt;
  1281.                 //
  1282.                 //  Move the OK and Cancel buttons up underneath the
  1283.                 //  Printer group box and then resize the dialog
  1284.                 //  appropriately.
  1285.                 //
  1286.                 GetWindowText(GetParent(hDlg), szTitle, 32);
  1287.                 SetWindowText(hDlg, szTitle);
  1288.                 GetWindowRect(hDlg, &aRtDlg);
  1289.                 GetWindowRect(GetDlgItem(hDlg, ID_PRINT_G_PRINTER), &aRtGrp);
  1290.                 GetWindowRect(hBtnYep = GetDlgItem(hDlg, IDOK), &aRtYep);
  1291.                 GetWindowRect(hBtnCan = GetDlgItem(hDlg, IDCANCEL), &aRtCan);
  1292.                 ScreenToClient(hDlg   , (LPPOINT)&aRtYep.left );
  1293.                 ScreenToClient(hDlg   , (LPPOINT)&aRtCan.left );
  1294.                 ScreenToClient(hDlg   , (LPPOINT)&aRtDlg.right);
  1295.                 ScreenToClient(hDlg   , (LPPOINT)&aRtGrp.right);
  1296.                 ScreenToClient(hBtnYep, (LPPOINT)&aRtYep.right);
  1297.                 ScreenToClient(hBtnCan, (LPPOINT)&aRtCan.right);
  1298. #ifdef WINNT
  1299.                 if (pPD->Flags & PD_SHOWHELP)
  1300.                 {
  1301.                     HWND hBtnHlp = GetDlgItem(hDlg, ID_BOTH_P_HELP);
  1302.                     RECT aRtHlp;
  1303.                     //
  1304.                     //  Also move the Help button up underneath the
  1305.                     //  Printer group box.
  1306.                     //
  1307.                     if (hBtnHlp)
  1308.                     {
  1309.                         GetWindowRect(hBtnHlp, &aRtHlp);
  1310.                         ScreenToClient(hDlg, (LPPOINT)&aRtHlp.left);
  1311.                         ScreenToClient(hBtnHlp, (LPPOINT)&aRtHlp.right);
  1312.                         MoveWindow( hBtnHlp,
  1313.                                     aRtHlp.left,
  1314.                                     aRtGrp.bottom + 2 * aRtHlp.bottom / 3,
  1315.                                     aRtHlp.right,
  1316.                                     aRtHlp.bottom,
  1317.                                     FALSE );
  1318.                     }
  1319.                 }
  1320. #endif
  1321.                 MoveWindow( hBtnYep,
  1322.                             aRtYep.left,
  1323.                             aRtGrp.bottom + 2 * aRtYep.bottom / 3,
  1324.                             aRtYep.right,
  1325.                             aRtYep.bottom,
  1326.                             FALSE );
  1327.                 MoveWindow( hBtnCan,
  1328.                             aRtCan.left,
  1329.                             aRtGrp.bottom + 2 * aRtCan.bottom / 3,
  1330.                             aRtCan.right,
  1331.                             aRtCan.bottom,
  1332.                             FALSE );
  1333.                 MoveWindow( hDlg,
  1334.                             aRtDlg.left,
  1335.                             aRtDlg.top,
  1336.                             aRtDlg.right,
  1337.                             aRtGrp.bottom + 10 * aRtCan.bottom / 3,
  1338.                             FALSE );
  1339.                 //
  1340.                 //  Hide all other print dlg items.
  1341.                 //
  1342.                 //  NOTE: Need to do a SetWindowPos to actually remove
  1343.                 //        the window so that the AddNetButton call does
  1344.                 //        not think it's there.
  1345.                 //
  1346.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_X_TOFILE),
  1347.                               NULL,
  1348.                               0, 0, 0, 0,
  1349.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1350.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_X_COLLATE),
  1351.                               NULL,
  1352.                               0, 0, 0, 0,
  1353.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1354.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_E_FROM),
  1355.                               NULL,
  1356.                               0, 0, 0, 0,
  1357.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1358.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_E_TO),
  1359.                               NULL,
  1360.                               0, 0, 0, 0,
  1361.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1362.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_E_COPIES),
  1363.                               NULL,
  1364.                               0, 0, 0, 0,
  1365.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1366.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_G_RANGE),
  1367.                               NULL,
  1368.                               0, 0, 0, 0,
  1369.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1370.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_G_COPIES),
  1371.                               NULL,
  1372.                               0, 0, 0, 0,
  1373.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1374.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_I_COLLATE),
  1375.                               NULL,
  1376.                               0, 0, 0, 0,
  1377.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1378.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_R_ALL),
  1379.                               NULL,
  1380.                               0, 0, 0, 0,
  1381.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1382.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_R_SELECTION),
  1383.                               NULL,
  1384.                               0, 0, 0, 0,
  1385.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1386.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_R_PAGES),
  1387.                               NULL,
  1388.                               0, 0, 0, 0,
  1389.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1390.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_S_FROM),
  1391.                               NULL,
  1392.                               0, 0, 0, 0,
  1393.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1394.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_S_TO),
  1395.                               NULL,
  1396.                               0, 0, 0, 0,
  1397.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1398.                 SetWindowPos( GetDlgItem(hDlg, ID_PRINT_S_COPIES),
  1399.                               NULL,
  1400.                               0, 0, 0, 0,
  1401.                               SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
  1402.                 //
  1403.                 //  Enlarge the comment edit control, since the
  1404.                 //  "print to file" check box is hidden.
  1405.                 //
  1406.                 GetWindowRect(GetDlgItem(hDlg, ID_BOTH_S_WHERE), &aRtWhere);
  1407.                 GetWindowRect( hCtl = GetDlgItem(hDlg, ID_BOTH_S_COMMENT),
  1408.                                &aRtCmmnt );
  1409.                 ScreenToClient(hDlg, (LPPOINT)&aRtCmmnt.left);
  1410.                 MoveWindow( hCtl,
  1411.                             aRtCmmnt.left,
  1412.                             aRtCmmnt.top,
  1413.                             aRtWhere.right  - aRtWhere.left,
  1414.                             aRtWhere.bottom - aRtWhere.top,
  1415.                             FALSE );
  1416. #ifdef WINNT
  1417.                 //
  1418.                 //  Add or hide net button, if necessary.
  1419.                 //
  1420.                 if ((pPD->Flags & PD_NONETWORKBUTTON))
  1421.                 {
  1422.                     if (hCtl = GetDlgItem(hDlg, ID_BOTH_P_NETWORK))
  1423.                     {
  1424.                         EnableWindow(hCtl, FALSE);
  1425.                         ShowWindow(hCtl, SW_HIDE);
  1426.                     }
  1427.                 }
  1428.                 else
  1429.                 {
  1430.                     AddNetButton( hDlg,
  1431.                                   g_hinst,
  1432.                                   FILE_BOTTOM_MARGIN,
  1433.                                   TRUE,
  1434.                                   FALSE,
  1435.                                   TRUE );
  1436.                     //
  1437.                     //  The button can be added in two ways -
  1438.                     //      statically (they have it predefined in their template) and
  1439.                     //      dynamically (successful call to AddNetButton).
  1440.                     //
  1441.                     if (!IsNetworkInstalled())
  1442.                     {
  1443.                         hCtl = GetDlgItem(hDlg, ID_BOTH_P_NETWORK);
  1444.                         EnableWindow(hCtl, FALSE);
  1445.                         ShowWindow(hCtl, SW_HIDE);
  1446.                     }
  1447.                 }
  1448. #endif
  1449.             }
  1450.             else
  1451.             {
  1452.                 if (pPD->Flags & PD_COLLATE)
  1453.                 {
  1454.                     pPI->Status |= PI_COLLATE_REQUESTED;
  1455.                 }
  1456.             }
  1457.             if (!PrintInitGeneral(hDlg, ID_PRINT_C_NAME, pPI) ||
  1458.                 ((dwResult = PrintInitPrintDlg( hDlg,
  1459.                                                 wParam,
  1460.                                                 pPI )) == 0xFFFFFFFF))
  1461.             {
  1462.                 RemoveProp(hDlg, PRNPROP);
  1463.                 EndDialog(hDlg, -2);
  1464.             }
  1465.             HourGlass(FALSE);
  1466.             bResult = (dwResult == 1);
  1467.             return (bResult);
  1468.         }
  1469.         case ( WM_COMMAND ) :
  1470.         {
  1471.             bResult = FALSE;
  1472.             if (!pPI)
  1473.             {
  1474.                 break;
  1475.             }
  1476.             switch (GET_WM_COMMAND_ID(wParam, lParam))
  1477.             {
  1478.                 case ( ID_PRINT_C_NAME ) :       // Printer Name combobox
  1479.                 {
  1480.                     if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
  1481.                     {
  1482.                         PrintPrinterChanged(hDlg, ID_PRINT_C_NAME, pPI);
  1483.                     }
  1484.                     else if ( (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_DROPDOWN) &&
  1485.                               !(pPI->Status & PI_PRINTERS_ENUMERATED) )
  1486.                     {
  1487.                         //
  1488.                         //  Enumerate printers if this hasn't been done yet.
  1489.                         //
  1490.                         PrintEnumAndSelect( hDlg,
  1491.                                             ID_PRINT_C_NAME,
  1492.                                             pPI,
  1493.                                             (pPI->pCurPrinter)
  1494.                                               ? pPI->pCurPrinter->pPrinterName
  1495.                                               : NULL,
  1496.                                             TRUE );
  1497.                     }
  1498.                     break;
  1499.                 }
  1500.                 case ( ID_BOTH_P_PROPERTIES ) :  // Properties... button
  1501.                 {
  1502.                     PrintChangeProperties(hDlg, ID_PRINT_C_NAME, pPI);
  1503.                     break;
  1504.                 }
  1505.                 case ( ID_PRINT_P_SETUP ) :      // Setup... button
  1506.                 {
  1507.                     DWORD dwFlags = pPD->Flags;
  1508.                     HWND hwndOwner = pPD->hwndOwner;
  1509.                     pPD->Flags |= PD_PRINTSETUP;
  1510.                     pPD->Flags &= ~(PD_RETURNDC | PD_RETURNIC);
  1511.                     pPI->Status |= PI_PRINTDLGX_RECURSE;
  1512.                     pPD->hwndOwner = hDlg;
  1513.                     if (PrintDlgX(pPI))
  1514.                     {
  1515.                         if (!PrintInitBannerAndQuality(hDlg, pPI, pPD))
  1516.                         {
  1517.                             StoreExtendedError(CDERR_GENERALCODES);
  1518.                         }
  1519.                     }
  1520.                     pPI->Status &= ~PI_PRINTDLGX_RECURSE;
  1521.                     pPD->Flags = dwFlags;
  1522.                     pPD->hwndOwner = hwndOwner;
  1523.                     break;
  1524.                 }
  1525.                 case ( ID_PRINT_R_ALL ) :        // Print Range - All
  1526.                 case ( ID_PRINT_R_SELECTION ) :  // Print Range - Selection
  1527.                 case ( ID_PRINT_R_PAGES ) :      // Print Range - Pages (From, To)
  1528.                 {
  1529.                     CheckRadioButton( hDlg,
  1530.                                       ID_PRINT_R_ALL,
  1531.                                       ID_PRINT_R_PAGES,
  1532.                                       GET_WM_COMMAND_ID(wParam, lParam) );
  1533.                     //
  1534.                     //  Only move the the focus to the "From" control when
  1535.                     //  the up/down arrow is NOT used.
  1536.                     //
  1537.                     if ( !IS_KEY_PRESSED(VK_UP) &&
  1538.                          !IS_KEY_PRESSED(VK_DOWN) &&
  1539.                          ((BOOL)(GET_WM_COMMAND_ID(wParam, lParam) == ID_PRINT_R_PAGES)) )
  1540.                     {
  1541.                         SendMessage( hDlg,
  1542.                                      WM_NEXTDLGCTL,
  1543.                                      (WPARAM)GetDlgItem(hDlg, ID_PRINT_E_FROM),
  1544.                                      1L );
  1545.                     }
  1546.                     break;
  1547.                 }
  1548.                 case ( ID_PRINT_E_FROM ) :       // From  (Print Range - Pages)
  1549.                 {
  1550.                     //
  1551.                     //  Only enable the "To" control if the "From" control
  1552.                     //  contains a value.
  1553.                     //
  1554.                     GetDlgItemInt(hDlg, ID_PRINT_E_FROM, &bTest, FALSE);
  1555.                     EnableWindow(GetDlgItem(hDlg, ID_PRINT_S_TO), bTest);
  1556.                     EnableWindow(GetDlgItem(hDlg, ID_PRINT_E_TO), bTest);
  1557.                     //  FALL THRU...
  1558.                 }
  1559.                 case ( ID_PRINT_E_TO ) :         // To  (Print Range - Pages)
  1560.                 {
  1561.                     if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  1562.                     {
  1563.                         CheckRadioButton( hDlg,
  1564.                                           ID_PRINT_R_ALL,
  1565.                                           ID_PRINT_R_PAGES,
  1566.                                           ID_PRINT_R_PAGES );
  1567.                     }
  1568.                     break;
  1569.                 }
  1570.                 case ( ID_PRINT_X_COLLATE ) :    // Collate check box
  1571.                 {
  1572.                     if (hCtl = GetDlgItem(hDlg, ID_PRINT_I_COLLATE))
  1573.                     {
  1574.                         ShowWindow(hCtl, SW_HIDE);
  1575.                         SendMessage( hCtl,
  1576.                                      STM_SETICON,
  1577.                                      IsDlgButtonChecked(hDlg, ID_PRINT_X_COLLATE)
  1578.                                          ? (LONG)hIconCollate
  1579.                                          : (LONG)hIconNoCollate,
  1580.                                      0L );
  1581.                         ShowWindow(hCtl, SW_SHOW);
  1582.                         if (IsDlgButtonChecked(hDlg, ID_PRINT_X_COLLATE))
  1583.                         {
  1584.                             pPI->Status |= PI_COLLATE_REQUESTED;
  1585.                         }
  1586.                         else
  1587.                         {
  1588.                             pPI->Status &= ~PI_COLLATE_REQUESTED;
  1589.                         }
  1590.                     }
  1591.                     break;
  1592.                 }
  1593.                 case ( ID_BOTH_P_NETWORK ) :     // Network... button
  1594.                 {
  1595. #ifdef WINNT
  1596.                     HANDLE hPrinter;
  1597.                     DWORD cbPrinter = 0;
  1598.                     LPPRINTER_INFO_2 pPrinter = NULL;
  1599.                     hPrinter = (HANDLE)(*WinSpool_ConnectToPrinterDlg)(hDlg, 0);
  1600.                     if (hPrinter)
  1601.                     {
  1602.                         if (!(*WinSpool_GetPrinter)( hPrinter,
  1603.                                                      2,
  1604.                                                      (LPBYTE)pPrinter,
  1605.                                                      cbPrinter,
  1606.                                                      &cbPrinter ))
  1607.                         {
  1608.                             if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  1609.                             {
  1610.                                 if (pPrinter = LocalAlloc(LPTR, cbPrinter))
  1611.                                 {
  1612.                                     if (!(*WinSpool_GetPrinter)(
  1613.                                                hPrinter,
  1614.                                                2,
  1615.                                                (LPBYTE)pPrinter,
  1616.                                                cbPrinter,
  1617.                                                &cbPrinter ))
  1618.                                     {
  1619.                                         StoreExtendedError(PDERR_PRINTERNOTFOUND);
  1620.                                     }
  1621.                                     else
  1622.                                     {
  1623.                                         SendDlgItemMessage( hDlg,
  1624.                                                             ID_PRINT_C_NAME,
  1625.                                                             CB_RESETCONTENT,
  1626.                                                             0,
  1627.                                                             0 );
  1628.                                         PrintEnumAndSelect( hDlg,
  1629.                                                             ID_PRINT_C_NAME,
  1630.                                                             pPI,
  1631.                                                             pPrinter->pPrinterName,
  1632.                                                             TRUE );
  1633.                                     }
  1634.                                 }
  1635.                                 else
  1636.                                 {
  1637.                                     StoreExtendedError(CDERR_MEMALLOCFAILURE);
  1638.                                 }
  1639.                             }
  1640.                             else
  1641.                             {
  1642.                                 StoreExtendedError(PDERR_SETUPFAILURE);
  1643.                             }
  1644.                         }
  1645.                         if (!GetStoredExtendedError())
  1646.                         {
  1647.                             SendDlgItemMessage( hDlg,
  1648.                                                 ID_PRINT_C_NAME,
  1649.                                                 CB_SETCURSEL,
  1650.                                                 (WPARAM)SendDlgItemMessage(
  1651.                                                       hDlg,
  1652.                                                       ID_PRINT_C_NAME,
  1653.                                                       CB_FINDSTRING,
  1654.                                                       0,
  1655.                                                       (LPARAM)pPrinter->pPrinterName ),
  1656.                                                 (LPARAM)0 );
  1657.                             PrintPrinterChanged(hDlg, ID_PRINT_C_NAME, pPI);
  1658.                         }
  1659.                         LocalFree(pPrinter);
  1660.                         (*WinSpool_ClosePrinter)(hPrinter);
  1661.                     }
  1662. #else
  1663.                     if (!hMPR)
  1664.                     {
  1665.                         hMPR = LoadLibrary(szMprDll);
  1666.                     }
  1667.                     if (hMPR && !MPR_WNetConnectionDialog)
  1668.                     {
  1669.                         MPR_WNetConnectionDialog = (LPFNWNETCONNECTIONDIALOG)
  1670.                                GetProcAddress(hMPR, szWNetConnectionDialog);
  1671.                     }
  1672.                     if (MPR_WNetConnectionDialog)
  1673.                     {
  1674.                         (*MPR_WNetConnectionDialog)(hDlg, RESOURCETYPE_PRINT);
  1675.                     }
  1676. #endif
  1677.                     break;
  1678.                 }
  1679.                 case ( ID_BOTH_P_HELP ) :        // Help button
  1680.                 {
  1681. #ifdef UNICODE
  1682.                     if (pPI->ApiType == COMDLG_ANSI)
  1683.                     {
  1684.                         if (msgHELPA && pPD->hwndOwner)
  1685.                         {
  1686.                             SendMessage( pPD->hwndOwner,
  1687.                                          msgHELPA,
  1688.                                          (WPARAM)hDlg,
  1689.                                          (DWORD)pPI->pPDA );
  1690.                         }
  1691.                     }
  1692.                     else
  1693. #endif
  1694.                     {
  1695.                         if (msgHELPW && pPD->hwndOwner)
  1696.                         {
  1697.                             SendMessage( pPD->hwndOwner,
  1698.                                          msgHELPW,
  1699.                                          (WPARAM)hDlg,
  1700.                                          (DWORD)pPD );
  1701.                         }
  1702.                     }
  1703.                     break;
  1704.                 }
  1705.                 case ( IDOK ) :                  // OK button
  1706.                 {
  1707.                     bResult = TRUE;
  1708.                     if (!(pPI->pPSD))
  1709.                     {
  1710.                         pPD->Flags &= ~((DWORD)( PD_PRINTTOFILE |
  1711.                                                  PD_PAGENUMS    |
  1712.                                                  PD_SELECTION   |
  1713.                                                  PD_COLLATE ));
  1714.                         pPD->nCopies = (WORD)GetDlgItemInt( hDlg,
  1715.                                                             ID_PRINT_E_COPIES,
  1716.                                                             &bTest,
  1717.                                                             FALSE );
  1718.                         if ((!bTest) || (!pPD->nCopies))
  1719.                         {
  1720.                             PrintEditError( hDlg,
  1721.                                             ID_PRINT_E_COPIES,
  1722.                                             iszCopiesZero );
  1723.                             return (TRUE);
  1724.                         }
  1725.                         if (IsDlgButtonChecked(hDlg, ID_PRINT_R_SELECTION))
  1726.                         {
  1727.                             pPD->Flags |= PD_SELECTION;
  1728.                         }
  1729.                         else if (IsDlgButtonChecked(hDlg, ID_PRINT_R_PAGES))
  1730.                         {
  1731.                             //
  1732.                             //  Check the "From" and "To" values.
  1733.                             //
  1734.                             pPD->Flags |= PD_PAGENUMS;
  1735.                             pPD->nFromPage = (WORD)GetDlgItemInt( hDlg,
  1736.                                                                   ID_PRINT_E_FROM,
  1737.                                                                   &bTest,
  1738.                                                                   FALSE );
  1739.                             if (!bTest)
  1740.                             {
  1741.                                 PrintEditError( hDlg,
  1742.                                                 ID_PRINT_E_FROM,
  1743.                                                 iszPageFromError );
  1744.                                 return (TRUE);
  1745.                             }
  1746.                             pPD->nToPage = (WORD)GetDlgItemInt( hDlg,
  1747.                                                                 ID_PRINT_E_TO,
  1748.                                                                 &bTest,
  1749.                                                                 FALSE );
  1750.                             if (!bTest)
  1751.                             {
  1752.                                 TCHAR szBuf[PAGE_EDIT_SIZE + 1];
  1753.                                 if (GetDlgItemText( hDlg,
  1754.                                                     ID_PRINT_E_TO,
  1755.                                                     szBuf,
  1756.                                                     PAGE_EDIT_SIZE + 1 ))
  1757.                                 {
  1758.                                     PrintEditError( hDlg,
  1759.                                                     ID_PRINT_E_TO,
  1760.                                                     iszPageToError );
  1761.                                     return (TRUE);
  1762.                                 }
  1763.                                 else
  1764.                                 {
  1765.                                     pPD->nToPage = pPD->nFromPage;
  1766.                                 }
  1767.                             }
  1768.                             if ( (pPD->nFromPage < pPD->nMinPage) ||
  1769.                                  (pPD->nFromPage > pPD->nMaxPage) )
  1770.                             {
  1771.                                 PrintEditError( hDlg,
  1772.                                                 ID_PRINT_E_FROM,
  1773.                                                 iszPageRangeError,
  1774.                                                 pPD->nMinPage,
  1775.                                                 pPD->nMaxPage );
  1776.                                 return (TRUE);
  1777.                             }
  1778.                             if ( (pPD->nToPage < pPD->nMinPage) ||
  1779.                                  (pPD->nToPage > pPD->nMaxPage) )
  1780.                             {
  1781.                                 PrintEditError( hDlg,
  1782.                                                 ID_PRINT_E_TO,
  1783.                                                 iszPageRangeError,
  1784.                                                 pPD->nMinPage,
  1785.                                                 pPD->nMaxPage );
  1786.                                 return (TRUE);
  1787.                             }
  1788.                             if (pPD->nFromPage > pPD->nToPage)
  1789.                             {
  1790.                                 PrintEditError( hDlg,
  1791.                                                 ID_PRINT_E_FROM,
  1792.                                                 iszFromToError );
  1793.                                 return (TRUE);
  1794.                             }
  1795.                         }
  1796.                     }
  1797.                     HourGlass(TRUE);
  1798.                     if (IsDlgButtonChecked(hDlg, ID_PRINT_X_TOFILE))
  1799.                     {
  1800.                         pPD->Flags |= PD_PRINTTOFILE;
  1801.                     }
  1802.                     if ( (hCtl = GetDlgItem(hDlg, ID_PRINT_X_COLLATE)) &&
  1803.                          IsWindowEnabled(hCtl) &&
  1804.                          IsDlgButtonChecked(hDlg, ID_PRINT_X_COLLATE) )
  1805.                     {
  1806.                         pPD->Flags |= PD_COLLATE;
  1807.                     }
  1808.                     if (!PrintSetCopies(hDlg, pPI, ID_PRINT_C_NAME))
  1809.                     {
  1810.                         HourGlass(FALSE);
  1811.                         return (TRUE);
  1812.                     }
  1813.                     pDM = NULL;
  1814.                     pDN = NULL;
  1815.                     if (pPD->hDevMode)
  1816.                     {
  1817.                         pDM = GlobalLock(pPD->hDevMode);
  1818.                     }
  1819.                     if (pPD->hDevNames)
  1820.                     {
  1821.                         pDN = GlobalLock(pPD->hDevNames);
  1822.                     }
  1823.                     if (pDM && pDN)
  1824.                     {
  1825.                         DWORD nNum;
  1826.                         if ( GetDlgItem(hDlg, ID_PRINT_C_QUALITY) &&
  1827.                              (nNum = SendDlgItemMessage( hDlg,
  1828.                                                          ID_PRINT_C_QUALITY,
  1829.                                                          CB_GETCURSEL,
  1830.                                                          0,
  1831.                                                          0L )) != CB_ERR )
  1832.                         {
  1833.                             pDM->dmPrintQuality =
  1834.                                 (WORD)SendDlgItemMessage( hDlg,
  1835.                                                           ID_PRINT_C_QUALITY,
  1836.                                                           CB_GETITEMDATA,
  1837.                                                           (WPARAM)nNum,
  1838.                                                           0L );
  1839.                         }
  1840.                         PrintReturnICDC(pPD, pDN, pDM);
  1841.                     }
  1842.                     if (pDM)
  1843.                     {
  1844.                         GlobalUnlock(pPD->hDevMode);
  1845.                     }
  1846.                     if (pDN)
  1847.                     {
  1848.                         GlobalUnlock(pPD->hDevNames);
  1849.                     }
  1850. #ifdef UNICODE
  1851.                     if (pPI->bUseExtDeviceMode)
  1852.                     {
  1853.                         UpdateSpoolerInfo(pPI);
  1854.                     }
  1855. #endif
  1856.                     //  FALL THRU...
  1857.                 }
  1858.                 case ( IDCANCEL ) :              // Cancel button
  1859.                 case ( IDABORT ) :
  1860.                 {
  1861.                     HourGlass(TRUE);
  1862.                     glpfnPrintHook = pPD->lpfnPrintHook;
  1863.                     RemoveProp(hDlg, PRNPROP);
  1864.                     EndDialog(hDlg, bResult);
  1865.                     HourGlass(FALSE);
  1866.                     break;
  1867.                 }
  1868.                 default :
  1869.                 {
  1870.                     return (FALSE);
  1871.                     break;
  1872.                 }
  1873.             }
  1874.             break;
  1875.         }
  1876.         case ( WM_MEASUREITEM ) :
  1877.         {
  1878.             PrintMeasureItem(hDlg, (LPMEASUREITEMSTRUCT)lParam);
  1879.             break;
  1880.         }
  1881.         case ( WM_HELP ) :
  1882.         {
  1883.             if (IsWindowEnabled(hDlg))
  1884.             {
  1885.                 WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  1886.                          NULL,
  1887.                          HELP_WM_HELP,
  1888.                          (DWORD)(LPTSTR)aPrintHelpIDs );
  1889.             }
  1890.             break;
  1891.         }
  1892.         case ( WM_CONTEXTMENU ) :
  1893.         {
  1894.             if (IsWindowEnabled(hDlg))
  1895.             {
  1896.                 WinHelp( (HWND)wParam,
  1897.                          NULL,
  1898.                          HELP_CONTEXTMENU,
  1899.                          (DWORD)(LPVOID)aPrintHelpIDs );
  1900.             }
  1901.             break;
  1902.         }
  1903.         case ( WM_CTLCOLOREDIT ) :
  1904.         {
  1905.             if (GetWindowLong((HWND)lParam, GWL_STYLE) & ES_READONLY)
  1906.             {
  1907.                 return ( SendMessage(hDlg, WM_CTLCOLORDLG, wParam, lParam) );
  1908.             }
  1909.             //  FALL THRU...
  1910.         }
  1911.         default :
  1912.         {
  1913.             return (FALSE);
  1914.             break;
  1915.         }
  1916.     }
  1917.     return (TRUE);
  1918. }
  1919. ////////////////////////////////////////////////////////////////////////////
  1920. //
  1921. //  PrintSetupDlgProc
  1922. //
  1923. //  Print Setup Dialog proc.
  1924. //
  1925. ////////////////////////////////////////////////////////////////////////////
  1926. BOOL PrintSetupDlgProc(
  1927.     HWND hDlg,
  1928.     UINT wMsg,
  1929.     WPARAM wParam,
  1930.     LONG lParam)
  1931. {
  1932.     PPRINTINFO pPI;
  1933.     LPPRINTDLG pPD;
  1934.     BOOL bResult;
  1935.     UINT uCmdId;
  1936.     LPDEVMODE pDM;
  1937.     if (pPI = (PPRINTINFO)GetProp(hDlg, PRNPROP))
  1938.     {
  1939.         if ((pPD = pPI->pPD) && (pPD->lpfnSetupHook))
  1940.         {
  1941. #ifdef UNICODE
  1942.             if (pPI->ApiType == COMDLG_ANSI)
  1943.             {
  1944.                 ThunkPrintDlgW2A(pPI);
  1945.                 TransferPDA2PSD(pPI);
  1946.                 bResult = (*pPD->lpfnSetupHook)(hDlg, wMsg, wParam, lParam);
  1947.                 if (bResult)
  1948.                 {
  1949.                     TransferPSD2PDA(pPI);
  1950.                     ThunkPrintDlgA2W(pPI);
  1951.                     TransferPD2PSD(pPI);
  1952.                     return (bResult);
  1953.                 }
  1954.             }
  1955.             else
  1956. #endif
  1957.             {
  1958.                 TransferPD2PSD(pPI);
  1959.                 bResult = (*pPD->lpfnSetupHook)(hDlg, wMsg, wParam, lParam);
  1960.                 if (bResult)
  1961.                 {
  1962.                     TransferPSD2PD(pPI);
  1963.                     return (bResult);
  1964.                 }
  1965.             }
  1966.         }
  1967.     }
  1968.     else if ( glpfnSetupHook &&
  1969.               (wMsg != WM_INITDIALOG) &&
  1970.               (bResult = (*glpfnSetupHook)(hDlg, wMsg, wParam, lParam)) )
  1971.     {
  1972.         return (bResult);
  1973.     }
  1974.     switch (wMsg)
  1975.     {
  1976.         case ( WM_INITDIALOG ) :
  1977.         {
  1978.             DWORD dwResult = 0;
  1979.             HourGlass(TRUE);
  1980. #ifndef WINNT
  1981.             msgHELPA = RegisterWindowMessage(szCommdlgHelp);
  1982. #endif
  1983.             SetProp(hDlg, PRNPROP, (HANDLE)lParam);
  1984.             pPI = (PPRINTINFO)lParam;
  1985.             pPI->bKillFocus = FALSE;
  1986.             glpfnSetupHook = NULL;
  1987.             if (!PrintInitGeneral(hDlg, ID_SETUP_C_NAME, pPI) ||
  1988.                 ((dwResult = PrintInitSetupDlg( hDlg,
  1989.                                                 wParam,
  1990.                                                 pPI )) == 0xFFFFFFFF))
  1991.             {
  1992.                 RemoveProp(hDlg, PRNPROP);
  1993.                 EndDialog(hDlg, FALSE);
  1994.             }
  1995.             else if (pPI->pPSD && (pPI->pPSD->Flags & PSD_RETURNDEFAULT))
  1996.             {
  1997.                 //
  1998.                 //  PSD_RETURNDEFAULT goes through the entire initialization
  1999.                 //  in order to set rtMinMargin, rtMargin, and ptPaperSize.
  2000.                 //  Win95 Notepad relies on this behavior.
  2001.                 //
  2002.                 SendMessage(hDlg, WM_COMMAND, IDOK, 0);
  2003.             }
  2004.             HourGlass(FALSE);
  2005.             bResult = (dwResult == 1);
  2006.             return (bResult);
  2007.         }
  2008.         case ( WM_COMMAND ) :
  2009.         {
  2010.             bResult = FALSE;
  2011.             if (!pPI)
  2012.             {
  2013.                 break;
  2014.             }
  2015.             switch (uCmdId = GET_WM_COMMAND_ID(wParam, lParam))
  2016.             {
  2017.                 case ( ID_SETUP_C_NAME ) :       // Printer Name combobox
  2018.                 {
  2019.                     if ( (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_DROPDOWN) &&
  2020.                          !(pPI->Status & PI_PRINTERS_ENUMERATED) )
  2021.                     {
  2022.                         //
  2023.                         //  Enumerate printers if this hasn't been done yet.
  2024.                         //
  2025.                         PrintEnumAndSelect( hDlg,
  2026.                                             ID_SETUP_C_NAME,
  2027.                                             pPI,
  2028.                                             (pPI->pCurPrinter)
  2029.                                               ? pPI->pCurPrinter->pPrinterName
  2030.                                               : NULL,
  2031.                                             TRUE );
  2032.                     }
  2033.                     if (GET_WM_COMMAND_CMD(wParam, lParam) != CBN_SELCHANGE)
  2034.                     {
  2035.                         break;
  2036.                     }
  2037.                     if ( !GetDlgItem(hDlg, ID_SETUP_R_SPECIFIC) ||
  2038.                          IsDlgButtonChecked(hDlg, ID_SETUP_R_SPECIFIC) )
  2039.                     {
  2040.                         PrintPrinterChanged(hDlg, ID_SETUP_C_NAME, pPI);
  2041.                         break;
  2042.                     }
  2043.                     uCmdId = ID_SETUP_R_SPECIFIC;
  2044.                     // FALL THRU...
  2045.                 }
  2046.                 case ( ID_SETUP_R_DEFAULT ) :    // Default printer
  2047.                 case ( ID_SETUP_R_SPECIFIC ) :   // Specific printer
  2048.                 {
  2049.                     //
  2050.                     //  Sanity check for Publisher bug where user tries to
  2051.                     //  set focus to ID_SETUP_R_DEFAULT on exit if the
  2052.                     //  dialog has no default printer.
  2053.                     //
  2054.                     if (pPI->hCurPrinter)
  2055.                     {
  2056.                         HWND hCmb;
  2057.                         DWORD dwStyle;
  2058.                         hCmb = GetDlgItem(hDlg, ID_SETUP_C_NAME);
  2059.                         if (hCmb && (uCmdId == ID_SETUP_R_DEFAULT))
  2060.                         {
  2061.                             if (!(pPI->Status & PI_PRINTERS_ENUMERATED))
  2062.                             {
  2063.                                 //
  2064.                                 //  Enumerate printers if this hasn't been
  2065.                                 //  done yet.  Otherwise, the default printer
  2066.                                 //  may not be found in the list box when
  2067.                                 //  switching from Specific to Default.
  2068.                                 //
  2069.                                 PrintEnumAndSelect( hDlg,
  2070.                                                     ID_SETUP_C_NAME,
  2071.                                                     pPI,
  2072.                                                     NULL,
  2073.                                                     TRUE );
  2074.                             }
  2075.                             SendMessage( hCmb,
  2076.                                          CB_SETCURSEL,
  2077.                                          (WPARAM)SendMessage(
  2078.                                              hCmb,
  2079.                                              CB_FINDSTRINGEXACT,
  2080.                                              (WPARAM)-1,
  2081.                                              (LPARAM)(pPI->szDefaultPrinter) ),
  2082.                                          (LPARAM)0 );
  2083.                         }
  2084.                         PrintPrinterChanged(hDlg, ID_SETUP_C_NAME, pPI);
  2085.                         CheckRadioButton( hDlg,
  2086.                                           ID_SETUP_R_DEFAULT,
  2087.                                           ID_SETUP_R_SPECIFIC,
  2088.                                           uCmdId);
  2089.                         dwStyle = GetWindowLong(hCmb, GWL_STYLE);
  2090.                         if (uCmdId == ID_SETUP_R_DEFAULT)
  2091.                         {
  2092.                             dwStyle &= ~WS_TABSTOP;
  2093.                         }
  2094.                         else
  2095.                         {
  2096.                             dwStyle |= WS_TABSTOP;
  2097.                             SendMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)hCmb, 1L);
  2098.                         }
  2099.                         SetWindowLong(hCmb, GWL_STYLE, dwStyle);
  2100.                     }
  2101.                     break;
  2102.                 }
  2103.                 case ( ID_BOTH_P_PROPERTIES ) :  // Properties... button
  2104.                 {
  2105.                     PrintChangeProperties(hDlg, ID_SETUP_C_NAME, pPI);
  2106.                     break;
  2107.                 }
  2108.                 case ( ID_SETUP_P_MORE ) :      // More... button
  2109.                 {
  2110.                     pDM = GlobalLock(pPD->hDevMode);
  2111.                     (*WinSpool_AdvancedDocProps)(
  2112.                           hDlg,
  2113.                           pPI->hCurPrinter,
  2114.                           (pPI->pCurPrinter)
  2115.                             ? pPI->pCurPrinter->pPrinterName
  2116.                             : NULL,
  2117.                           pDM,
  2118.                           pDM );
  2119.                     GlobalUnlock(pPD->hDevMode);
  2120.                     SendMessage( hDlg,
  2121.                                  WM_NEXTDLGCTL,
  2122.                                  (WPARAM)GetDlgItem(hDlg, IDOK),
  2123.                                  1L );
  2124.                     break;
  2125.                 }
  2126.                 case ( ID_SETUP_R_PORTRAIT ) :   // Portrait
  2127.                 case ( ID_SETUP_R_LANDSCAPE ) :  // Landscape
  2128.                 {
  2129.                     if ((pPD->hDevMode) && (pDM = GlobalLock(pPD->hDevMode)))
  2130.                     {
  2131.                         PrintSetOrientation( hDlg,
  2132.                                              pPI,
  2133.                                              pDM,
  2134.                                              pPI->uiOrientationID,
  2135.                                              uCmdId );
  2136.                         GlobalUnlock(pPD->hDevMode);
  2137.                     }
  2138.                     //  FALL THRU ...
  2139.                 }
  2140.                 case ( ID_SETUP_R_NONE ) :       // None       (2-Sided)
  2141.                 case ( ID_SETUP_R_LONG ) :       // Long Side  (2-Sided)
  2142.                 case ( ID_SETUP_R_SHORT ) :      // Short Side (2-Sided)
  2143.                 {
  2144.                     if ((pPD->hDevMode) && (pDM = GlobalLock(pPD->hDevMode)))
  2145.                     {
  2146.                         PrintSetDuplex(hDlg, pDM, uCmdId);
  2147.                         GlobalUnlock(pPD->hDevMode);
  2148.                     }
  2149.                     break;
  2150.                 }
  2151.                 case ( ID_SETUP_C_SIZE ) :       // Size combobox
  2152.                 {
  2153.                     UINT Orientation;
  2154.                     if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
  2155.                     {
  2156.                         if ((pPD->hDevMode) && (pDM = GlobalLock(pPD->hDevMode)))
  2157.                         {
  2158.                         //  pDM->dmFields |= DM_PAPERSIZE;
  2159.                             pDM->dmPaperSize =
  2160.                                 (SHORT)SendMessage( (HWND)lParam,
  2161.                                                     CB_GETITEMDATA,
  2162.                                                     SendMessage( (HWND)lParam,
  2163.                                                                  CB_GETCURSEL,
  2164.                                                                  0,
  2165.                                                                  0L ),
  2166.                                                     0L );
  2167.                             Orientation =
  2168.                                 IsDlgButtonChecked(hDlg, ID_SETUP_R_PORTRAIT)
  2169.                                               ? ID_SETUP_R_PORTRAIT
  2170.                                               : ID_SETUP_R_LANDSCAPE;
  2171.                             PrintSetOrientation( hDlg,
  2172.                                                  pPI,
  2173.                                                  pDM,
  2174.                                                  Orientation,
  2175.                                                  Orientation );
  2176.                             GlobalUnlock(pPD->hDevMode);
  2177.                         }
  2178.                     }
  2179.                     break;
  2180.                 }
  2181.                 case ( ID_SETUP_C_SOURCE ) :       // Source combobox
  2182.                 {
  2183.                     if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
  2184.                     {
  2185.                         if ((pPD->hDevMode) && (pDM = GlobalLock(pPD->hDevMode)))
  2186.                         {
  2187.                         //  pDM->dmFields |= DM_DEFAULTSOURCE;
  2188.                             pDM->dmDefaultSource =
  2189.                                 (SHORT)SendMessage( (HWND)lParam,
  2190.                                                     CB_GETITEMDATA,
  2191.                                                     SendMessage( (HWND)lParam,
  2192.                                                                  CB_GETCURSEL,
  2193.                                                                  0,
  2194.                                                                  0L ),
  2195.                                                     0L );
  2196.                             GlobalUnlock(pPD->hDevMode);
  2197.                         }
  2198.                     }
  2199.                     break;
  2200.                 }
  2201.                 case ( ID_SETUP_E_LEFT ) :       // Left    (Margins)
  2202.                 case ( ID_SETUP_E_TOP ) :        // Top     (Margins)
  2203.                 case ( ID_SETUP_E_RIGHT ) :      // Right   (Margins)
  2204.                 case ( ID_SETUP_E_BOTTOM ) :     // Bottom  (Margins)
  2205.                 {
  2206.                     if (pPI->bKillFocus)
  2207.                     {
  2208.                         break;
  2209.                     }
  2210.                     switch (GET_WM_COMMAND_CMD(wParam, lParam))
  2211.                     {
  2212.                         case ( EN_KILLFOCUS ) :
  2213.                         {
  2214.                             pPI->bKillFocus = TRUE;
  2215.                             PrintSetMargin( hDlg,
  2216.                                             pPI,
  2217.                                             uCmdId,
  2218.                                             *((LONG*)&pPI->pPSD->rtMargin +
  2219.                                               uCmdId - ID_SETUP_E_LEFT) );
  2220.                             pPI->bKillFocus = FALSE;
  2221.                             break;
  2222.                         }
  2223.                         case ( EN_CHANGE ) :
  2224.                         {
  2225.                             HWND hSample;
  2226.                             PrintGetMargin( GET_WM_COMMAND_HWND(wParam, lParam),
  2227.                                             pPI,
  2228.                                             *((LONG*)&pPI->pPSD->rtMinMargin +
  2229.                                               uCmdId - ID_SETUP_E_LEFT),
  2230.                                             (LONG*)&pPI->pPSD->rtMargin +
  2231.                                               uCmdId - ID_SETUP_E_LEFT,
  2232.                                             (LONG*)&pPI->RtMarginMMs +
  2233.                                               uCmdId - ID_SETUP_E_LEFT );
  2234.                             if (hSample = GetDlgItem(hDlg, ID_SETUP_W_SAMPLE))
  2235.                             {
  2236.                                 RECT rect;
  2237.                                 GetClientRect(hSample, &rect);
  2238.                                 InflateRect(&rect, -1, -1);
  2239.                                 InvalidateRect(hSample, &rect, TRUE);
  2240.                             }
  2241.                             break;
  2242.                         }
  2243.                     }
  2244.                     break;
  2245.                 }
  2246.                 case ( ID_SETUP_P_PRINTER ) :    // Printer... button
  2247.                 {
  2248.                     //
  2249.                     //  Save a copy of the original values.
  2250.                     //
  2251.                     HWND hwndOwner = pPD->hwndOwner;
  2252.                     DWORD dwFlags = pPD->Flags;
  2253.                     HINSTANCE hInstance = pPD->hInstance;
  2254.                     LPCTSTR lpPrintTemplateName = pPD->lpPrintTemplateName;
  2255.                     //
  2256.                     //  Set up pPI so that PrintDlgX can do all the work.
  2257.                     //
  2258.                     pPD->hwndOwner = hDlg;
  2259.                     pPD->Flags &= ~( PD_ENABLEPRINTTEMPLATEHANDLE |
  2260.                                      PD_RETURNIC |
  2261.                                      PD_RETURNDC |
  2262.                                      PD_PAGESETUP );
  2263.                     pPD->Flags |= PD_ENABLEPRINTTEMPLATE;
  2264.                     pPD->hInstance = g_hinst;
  2265.                     pPD->lpPrintTemplateName = MAKEINTRESOURCE(PRINTDLGORD);
  2266.                     pPI->Status |= PI_PRINTDLGX_RECURSE;
  2267.                     if (PrintDlgX(pPI))
  2268.                     {
  2269.                         PrintUpdateSetupDlg( hDlg,
  2270.                                              pPI,
  2271.                                              GlobalLock(pPD->hDevMode),
  2272.                                              TRUE );
  2273.                         GlobalUnlock(pPD->hDevMode);
  2274.                     }
  2275.                     //
  2276.                     //  Restore the original values.
  2277.                     //
  2278.                     pPD->hwndOwner = hwndOwner;
  2279.                     pPD->Flags = dwFlags;
  2280.                     pPD->hInstance = hInstance;
  2281.                     pPD->lpPrintTemplateName = lpPrintTemplateName;
  2282.                     pPI->Status &= ~PI_PRINTDLGX_RECURSE;
  2283.                     //
  2284.                     //  Set the keyboard focus to the OK button.
  2285.                     //
  2286.                     SendMessage( hDlg,
  2287.                                  WM_NEXTDLGCTL,
  2288.                                  (WPARAM)GetDlgItem(hDlg, IDOK),
  2289.                                  1L );
  2290.                     HourGlass(FALSE);
  2291.                     break;
  2292.                 }
  2293.                 case ( ID_BOTH_P_NETWORK ) :     // Network... button
  2294.                 {
  2295. #ifdef WINNT
  2296.                     HANDLE hPrinter;
  2297.                     DWORD cbPrinter = 0;
  2298.                     LPPRINTER_INFO_2 pPrinter = NULL;
  2299.                     hPrinter = (HANDLE)(*WinSpool_ConnectToPrinterDlg)(hDlg, 0);
  2300.                     if (hPrinter)
  2301.                     {
  2302.                         if (!(*WinSpool_GetPrinter)(
  2303.                                    hPrinter,
  2304.                                    2,
  2305.                                    (LPBYTE)pPrinter,
  2306.                                    cbPrinter,
  2307.                                    &cbPrinter ))
  2308.                         {
  2309.                             if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  2310.                             {
  2311.                                 if (pPrinter = LocalAlloc(LPTR, cbPrinter))
  2312.                                 {
  2313.                                     if (!(*WinSpool_GetPrinter)(
  2314.                                                hPrinter,
  2315.                                                2,
  2316.                                                (LPBYTE)pPrinter,
  2317.                                                cbPrinter,
  2318.                                                &cbPrinter ))
  2319.                                     {
  2320.                                         StoreExtendedError(PDERR_PRINTERNOTFOUND);
  2321.                                     }
  2322.                                     else
  2323.                                     {
  2324.                                         SendDlgItemMessage( hDlg,
  2325.                                                             ID_SETUP_C_NAME,
  2326.                                                             CB_RESETCONTENT,
  2327.                                                             0,
  2328.                                                             0 );
  2329.                                         PrintEnumAndSelect( hDlg,
  2330.                                                             ID_SETUP_C_NAME,
  2331.                                                             pPI,
  2332.                                                             pPrinter->pPrinterName,
  2333.                                                             TRUE );
  2334.                                     }
  2335.                                 }
  2336.                                 else
  2337.                                 {
  2338.                                     StoreExtendedError(CDERR_MEMALLOCFAILURE);
  2339.                                 }
  2340.                             }
  2341.                             else
  2342.                             {
  2343.                                 StoreExtendedError(PDERR_SETUPFAILURE);
  2344.                             }
  2345.                         }
  2346.                         if (!GetStoredExtendedError())
  2347.                         {
  2348.                             SendDlgItemMessage( hDlg,
  2349.                                                 ID_SETUP_C_NAME,
  2350.                                                 CB_SETCURSEL,
  2351.                                                 (WPARAM)SendDlgItemMessage(
  2352.                                                       hDlg,
  2353.                                                       ID_SETUP_C_NAME,
  2354.                                                       CB_FINDSTRING,
  2355.                                                       0,
  2356.                                                       (LPARAM)pPrinter->pPrinterName ),
  2357.                                                 (LPARAM)0 );
  2358.                             PrintPrinterChanged(hDlg, ID_SETUP_C_NAME, pPI);
  2359.                         }
  2360.                         LocalFree(pPrinter);
  2361.                         (*WinSpool_ClosePrinter)(hPrinter);
  2362.                     }
  2363. #else
  2364.                     if (!hMPR)
  2365.                     {
  2366.                         hMPR = LoadLibrary(szMprDll);
  2367.                     }
  2368.                     if (hMPR && !MPR_WNetConnectionDialog)
  2369.                     {
  2370.                         MPR_WNetConnectionDialog = (LPFNWNETCONNECTIONDIALOG)
  2371.                                GetProcAddress(hMPR, szWNetConnectionDialog);
  2372.                     }
  2373.                     if (MPR_WNetConnectionDialog)
  2374.                     {
  2375.                         (*MPR_WNetConnectionDialog)(hDlg, RESOURCETYPE_PRINT);
  2376.                     }
  2377. #endif
  2378.                     break;
  2379.                 }
  2380.                 case ( ID_BOTH_P_HELP ) :        // Help button
  2381.                 {
  2382. #ifdef UNICODE
  2383.                     if (pPI->ApiType == COMDLG_ANSI)
  2384.                     {
  2385.                         if (msgHELPA && pPD->hwndOwner)
  2386.                         {
  2387.                             SendMessage( pPD->hwndOwner,
  2388.                                          msgHELPA,
  2389.                                          (WPARAM)hDlg,
  2390.                                          (LPARAM)pPI->pPDA );
  2391.                         }
  2392.                     }
  2393.                     else
  2394. #endif
  2395.                     {
  2396.                         if (msgHELPW && pPD->hwndOwner)
  2397.                         {
  2398.                             SendMessage( pPD->hwndOwner,
  2399.                                          msgHELPW,
  2400.                                          (WPARAM)hDlg,
  2401.                                          (LPARAM)pPD );
  2402.                         }
  2403.                     }
  2404.                     break;
  2405.                 }
  2406.                 case ( IDOK ) :                  // OK button
  2407.                 {
  2408.                     LPPAGESETUPDLG pPSD = pPI->pPSD;
  2409.                     int i;
  2410.                     if (pPSD)
  2411.                     {
  2412.                         if ((pPSD->rtMinMargin.left + pPSD->rtMinMargin.right >
  2413.                                 pPSD->ptPaperSize.x) ||
  2414.                             (pPSD->rtMinMargin.top + pPSD->rtMinMargin.bottom >
  2415.                                 pPSD->ptPaperSize.y))
  2416.                         {
  2417.                             //
  2418.                             //  This is an unprintable case that can happen.
  2419.                             //  Let's assume that the driver is at fault
  2420.                             //  and accept whatever the user entered.
  2421.                             //
  2422.                         }
  2423.                         else if (pPSD->rtMargin.left + pPSD->rtMargin.right >
  2424.                                      pPSD->ptPaperSize.x)
  2425.                         {
  2426.                             i = (pPSD->rtMargin.left >= pPSD->rtMargin.right)
  2427.                                     ? ID_SETUP_E_LEFT
  2428.                                     : ID_SETUP_E_RIGHT;
  2429.                             PrintEditError(hDlg, i, iszBadMarginError);
  2430.                             return (TRUE);
  2431.                         }
  2432.                         else if (pPSD->rtMargin.top + pPSD->rtMargin.bottom >
  2433.                                      pPSD->ptPaperSize.y)
  2434.                         {
  2435.                             i = (pPSD->rtMargin.top >= pPSD->rtMargin.bottom)
  2436.                                     ? ID_SETUP_E_TOP
  2437.                                     : ID_SETUP_E_BOTTOM;
  2438.                             PrintEditError(hDlg, i, iszBadMarginError);
  2439.                             return (TRUE);
  2440.                         }
  2441.                     }
  2442.                     else
  2443.                     {
  2444.                         if (!PrintSetCopies(hDlg, pPI, ID_SETUP_C_NAME))
  2445.                         {
  2446.                             return (TRUE);
  2447.                         }
  2448.                     }
  2449.                     bResult = TRUE;
  2450.                     SetFocus( GetDlgItem(hDlg, IDOK) );
  2451.                     //  FALL THRU...
  2452.                 }
  2453.                 case ( IDCANCEL ) :              // Cancel button
  2454.                 case ( IDABORT ) :
  2455.                 {
  2456.                     HourGlass(TRUE);
  2457.                     if (bResult)
  2458.                     {
  2459.                         PrintGetSetupInfo(hDlg, pPD);
  2460. #ifdef UNICODE
  2461.                         if (pPI->bUseExtDeviceMode)
  2462.                         {
  2463.                             UpdateSpoolerInfo(pPI);
  2464.                         }
  2465. #endif
  2466.                     }
  2467.                     else
  2468.                     {
  2469.                         SetFocus( GetDlgItem(hDlg, IDCANCEL) );
  2470.                     }
  2471.                     pPI->bKillFocus = TRUE;
  2472.                     glpfnSetupHook = pPD->lpfnSetupHook;
  2473.                     RemoveProp(hDlg, PRNPROP);
  2474.                     EndDialog(hDlg, bResult);
  2475.                     break;
  2476.                 }
  2477.                 default :
  2478.                 {
  2479.                     return (FALSE);
  2480.                     break;
  2481.                 }
  2482.             }
  2483.             break;
  2484.         }
  2485.         case ( WM_MEASUREITEM ) :
  2486.         {
  2487.             PrintMeasureItem(hDlg, (LPMEASUREITEMSTRUCT)lParam);
  2488.             break;
  2489.         }
  2490.         case ( WM_HELP ) :
  2491.         {
  2492.             if (IsWindowEnabled(hDlg))
  2493.             {
  2494.                 WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  2495.                          NULL,
  2496.                          HELP_WM_HELP,
  2497.                          (DWORD)(LPTSTR)((pPD->Flags & PD_PRINTSETUP)
  2498.                                             ? aPrintSetupHelpIDs
  2499.                                             : aPageSetupHelpIDs) );
  2500.             }
  2501.             break;
  2502.         }
  2503.         case ( WM_CONTEXTMENU ) :
  2504.         {
  2505.             if (IsWindowEnabled(hDlg))
  2506.             {
  2507.                 WinHelp( (HWND)wParam,
  2508.                          NULL,
  2509.                          HELP_CONTEXTMENU,
  2510.                          (DWORD)(LPVOID)((pPD->Flags & PD_PRINTSETUP)
  2511.                                             ? aPrintSetupHelpIDs
  2512.                                             : aPageSetupHelpIDs) );
  2513.             }
  2514.             break;
  2515.         }
  2516.         case ( WM_CTLCOLOREDIT ) :
  2517.         {
  2518.             if (GetWindowLong((HWND)lParam, GWL_STYLE) & ES_READONLY)
  2519.             {
  2520.                 return ( SendMessage(hDlg, WM_CTLCOLORDLG, wParam, lParam) );
  2521.             }
  2522.             //  FALL THRU...
  2523.         }
  2524.         default :
  2525.         {
  2526.             return (FALSE);
  2527.             break;
  2528.         }
  2529.     }
  2530.     return (TRUE);
  2531. }
  2532. ////////////////////////////////////////////////////////////////////////////
  2533. //
  2534. //  PrintEditNumberOnlyProc
  2535. //
  2536. //
  2537. //
  2538. ////////////////////////////////////////////////////////////////////////////
  2539. LONG PrintEditNumberOnlyProc(
  2540.     HWND hWnd,
  2541.     UINT msg,
  2542.     WPARAM wP,
  2543.     LPARAM lP)
  2544. {
  2545.     if ( (msg == WM_CHAR) &&
  2546.          (wP != BACKSPACE) &&
  2547.          ((wP < TEXT('0')) || (wP > TEXT('9'))) )
  2548.     {
  2549.         MessageBeep(0);
  2550.         return (FALSE);
  2551.     }
  2552.     return ( CallWindowProc(lpEditNumOnlyProc, hWnd, msg, wP, lP) );
  2553. }
  2554. ////////////////////////////////////////////////////////////////////////////
  2555. //
  2556. //  PrintEditMarginProc
  2557. //
  2558. //
  2559. //
  2560. ////////////////////////////////////////////////////////////////////////////
  2561. LONG PrintEditMarginProc(
  2562.     HWND hWnd,
  2563.     UINT msg,
  2564.     WPARAM wP,
  2565.     LPARAM lP)