PRINT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:36k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /************************************************************************
  2.   File: print.c
  3.   Purpose:  To manage CDTEST's print dialog box.
  4.   Functions:
  5.     DoPrintDlg()            -- Creates CDTEST's print dialog box.
  6.     PrintProc()             -- Callback function for CDTEST's print dialog box.
  7.     DevnamesProc()          -- Callback function for CDTESTS Devnames dlg box.
  8.     DevmodeProc()           -- Callback function for CDTESTS Devmode dlg box.
  9.     InitPrintStruct()       -- Fills a PRINTDLG struct with some default values.
  10.     FillPrintDlg()          -- Fills CDTEST's print dialog with contents of a
  11.                                PRINTDLG structure.
  12.     GetPrintDlg()           -- Retrieves the users edits from CDTEST's print dlg.
  13.     FillDevnamesDlg()       -- Fills CDTEST's Devnames dialog with the contents
  14.                                of a DEVNAMES structure.
  15.     GetDevnamesDlg()        -- Retrieves the user's edits from CDTEST's devnames dlg.
  16.     FillDevmodeDlg()        -- Fills CDTEST's devmode dialog with the contents of
  17.                                a DEVMODE structure.
  18.     GetDevmodeDlg()         -- Retrieves the user's edits from CDTEST's devmode dlg.
  19.     GetPrintDlgHandle()     -- Loads and returns a handle to a Print dlg custom template.
  20.     GetSetupDlgHandle()     -- Loads and returns a handle to a Setup dlg custom template.
  21.     PrintHookProc()         -- Callback function for PRINTDLG->lpfnPrintHook and
  22.                                for PRINTDLG->lpfnSetupHook
  23.     PrintMultiProc1()       -- Starting address for multithread option thread 1
  24.     PrintMultiProc2()       -- Starting address for multithread option thread 2
  25.     MultiThreadPrintDlg()   -- Creates two threads which each call PrintDlg()
  26.     EnablePrintControls()   -- Enables or disables CDTEST's print dlg controls.
  27.     DoPrintDlgStuff()       -- Calls PrintDlg()
  28. ************************************************************************/
  29. #include <windows.h>
  30. #include <commdlg.h>
  31. #include <stdlib.h>
  32. #include <winnls.h>
  33. #include "cdtest.h"
  34. #include "print.h"
  35. #include "devnames.h"
  36. #include "devmode.h"
  37. #include "dlgs.h"
  38. /* Externs, prototypes, variable declarations for print.c */
  39. extern UINT uMode ;
  40. extern LONG MyAtol(LPTSTR, BOOL, LPBOOL) ;
  41. UINT APIENTRY PrintHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam) ;
  42. void InitPrintStruct(HWND, LPPRINTDLG) ;
  43. void FillPrintDlg(HWND, LPPRINTDLG) ;
  44. void GetPrintDlg(HWND, LPPRINTDLG) ;
  45. void FillDevnamesDlg(HWND, LPPRINTDLG) ;
  46. void GetDevnamesDlg(HWND, LPPRINTDLG) ;
  47. void FillDevmodeDlg(HWND, LPPRINTDLG) ;
  48. void GetDevmodeDlg(HWND, LPPRINTDLG) ;
  49. HANDLE GetPrintDlgHandle(void) ;
  50. HANDLE GetSetupDlgHandle(void) ;
  51. void DoPrintDlgStuff(HWND, LPPRINTDLG) ;
  52. HANDLE hResPrint ;
  53. HANDLE hDialogPrint ;
  54. PRINTDLG pd ;
  55. HANDLE hDevNames ;
  56. HANDLE hDevMode ;
  57. TCHAR szDriverOffset[100] ;
  58. TCHAR szDeviceOffset[100] ;
  59. TCHAR szOutputOffset[100] ;
  60. TCHAR szPrintTempName[40] ;
  61. TCHAR szSetupTempName[40] ;
  62. /* Multithreading function declarations, variables */
  63. DWORD PrintMultiProc1(LPDWORD) ;
  64. DWORD PrintMultiProc2(LPDWORD) ;
  65. void MultiThreadPrintDlg(void) ;
  66. void EnablePrintControls(HWND, BOOL) ;
  67. HANDLE hPrintThread1 ;
  68. HANDLE hPrintThread2 ;
  69. DWORD dwPrintThreadID1 ;
  70. DWORD dwPrintThreadID2 ;
  71. DWORD dwPrintThreadParm1 ;
  72. DWORD dwPrintThreadParm2 ;
  73. PRINTDLG pdThread1 ;
  74. PRINTDLG pdThread2 ;
  75. HWND hwndMainPrint ;
  76. int nOpenDialogCount ;
  77. HBRUSH hBrushDlg ;
  78. HBRUSH hBrushEdit ;    //brush handles for new colors done with hook proc
  79. HBRUSH hBrushButton ;
  80. /************************************************************************
  81.   Function: DoPrintDialog(HWND)
  82.   Purpose:  Creates CDTEST's print dialog box.
  83.   Returns:  Nothing.
  84.   Comments: There is only one dialog for both Print Setup and Print Print.
  85.             The Print Print dialog is the default.  To create the Print
  86.             Setup dialog, enter the value for PD_PRINTSETUP into the
  87.             "Flags" edit box and click OK.
  88. ************************************************************************/
  89. void DoPrintDialog(HWND hwnd)
  90. {
  91.   DialogBox(hInst, MAKEINTRESOURCE(ID_PRINTDIALOG),
  92.             hwnd, PrintProc) ;
  93. }
  94. /************************************************************************
  95.   Function: PrintProc(HWND, UINT, UINT, LONG)
  96.   Purpose:  Callback function for CDTEST's print dialog box.
  97.   Returns:  TRUE or FALSE depending on the situation/message.
  98.   Comments:
  99. ************************************************************************/
  100. BOOL APIENTRY PrintProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  101. {
  102.   switch (msg)
  103.   {
  104.     case WM_INITDIALOG:
  105.         InitPrintStruct(hwnd, &pd) ;
  106.         FillPrintDlg(hwnd, &pd) ;
  107.         *(&pdThread1) = *(&pdThread2) = *(&pd) ;
  108.         hwndMainPrint = hwnd ;
  109.         nOpenDialogCount = 0 ;
  110.         SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEP)) ;
  111.         break ;
  112.     case UMSG_DECREMENTDLGCOUNT: //user defined message that is send when
  113.                                  //each thread created when multithreading ends
  114.         nOpenDialogCount-- ;
  115.         if (nOpenDialogCount == 0)               //once both multitheading dlgs
  116.             EnablePrintControls(hwnd, TRUE) ;   //are done, enable the controls again
  117.         break ;
  118.     case WM_COMMAND:
  119.     {
  120.         switch (LOWORD(wParam))
  121.         {
  122.           case IDOK:
  123.             GetPrintDlg(hwnd, &pd) ;
  124.             DoPrintDlgStuff(hwnd, &pd) ;
  125.             break ;
  126.           case IDCANCEL:
  127.             if (pd.hDC)
  128.               ReleaseDC(hwnd, pd.hDC) ;
  129.             EndDialog(hwnd, FALSE) ;
  130.             break ;
  131.           case ID_RESETPRINT:
  132.             SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEP)) ;
  133.             InitPrintStruct(hwnd, &pd) ;
  134.             FillPrintDlg(hwnd, &pd) ;
  135.             SendDlgItemMessage(hwnd, ID_PRESETUPP,   BM_SETCHECK, (WPARAM)0, (LPARAM)0) ;
  136.             SendDlgItemMessage(hwnd, ID_PREPRINTP,   BM_SETCHECK, (WPARAM)0, (LPARAM)0) ;
  137.             SendDlgItemMessage(hwnd, ID_NULLSTRUCTP, BM_SETCHECK, (WPARAM)0, (LPARAM)0) ;
  138.             break ;
  139.           case ID_EDITDEVNAMES:
  140.             DialogBox(hInst, MAKEINTRESOURCE(ID_DEVNAMESDIALOG),
  141.                       hwnd, DevnamesProc) ;
  142.             break ;
  143.           case ID_EDITDEVMODE:
  144.             DialogBox(hInst, MAKEINTRESOURCE(ID_DEVMODEDIALOG),
  145.                       hwnd, DevmodeProc) ;
  146.             break ;
  147.           case ID_MULTITHREADPRINT:
  148.             nOpenDialogCount = 2 ;
  149.             EnablePrintControls(hwnd, FALSE) ;
  150.             MultiThreadPrintDlg() ;
  151.             break ;
  152.           default: break ;
  153.         }
  154.     }
  155.     default:
  156.       /* If the help button is pressed in the PrintDlg() dialog box,
  157.          it will send a message Registered with RegisterWindowMessage()
  158.          to the parent window.  The message nHelpMessage was registered
  159.          at application startup */
  160.       if (msg == nHelpMessage)
  161.         MessageBox(GetForegroundWindow(), TEXT("Hello from the help button"),
  162.                    TEXT("Print Help Button"), MB_OK | MB_APPLMODAL) ;
  163.       break ;
  164.   }
  165.   return FALSE ;
  166. }
  167. /************************************************************************
  168.   Function: DevnamesProc(HWND, UINT, UINT, LONG)
  169.   Purpose:  Callback function for the Devnames dialog box
  170.   Returns:  TRUE or FALSE depending on situation / message
  171.   Comments:
  172. ************************************************************************/
  173. BOOL APIENTRY DevnamesProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  174. {
  175.   switch (msg)
  176.   {
  177.     case WM_INITDIALOG:
  178.         FillDevnamesDlg(hwnd, &pd) ;
  179.         break ;
  180.     case WM_COMMAND:
  181.     {
  182.         switch (LOWORD(wParam))
  183.         {
  184.           case IDOK:
  185.             GetDevnamesDlg(hwnd, &pd) ;
  186.             EndDialog(hwnd, TRUE) ;
  187.             break ;
  188.           case IDCANCEL:
  189.             EndDialog(hwnd, FALSE) ;
  190.             break ;
  191.           default: break ;
  192.         }
  193.     }
  194.     default: break ;
  195.   }
  196.   return FALSE ;
  197. }
  198. /************************************************************************
  199.   Function: DevmodeProc(HWND, UINT, UINT, LONG)
  200.   Purpose:  Callback function for the Devmode dialog box
  201.   Returns:  TRUE or FALSE depending on situation / message
  202.   Comments:
  203. ************************************************************************/
  204. BOOL APIENTRY DevmodeProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  205. {
  206.   switch (msg)
  207.   {
  208.     case WM_INITDIALOG:
  209.         FillDevmodeDlg(hwnd, &pd) ;
  210.         break ;
  211.     case WM_COMMAND:
  212.     {
  213.         switch (LOWORD(wParam))
  214.         {
  215.           case IDOK:
  216.             GetDevmodeDlg(hwnd, &pd) ;
  217.             EndDialog(hwnd, TRUE) ;
  218.             break ;
  219.           case IDCANCEL:
  220.             EndDialog(hwnd, FALSE) ;
  221.             break ;
  222.           default: break ;
  223.         }
  224.     }
  225.     default: break ;
  226.   }
  227.   return FALSE ;
  228. }
  229. /************************************************************************
  230.   Function: InitPrintStruct(HWND, LPPRINTDLG)
  231.   Purpose:  Fills a PRINTDLG structure with some default values.
  232.   Returns:  Nothing.
  233.   Comments:
  234.     In order to fill in the hDevMode and hDevNames PRINTDLG structure
  235.     elements, a call to PrintDlg() must be made with the
  236.     (PD_RETURNDEFAULT | PD_RETURNDC) flag bits set.
  237. ************************************************************************/
  238. void InitPrintStruct(HWND hwnd, LPPRINTDLG ppd)
  239. {
  240.   DWORD dwTempFlags = 0 ;
  241.   ppd->lStructSize = sizeof(PRINTDLG) ;
  242.   ppd->hwndOwner = hwnd ;
  243.   ppd->hDevMode = (HANDLE) 0 ;
  244.   ppd->hDevNames = (HANDLE) 0 ;
  245.   ppd->hDC = (HDC) 0 ;
  246.   ppd->Flags = PD_RETURNDC | PD_COLLATE | PD_SHOWHELP | PD_PAGENUMS ;
  247.   ppd->nFromPage = 1 ;
  248.   ppd->nToPage = 10 ;
  249.   ppd->nMinPage = 0 ;
  250.   ppd->nMaxPage = 9 ;
  251.   ppd->nCopies = 1000 ;
  252.   ppd->hInstance = (HANDLE) hInst ;
  253.   ppd->lCustData = 0L ;
  254.   ppd->lpfnPrintHook = PrintHookProc ;
  255.   ppd->lpfnSetupHook = PrintHookProc ;
  256.   lstrcpy(szPrintTempName, TEXT("prtemp1")) ;
  257.   ppd->lpPrintTemplateName = szPrintTempName ;
  258.   lstrcpy(szSetupTempName, TEXT("prtemp2")) ;
  259.   ppd->lpSetupTemplateName = szSetupTempName ;
  260.   ppd->hPrintTemplate = (HANDLE) 0 ;   //these are unknown right now
  261.   ppd->hSetupTemplate = (HANDLE) 0 ;
  262.   /* Let's fill the hDevMode and hDevNames structures. */
  263.   /* This call should just return handles to structures of this */
  264.   /* type filled with the info for the default printer */
  265.   dwTempFlags = ppd->Flags ;
  266.   ppd->Flags = PD_RETURNDEFAULT | PD_RETURNDC ;
  267.   PrintDlg(ppd) ;
  268.   ppd->Flags = dwTempFlags ;
  269. }
  270. /************************************************************************
  271.   Function: FillPrintDlg(HWND, LPPRINTDLG)
  272.   Purpose:  Fills CDTEST's print dialog with the contents of a
  273.             PRINTDLG structure.
  274.   Returns:  Nothing.
  275.   Comments:
  276. ************************************************************************/
  277. void FillPrintDlg(HWND hwnd, LPPRINTDLG ppd)
  278. {
  279.   wsprintf(szTemp, szLongFilter, ppd->lStructSize) ;
  280.   SetDlgItemText(hwnd, ID_STRUCTSIZEP, szTemp) ;
  281.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hwndOwner) ;
  282.   SetDlgItemText(hwnd, ID_HWNDOWNERP, szTemp) ;
  283.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hDevMode) ;
  284.   SetDlgItemText(hwnd, ID_HDEVMODEP, szTemp) ;
  285.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hDevNames) ;
  286.   SetDlgItemText(hwnd, ID_HDEVNAMESP, szTemp) ;
  287.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hDC) ;
  288.   SetDlgItemText(hwnd, ID_HDCP, szTemp) ;
  289.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->Flags) ;
  290.   SetDlgItemText(hwnd, ID_FLAGSP, szTemp) ;
  291.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->nFromPage) ;
  292.   SetDlgItemText(hwnd, ID_FROMPAGEP, szTemp) ;
  293.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->nToPage) ;
  294.   SetDlgItemText(hwnd, ID_TOPAGEP, szTemp) ;
  295.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->nMinPage) ;
  296.   SetDlgItemText(hwnd, ID_MINPAGEP, szTemp) ;
  297.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->nMaxPage) ;
  298.   SetDlgItemText(hwnd, ID_MAXPAGEP, szTemp) ;
  299.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->nCopies) ;
  300.   SetDlgItemText(hwnd, ID_COPIESP, szTemp) ;
  301.   wsprintf(szTemp, szLongFilter, ppd->hInstance) ;
  302.   SetDlgItemText(hwnd, ID_HINSTANCEP, szTemp) ;
  303.   wsprintf(szTemp, szLongFilter, ppd->lCustData) ;
  304.   SetDlgItemText(hwnd, ID_CUSTDATAP, szTemp) ;
  305.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->lpfnPrintHook) ;
  306.   SetDlgItemText(hwnd, ID_PRINTHOOKP, szTemp) ;
  307.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->lpfnSetupHook) ;
  308.   SetDlgItemText(hwnd, ID_SETUPHOOKP, szTemp) ;
  309.   SetDlgItemText(hwnd, ID_LPPRINTTEMPP, ppd->lpPrintTemplateName) ;
  310.   SetDlgItemText(hwnd, ID_LPSETUPTEMPP, ppd->lpSetupTemplateName) ;
  311.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hPrintTemplate) ;
  312.   SetDlgItemText(hwnd, ID_HPRINTTEMPP, szTemp) ;
  313.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hSetupTemplate) ;
  314.   SetDlgItemText(hwnd, ID_HSETUPTEMPP, szTemp) ;
  315. }
  316. /************************************************************************
  317.   Function: GetPrintDlg(HWND, LPPRINTDLG)
  318.   Purpose:  Fills a PRINTDLG structure with the users choices in CDTEST's
  319.             print dialog box.
  320.   Returns:  Nothing.
  321.   Comments:
  322. ************************************************************************/
  323. void GetPrintDlg(HWND hwnd, LPPRINTDLG ppd)
  324. {
  325.   BOOL b ;
  326.   TCHAR szNum[20] ;
  327.   #define WMAX 20
  328.   GetDlgItemText(hwnd, ID_STRUCTSIZEP, szNum, WMAX) ;
  329.   ppd->lStructSize = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  330.   GetDlgItemText(hwnd, ID_HWNDOWNERP, szNum, WMAX) ;
  331.   ppd->hwndOwner = (HWND) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  332.   GetDlgItemText(hwnd, ID_HDEVMODEP, szNum, WMAX) ;
  333.   ppd->hDevMode = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  334.   GetDlgItemText(hwnd, ID_HDEVNAMESP, szNum, WMAX) ;
  335.   ppd->hDevNames = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  336.   GetDlgItemText(hwnd, ID_HDCP, szNum, WMAX) ;
  337.   ppd->hDC = (HDC) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  338.   GetDlgItemText(hwnd, ID_FLAGSP, szNum, WMAX) ;
  339.   ppd->Flags = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  340.   GetDlgItemText(hwnd, ID_FROMPAGEP, szNum, WMAX) ;
  341.   ppd->nFromPage = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  342.   GetDlgItemText(hwnd, ID_TOPAGEP, szNum, WMAX) ;
  343.   ppd->nToPage = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  344.   GetDlgItemText(hwnd, ID_MINPAGEP, szNum, WMAX) ;
  345.   ppd->nMinPage = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  346.   GetDlgItemText(hwnd, ID_MAXPAGEP, szNum, WMAX) ;
  347.   ppd->nMaxPage = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  348.   GetDlgItemText(hwnd, ID_COPIESP, szNum, WMAX) ;
  349.   ppd->nCopies = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  350.   GetDlgItemText(hwnd, ID_HINSTANCEP, szNum, WMAX) ;
  351.   ppd->hInstance = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  352.   GetDlgItemText(hwnd, ID_CUSTDATAP, szNum, WMAX) ;
  353.   ppd->lCustData = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  354.   GetDlgItemText(hwnd, ID_PRINTHOOKP, szNum, WMAX) ;
  355.   ppd->lpfnPrintHook = (LPPRINTHOOKPROC) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  356.   GetDlgItemText(hwnd, ID_SETUPHOOKP, szNum, WMAX) ;
  357.   ppd->lpfnSetupHook = (LPSETUPHOOKPROC) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  358.   GetDlgItemText(hwnd, ID_LPPRINTTEMPP, szPrintTempName, 100) ;
  359.   GetDlgItemText(hwnd, ID_LPSETUPTEMPP, szSetupTempName, 100) ;
  360.   GetDlgItemText(hwnd, ID_HPRINTTEMPP, szNum, WMAX) ;
  361.   ppd->hPrintTemplate = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  362.   GetDlgItemText(hwnd, ID_HSETUPTEMPP, szNum, WMAX) ;
  363.   ppd->hSetupTemplate = (HANDLE) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  364. }
  365. /************************************************************************
  366.   Function: FillDevnamesDlg(HWND, LPPRINTDLG)
  367.   Purpose:  Fills CDTEST's devnames dialog box with the values in
  368.             The hDevNames structure member of a PRINTDLG structure.
  369.   Returns:  Nothing.
  370.   Comments:
  371. ************************************************************************/
  372. void FillDevnamesDlg(HWND hwnd, LPPRINTDLG ppd)
  373. {
  374.   LPDEVNAMES pn = (LPDEVNAMES) 0 ;
  375.   if (ppd->hDevNames == (HANDLE) 0)
  376.     return ;
  377.   pn = (LPDEVNAMES) GlobalLock(ppd->hDevNames) ;
  378.   if (pn == (LPDEVNAMES) NULL) return ;
  379.   /* To find the strings in this block of memory, add the correct
  380.      offset to the original pointer returned by GlobalLock() */
  381.   SetDlgItemText(hwnd, ID_WDRIVEROFF, (LPTSTR) pn + pn->wDriverOffset) ;
  382.   SetDlgItemText(hwnd, ID_WDEVICEOFF, (LPTSTR) pn + pn->wDeviceOffset) ;
  383.   SetDlgItemText(hwnd, ID_WOUTPUTOFF, (LPTSTR) pn + pn->wOutputOffset) ;
  384.   wsprintf(szTemp, szShortFilter, (int) pn->wDefault) ;
  385.   SetDlgItemText(hwnd, ID_WDEFAULT, szTemp) ;
  386.   GlobalUnlock(ppd->hDevNames) ;
  387. }
  388. /************************************************************************
  389.   Function: GetDevnamesDlg(HWND, LPPRINTDLG)
  390.   Purpose:  Retrieves the user's choices in CDTEST's devnames dialog box,
  391.             Allocates some memory to hold a new DEVNAMES structure, fills
  392.             the users choices into the new DEVNAMES structure, and sets
  393.             the hDevNames member of a PRINTDLG structure to this new
  394.             memory handle.
  395.   Returns:  Nothing.
  396.   Comments:
  397. ************************************************************************/
  398. void GetDevnamesDlg(HWND hwnd, LPPRINTDLG ppd)
  399. {
  400.   BOOL b ;
  401.   TCHAR szNum[30] ;
  402.   LPDEVNAMES pn ;
  403.   TCHAR sz1[100] ;
  404.   TCHAR sz2[100] ;
  405.   TCHAR sz3[100] ;
  406.   DWORD dwSize ;
  407.   int n1, n2, n3 ;
  408.   GetDlgItemText(hwnd, ID_WDRIVEROFF, sz1, 100) ;
  409.   GetDlgItemText(hwnd, ID_WDEVICEOFF, sz2, 100) ;
  410.   GetDlgItemText(hwnd, ID_WOUTPUTOFF, sz3, 100) ;
  411.   n1 = lstrlen(sz1) ;
  412.   n2 = lstrlen(sz2) ;
  413.   n3 = lstrlen(sz3) ;
  414.   if (hDevNames)
  415.   {
  416.     GlobalFree(hDevNames) ;
  417.     hDevNames = (HANDLE) 0 ;
  418.   }
  419.   /* allocate size of everything + 5 extra bytes for zeroes */
  420.   dwSize = sizeof(DEVNAMES) + ((n1+n2+n3+5) * sizeof(TCHAR)) ;
  421.   /* Allocate the memory and lock it down */
  422.   if (!(hDevNames = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize)))
  423.   {
  424.     MessageBox(hwnd, TEXT("Can't Alloc memory for hDevNames!"),
  425.                TEXT("Fatal Error!"), MB_OK | MB_APPLMODAL) ;
  426.     return ;
  427.   }
  428.   if (!(pn = (LPDEVNAMES) GlobalLock(hDevNames)))
  429.   {
  430.     MessageBox(hwnd, TEXT("Can't Lock New hDevNames memory!"),
  431.                TEXT("Fatal Error"), MB_OK | MB_APPLMODAL) ;
  432.     GlobalFree(hDevNames) ;
  433.     hDevNames = (HANDLE) 0 ;
  434.     return ;
  435.   }
  436.   /* skip over devnames and copy string 1 there.  Make sure to
  437.      divide by sizeof(TCHAR) or the compiler will create a pointer
  438.      that points too far if you compile as a UNICODE program */
  439.   pn->wDriverOffset = sizeof(DEVNAMES) / sizeof(TCHAR) ;
  440.   lstrcpy((LPTSTR) pn + pn->wDriverOffset, (LPTSTR) sz1) ;
  441.   /* skip over string 1 and add string 1 with a zero between them */
  442.   pn->wDeviceOffset = pn->wDriverOffset + n1 + 1 ;
  443.   lstrcpy((LPTSTR) pn + pn->wDeviceOffset, (LPTSTR) sz2) ;
  444.   /* skip over string 2 and put string 3 there with a zero between them */
  445.   pn->wOutputOffset = pn->wDeviceOffset + n2 + 1 ;
  446.   lstrcpy((LPTSTR) pn + pn->wOutputOffset, (LPTSTR) sz3) ;
  447.   GetDlgItemText(hwnd, ID_WDEFAULT, szNum, 30) ;
  448.   pn->wDefault = (WORD) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  449.   GlobalUnlock(hDevNames) ;
  450.   ppd->hDevNames = hDevNames ;
  451.   wsprintf(szTemp, szLongFilter, ppd->hDevNames) ;
  452.   SetDlgItemText(GetParent(hwnd), ID_HDEVNAMESP, szTemp) ;
  453. }
  454. /************************************************************************
  455.   Function: FillDevmodeDlg(HWND, LPPRINTDLG)
  456.   Purpose: Fills CDTEST's devmode dialog with the contents of the DEVMODE
  457.            structure handle of a PRINTDLG structure.
  458.   Returns:  Nothing.
  459.   Comments:
  460. ************************************************************************/
  461. void FillDevmodeDlg(HWND hwnd, LPPRINTDLG ppd)
  462. {
  463.   LPDEVMODE p ;
  464.   if (ppd->hDevMode == (HANDLE) 0)
  465.     return ;
  466.   p = (LPDEVMODE) GlobalLock(ppd->hDevMode) ;
  467.   if (p == (LPDEVMODE) NULL) return ;
  468.   SetDlgItemText(hwnd, ID_DMDEVNAME, (LPTSTR) p->dmDeviceName) ;
  469.   wsprintf(szTemp, szShortFilter, (int) p->dmSpecVersion) ;
  470.   SetDlgItemText(hwnd, ID_DMSPECVER, szTemp) ;
  471.   wsprintf(szTemp, szShortFilter, (int) p->dmDriverVersion) ;
  472.   SetDlgItemText(hwnd, ID_DMDRIVERVER, szTemp) ;
  473.   wsprintf(szTemp, szShortFilter, (int) p->dmSize) ;
  474.   SetDlgItemText(hwnd, ID_DMSIZEDEV, szTemp) ;
  475.   wsprintf(szTemp, szShortFilter, (int) p->dmDriverExtra) ;
  476.   SetDlgItemText(hwnd, ID_DMDRIVEREXTRA, szTemp) ;
  477.   wsprintf(szTemp, szShortFilter, (int) p->dmFields) ;
  478.   SetDlgItemText(hwnd, ID_DMFIELDS, szTemp) ;
  479.   wsprintf(szTemp, szShortFilter, (int) p->dmOrientation) ;
  480.   SetDlgItemText(hwnd, ID_DMORIENTATION, szTemp) ;
  481.   wsprintf(szTemp, szShortFilter, (int) p->dmPaperSize) ;
  482.   SetDlgItemText(hwnd, ID_DMPAPERSIZE, szTemp) ;
  483.   wsprintf(szTemp, szLongFilter, p->dmPaperLength) ;
  484.   SetDlgItemText(hwnd, ID_DMPAPERLENGTH, szTemp) ;
  485.   wsprintf(szTemp, szLongFilter, p->dmPaperWidth) ;
  486.   SetDlgItemText(hwnd, ID_DMPAPERWIDTH, szTemp) ;
  487.   wsprintf(szTemp, szLongFilter, p->dmScale) ;
  488.   SetDlgItemText(hwnd, ID_DMSCALE, szTemp) ;
  489.   wsprintf(szTemp, szLongFilter, p->dmCopies) ;
  490.   SetDlgItemText(hwnd, ID_DMCOPIES, szTemp) ;
  491.   wsprintf(szTemp, szLongFilter, p->dmDefaultSource) ;
  492.   SetDlgItemText(hwnd, ID_DMDEFAULTSOURCE, szTemp) ;
  493.   wsprintf(szTemp, szLongFilter, p->dmPrintQuality) ;
  494.   SetDlgItemText(hwnd, ID_DMPRINTQUALITY, szTemp) ;
  495.   wsprintf(szTemp, szLongFilter, p->dmColor) ;
  496.   SetDlgItemText(hwnd, ID_DMCOLOR, szTemp) ;
  497.   wsprintf(szTemp, szLongFilter, p->dmDuplex) ;
  498.   SetDlgItemText(hwnd, ID_DMDUPLEX, szTemp) ;
  499.   wsprintf(szTemp, szLongFilter, p->dmCollate) ;
  500.   SetDlgItemText(hwnd, ID_DMCOLLATE, szTemp) ;
  501.   SetDlgItemText(hwnd, ID_DMFORMNAME, (LPTSTR) p->dmFormName) ;
  502.   wsprintf(szTemp, szLongFilter, p->dmBitsPerPel) ;
  503.   SetDlgItemText(hwnd, ID_DMBITSPERPEL, szTemp) ;
  504.   wsprintf(szTemp, szLongFilter, p->dmPelsWidth) ;
  505.   SetDlgItemText(hwnd, ID_DMPELSWIDTH, szTemp) ;
  506.   wsprintf(szTemp, szLongFilter, p->dmPelsHeight) ;
  507.   SetDlgItemText(hwnd, ID_DMPELSHEIGHT, szTemp) ;
  508.   wsprintf(szTemp, szLongFilter, p->dmDisplayFrequency) ;
  509.   SetDlgItemText(hwnd, ID_DMDISPLAYFREQ, szTemp) ;
  510.   GlobalUnlock(ppd->hDevMode) ;
  511. }
  512. /************************************************************************
  513.   Function: GetDevmodeDlg(HWND, LPPRINTDLG)
  514.   Purpose:  Retrieves the user's edits in CDTEST's DEVMODE dialog box,
  515.             allocates memory for a new DEVMODE structure, fills that
  516.             memory with the user's edits, and puts a handle to that
  517.             memory in the hDevMode member of a PRINTDLG structure.
  518.   Returns:  Nothing.
  519.   Comments:
  520. ************************************************************************/
  521. void GetDevmodeDlg(HWND hwnd, LPPRINTDLG ppd)
  522. {
  523.   LPDEVMODE p ;
  524.   BOOL b ;
  525.   TCHAR szNum[30] ;
  526.   #define WMAXDEV 30
  527.   if (hDevMode)
  528.   {
  529.     GlobalFree(hDevMode) ;
  530.     hDevMode = (HANDLE) 0 ;
  531.   }
  532.   if (!(hDevMode = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, sizeof(DEVMODE))))
  533.   {
  534.     MessageBox(hwnd, TEXT("Can't allocate memory for hDevMode"),
  535.                TEXT("Fatal Error"), MB_OK | MB_APPLMODAL) ;
  536.     return ;
  537.   }
  538.   if (!(p = (LPDEVMODE) GlobalLock(hDevMode)))
  539.   {
  540.     MessageBox(hwnd, TEXT("Can't lock memory for hDevMode"),
  541.                TEXT("Fatal Error"), MB_OK | MB_APPLMODAL) ;
  542.     GlobalFree(hDevMode) ;
  543.     hDevMode = (HANDLE) 0 ;
  544.     return ;
  545.   }
  546.   GetDlgItemText(hwnd, ID_DMDEVNAME, p->dmDeviceName, 32) ;
  547.   GetDlgItemText(hwnd, ID_DMSPECVER, szNum, WMAXDEV) ;
  548.   p->dmSpecVersion = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  549.   GetDlgItemText(hwnd, ID_DMDRIVERVER, szNum, WMAXDEV) ;
  550.   p->dmDriverVersion = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  551.   GetDlgItemText(hwnd, ID_DMSIZEDEV, szNum, WMAXDEV) ;
  552.   p->dmSize = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  553.   GetDlgItemText(hwnd, ID_DMDRIVEREXTRA, szNum, WMAXDEV) ;
  554.   p->dmDriverExtra = (WORD) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  555.   GetDlgItemText(hwnd, ID_DMFIELDS, szNum, WMAXDEV) ;
  556.   p->dmFields = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  557.   GetDlgItemText(hwnd, ID_DMORIENTATION, szNum, WMAXDEV) ;
  558.   p->dmOrientation = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  559.   GetDlgItemText(hwnd, ID_DMPAPERSIZE, szNum, WMAXDEV) ;
  560.   p->dmPaperSize = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  561.   GetDlgItemText(hwnd, ID_DMPAPERLENGTH, szNum, WMAXDEV) ;
  562.   p->dmPaperLength = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  563.   GetDlgItemText(hwnd, ID_DMPAPERWIDTH, szNum, WMAXDEV) ;
  564.   p->dmPaperWidth = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  565.   GetDlgItemText(hwnd, ID_DMSCALE, szNum, WMAXDEV) ;
  566.   p->dmScale = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  567.   GetDlgItemText(hwnd, ID_DMCOPIES, szNum, WMAXDEV) ;
  568.   p->dmCopies = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  569.   GetDlgItemText(hwnd, ID_DMDEFAULTSOURCE, szNum, WMAXDEV) ;
  570.   p->dmDefaultSource = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  571.   GetDlgItemText(hwnd, ID_DMPRINTQUALITY, szNum, WMAXDEV) ;
  572.   p->dmPrintQuality = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  573.   GetDlgItemText(hwnd, ID_DMCOLOR, szNum, WMAXDEV) ;
  574.   p->dmColor = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  575.   GetDlgItemText(hwnd, ID_DMDUPLEX, szNum, WMAXDEV) ;
  576.   p->dmDuplex = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  577.   GetDlgItemText(hwnd, ID_DMCOLLATE, szNum, WMAXDEV) ;
  578.   p->dmCollate = (short) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  579.   GetDlgItemText(hwnd, ID_DMFORMNAME, p->dmFormName, 32) ;
  580.   GetDlgItemText(hwnd, ID_DMBITSPERPEL, szNum, WMAXDEV) ;
  581.   p->dmBitsPerPel = (USHORT) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  582.   GetDlgItemText(hwnd, ID_DMPELSWIDTH, szNum, WMAXDEV) ;
  583.   p->dmPelsWidth = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  584.   GetDlgItemText(hwnd, ID_DMPELSHEIGHT, szNum, WMAXDEV) ;
  585.   p->dmPelsHeight = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  586.   GetDlgItemText(hwnd, ID_DMDISPLAYFREQ, szNum, WMAXDEV) ;
  587.   p->dmDisplayFrequency = MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  588.   GlobalUnlock(hDevMode) ;
  589.   ppd->hDevMode = hDevMode ;
  590.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hDevMode) ;
  591.   SetDlgItemText(GetParent(hwnd), ID_HDEVMODEP, szTemp) ;
  592. }
  593. /************************************************************************
  594.   Function: GetPrintDlgHandle(void)
  595.   Purpose:  Finds the custom Print dialog template in the EXE, loads it
  596.             into a handle, and returns the handle.
  597.   Returns:  Nothing.
  598.   Comments:
  599. ************************************************************************/
  600. HANDLE GetPrintDlgHandle(void)
  601. {
  602.   hResPrint = FindResource(hInst, TEXT("prtemp1"), RT_DIALOG) ;
  603.   hDialogPrint = LoadResource(hInst, hResPrint) ;
  604.   return hDialogPrint ;
  605. }
  606. /************************************************************************
  607.   Function: GetSetupDlgHandle(void)
  608.   Purpose:  Finds the custom Setup dialog template in the EXE, loads it
  609.             into a handle, and returns the handle.
  610.   Returns:  Nothing.
  611.   Comments:
  612. ************************************************************************/
  613. HANDLE GetSetupDlgHandle(void)
  614. {
  615.   hResPrint = FindResource(hInst, TEXT("prtemp2"), RT_DIALOG) ;
  616.   hDialogPrint = LoadResource(hInst, hResPrint) ;
  617.   return hDialogPrint ;
  618. }
  619. /************************************************************************
  620.   Function: PrintHookProc(HWND, UINT, UINT, LONG)
  621.   Purpose:  A callback function that will receive messages intended for
  622.             the PrintDlg() dialog boxes before the normal common dialog
  623.             routine receives them.
  624.   Returns:  FALSE to allow the common dialogs to process the message
  625.             with its normal logic.  TRUE to discard the message.
  626.   Comments:
  627.      To enable this function for the Print dialog in CDTEST, enter the
  628.      value for PD_ENABLEPRINTHOOK in the "Flags" edit box.
  629.      To enable this function for the Setup dialog in CDTEST, enter the
  630.      value for (PD_ENABLESETUPHOOK | PD_PRINTSETUP) in the "Flags" edit box.
  631. ************************************************************************/
  632. UINT APIENTRY PrintHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  633. {
  634.   LPPRINTDLG pPr ;
  635.   TCHAR szMsg[50] ;
  636.   switch(msg)
  637.   {
  638.     case WM_INITDIALOG:
  639.       pPr = (LPPRINTDLG) lParam ;
  640.       if (pPr->lCustData != 0)
  641.       {
  642.         wsprintf(szMsg, TEXT("PRINTDLG->lCustData is: %ld"), pPr->lCustData) ;
  643.         MessageBox(hwnd, szMsg, TEXT("lCustData Sent!"), MB_OK | MB_APPLMODAL) ;
  644.       }
  645.       SetWindowText(hwnd, TEXT("Print Hook Proc Dialog")) ;
  646.       break ;
  647.     /* use the WM_CTLCOLOR* messages to change the color of the Open
  648.        dialog */
  649.     case WM_CTLCOLORDLG:
  650.         if (!hBrushDlg)
  651.             hBrushDlg = GetStockObject(LTGRAY_BRUSH) ;
  652.         return (UINT) hBrushDlg ;
  653.         break ;
  654.     case WM_CTLCOLORBTN:
  655.         SetBkMode((HDC) wParam, TRANSPARENT) ;   //sets background color
  656.                                                  //for push and check box
  657.                                                  //buttons...
  658.         if (!hBrushButton)
  659.             hBrushButton = GetStockObject(LTGRAY_BRUSH) ;
  660.         return (UINT) hBrushButton ;
  661.         break ;
  662.     case WM_CTLCOLORSTATIC:
  663.         SetTextColor((HDC) wParam, RGB(0x00, 0xff, 0x00)) ;  //green
  664.         SetBkMode((HDC) wParam, TRANSPARENT) ;               //transparent text
  665.         if (!hBrushDlg)
  666.             hBrushDlg = GetStockObject(LTGRAY_BRUSH) ;
  667.         return (UINT) hBrushDlg ;
  668.         break ;
  669.     default:
  670.       break ;
  671.   }
  672.   return FALSE ;   //send msg to the common dialog code
  673. }
  674. /************************************************************************
  675.   Function: PrintMultiProc1(LPDWORD)
  676.   Purpose:  Is the starting address for the first new thread when
  677.             multithreading.
  678.   Returns:  Any DWORD value.
  679.   Comments:
  680.             The new thread will start executing here and will end when
  681.             the PrintDlg() function returns and it has posted a message
  682.             to the CDTEST's print dialog window saying that one of the
  683.             two multithreading dialogs been terminated.
  684. ************************************************************************/
  685. DWORD PrintMultiProc1(LPDWORD pdw)
  686. {
  687.   GetPrintDlg(hwndMainPrint, &pdThread1) ;
  688.   DoPrintDlgStuff(hwndMainPrint, &pdThread1) ;
  689.   PostMessage(hwndMainPrint, UMSG_DECREMENTDLGCOUNT, 0, 0L ) ;
  690.   return 0L ;
  691. }
  692. /************************************************************************
  693.   Function: PrintMultiProc2(LPDWORD)
  694.   Purpose:  Is the starting address for the second new thread when
  695.             multithreading.
  696.   Returns:  Any DWORD value.
  697.   Comments:
  698.             The new thread will start executing here and will end when
  699.             the PrintDlg() function returns and it has posted a message
  700.             to the CDTEST's print dialog window saying that one of the
  701.             two multithreading dialogs been terminated.
  702. ************************************************************************/
  703. DWORD PrintMultiProc2(LPDWORD pdw)
  704. {
  705.   GetPrintDlg(hwndMainPrint, &pdThread2) ;
  706.   DoPrintDlgStuff(hwndMainPrint, &pdThread2) ;
  707.   PostMessage(hwndMainPrint, UMSG_DECREMENTDLGCOUNT, 0, 0L ) ;
  708.   return 0L ;
  709. }
  710. /************************************************************************
  711.   Function: MultiThreadPrintDlg(void)
  712.   Purpose:  Is the starting address for the first new thread when
  713.             multithreading.
  714.   Returns:  Any DWORD value.
  715.   Comments:
  716.             The new thread will start executing here and will end when
  717.             the PrintDlg() function returns and it has posted a message
  718.             to the CDTEST's print dialog window saying that one of the
  719.             two multithreading dialogs been terminated.
  720. ************************************************************************/
  721. void MultiThreadPrintDlg(void)
  722. {
  723.   dwPrintThreadParm1 = dwPrintThreadParm2 = 0L ;
  724.   if (!(hPrintThread1 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
  725.                                      (LPTHREAD_START_ROUTINE) PrintMultiProc1,
  726.                                      &dwPrintThreadParm1, CREATE_SUSPENDED, &dwPrintThreadID1)))
  727.   {
  728.     MessageBox(GetForegroundWindow(), TEXT("Error creating thread 1"), NULL,
  729.                MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL) ;
  730.     nOpenDialogCount = 0 ;
  731.     EnablePrintControls(hwndMainPrint, TRUE) ;
  732.     return ;
  733.   }
  734.   if (!(hPrintThread2 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
  735.                                      (LPTHREAD_START_ROUTINE) PrintMultiProc2,
  736.                                      &dwPrintThreadParm2, CREATE_SUSPENDED, &dwPrintThreadID2)))
  737.   {
  738.     MessageBox(GetForegroundWindow(), TEXT("Error creating thread 2"), NULL,
  739.                MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL) ;
  740.     nOpenDialogCount = 0 ;
  741.     EnablePrintControls(hwndMainPrint, TRUE) ;
  742.     return ;
  743.   }
  744.   ResumeThread(hPrintThread1) ;
  745.   ResumeThread(hPrintThread2) ;
  746.   return ;
  747. }
  748. /************************************************************************
  749.   Function: EnablePrintControls(HWND, BOOL)
  750.   Purpose:  Enable or disable CDTEST's print dialog's controls.
  751.   Returns:  Nothing.
  752.   Comments: This is necessary when CDTEST is multithreading.
  753. ************************************************************************/
  754. void EnablePrintControls(HWND hwnd, BOOL bEnable)
  755. {
  756.   EnableWindow(GetDlgItem(hwnd, IDOK), bEnable) ;
  757.   EnableWindow(GetDlgItem(hwnd, IDCANCEL), bEnable) ;
  758.   EnableWindow(GetDlgItem(hwnd, ID_RESETPRINT), bEnable) ;
  759.   EnableWindow(GetDlgItem(hwnd, ID_MULTITHREADPRINT), bEnable) ;
  760.   EnableWindow(GetDlgItem(hwnd, ID_EDITDEVMODE), bEnable) ;
  761.   EnableWindow(GetDlgItem(hwnd, ID_EDITDEVNAMES), bEnable) ;
  762. }
  763. /************************************************************************
  764.   Function: DoPrintDlgStuff(HWND, LPPRINTDLG)
  765.   Purpose:  Calls PrintDlg() with the correct parameters.
  766.   Returns:  Nothing.
  767.   Comments:
  768. ************************************************************************/
  769. void DoPrintDlgStuff(HWND hwnd, LPPRINTDLG ppd)
  770. {
  771.   BOOL bRet = FALSE ;
  772.   /* Figure out how the user want's to call PrintDlg() */
  773.   if (IsDlgButtonChecked(hwnd, ID_PREPRINTP) == 1)
  774.     ppd->hPrintTemplate = GetPrintDlgHandle() ;
  775.   if (IsDlgButtonChecked(hwnd, ID_PRESETUPP) == 1)
  776.     ppd->hSetupTemplate = GetSetupDlgHandle() ;
  777.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hPrintTemplate) ;
  778.   SetDlgItemText(hwnd, ID_HPRINTTEMPP, szTemp) ;
  779.   wsprintf(szTemp, szLongFilter, (DWORD) ppd->hSetupTemplate) ;
  780.   SetDlgItemText(hwnd, ID_HSETUPTEMPP, szTemp) ;
  781.   /* Call the function */
  782.   if (IsDlgButtonChecked(hwnd, ID_NULLSTRUCTP) == 1)
  783.     bRet = PrintDlg((LPPRINTDLG) NULL) ;
  784.   else
  785.     bRet = PrintDlg(ppd) ;
  786.   /* Clean up and show results */
  787.   wsprintf(szTemp, szLongFilter, CommDlgExtendedError()) ;
  788.   SetDlgItemText(hwnd, ID_ERRORP, szTemp) ;
  789.   SetDlgItemInt(hwnd, ID_RETURNP, bRet, TRUE) ;
  790.   if (hDialogPrint)
  791.   {
  792.     FreeResource(hDialogPrint) ; //obsolete call, but
  793.     hDialogPrint = (HANDLE) 0 ;  //it's possible that this
  794.     hResPrint = (HANDLE) 0 ;    //might be recompiled for win 3.x
  795.   }
  796.   pd.hDevMode = ppd->hDevMode ;    //need to fix this so that FillDevnamesDlg()
  797.   pd.hDevNames = ppd->hDevNames ;  //and FillDevmodeDlg() work...
  798.   FillPrintDlg(hwnd, ppd) ;
  799.   if (ppd->hDC)  //release the HDC after its value is
  800.                  //returned to the test app
  801.   {
  802.     ReleaseDC(ppd->hwndOwner, ppd->hDC) ;
  803.     ppd->hDC = (HDC) 0 ;
  804.   }
  805. }