- implementation of RtlReg* (read access), RtlEvent*, RtlSemaphore*,
[wine] / dlls / commdlg / printdlg.c
1 /*
2  * COMMDLG - Print Dialog
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  * Copyright 1999 Klaas van Gend
7  */
8
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "winbase.h"
13 #include "wine/winbase16.h"
14 #include "wine/winuser16.h"
15 #include "ldt.h"
16 #include "commdlg.h"
17 #include "resource.h"
18 #include "dialog.h"
19 #include "dlgs.h"
20 #include "module.h"
21 #include "debugtools.h"
22 #include "winproc.h"
23 #include "cderr.h"
24 #include "winspool.h"
25 #include "winerror.h"
26
27 DEFAULT_DEBUG_CHANNEL(commdlg)
28
29 #include "cdlg.h"
30
31
32 /* This PRINTDLGA internal structure stores
33  * pointers to several throughout useful structures.
34  * 
35  */
36 typedef struct  
37 {
38   LPPRINTER_INFO_2A lpPrinterInfo;
39   UINT              CurrentPrinter;  /* used as lpPrinterInfo[CurrentPrinter] */
40   UINT              DefaultPrinter;  /* used as lpPrinterInfo[DefaultPrinter] */
41   DWORD             NrOfPrinterInfoEntries;
42   LPPRINTDLGA       lpPrintDlg;
43   UINT              HelpMessageID;
44   HICON             hCollateIcon;    /* PrintDlg only */
45   HICON             hNoCollateIcon;  /* PrintDlg only */
46   HICON             hPortraitIcon;   /* PrintSetupDlg only */
47   HICON             hLandscapeIcon;  /* PrintSetupDlg only */
48 } PRINT_PTRA;
49
50
51 /* prototypes */
52 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg, 
53                                                   PRINT_PTRA* PrintStructures);
54
55 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
56                                     LPARAM lParam);
57
58
59 /***********************************************************************
60  *           PrintDlg16   (COMMDLG.20)
61  * 
62  *  Displays the the PRINT dialog box, which enables the user to specify
63  *  specific properties of the print job.
64  *
65  * RETURNS
66  *  nonzero if the user pressed the OK button
67  *  zero    if the user cancelled the window or an error occurred
68  *
69  * BUGS
70  *  * calls up to the 32-bit versions of the Dialogs, which look different
71  *  * Customizing is *not* implemented.
72  */
73 BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lpPrint )
74 {
75     PRINTDLGA Print32;
76     BOOL16 ret;
77
78     memset(&Print32, 0, sizeof(Print32));
79     Print32.lStructSize = sizeof(Print32);
80     Print32.hwndOwner   = lpPrint->hwndOwner;
81     Print32.hDevMode    = lpPrint->hDevMode;
82     Print32.hDevNames   = lpPrint->hDevNames;
83     Print32.Flags       = lpPrint->Flags;
84     Print32.nFromPage   = lpPrint->nFromPage;
85     Print32.nToPage     = lpPrint->nToPage;
86     Print32.nMinPage    = lpPrint->nMinPage;
87     Print32.nMaxPage    = lpPrint->nMaxPage;
88     Print32.nCopies     = lpPrint->nCopies;
89     Print32.hInstance   = lpPrint->hInstance;
90     Print32.lCustData   = lpPrint->lCustData;
91     if(lpPrint->lpfnPrintHook) {
92         FIXME("Need to allocate thunk\n");
93 /*        Print32.lpfnPrintHook = lpPrint->lpfnPrintHook;*/
94     }
95     if(lpPrint->lpfnSetupHook) {
96         FIXME("Need to allocate thunk\n");
97 /*      Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
98     }
99     Print32.lpPrintTemplateName = PTR_SEG_TO_LIN(lpPrint->lpPrintTemplateName);
100     Print32.lpSetupTemplateName = PTR_SEG_TO_LIN(lpPrint->lpSetupTemplateName);
101     Print32.hPrintTemplate = lpPrint->hPrintTemplate;
102     Print32.hSetupTemplate = lpPrint->hSetupTemplate;
103
104     ret = PrintDlgA(&Print32);
105
106     lpPrint->hDevMode  = Print32.hDevMode;
107     lpPrint->hDevNames = Print32.hDevNames;
108     lpPrint->hDC       = Print32.hDC;
109     lpPrint->Flags     = Print32.Flags;
110     lpPrint->nFromPage = Print32.nFromPage;
111     lpPrint->nToPage   = Print32.nToPage;
112     lpPrint->nCopies   = Print32.nCopies;
113
114     return ret;
115 }
116
117
118 /***********************************************************************
119  *           PrintDlgA   (COMDLG32.17)
120  *
121  *  Displays the the PRINT dialog box, which enables the user to specify
122  *  specific properties of the print job.
123  *
124  * RETURNS
125  *  nonzero if the user pressed the OK button
126  *  zero    if the user cancelled the window or an error occurred
127  *
128  * BUGS
129  *  PrintDlg:
130  *  * The Collate Icons do not display, even though they are in the code.
131  *  * The Properties Button(s) should call DocumentPropertiesA().
132  *  PrintSetupDlg:
133  *  * The Paper Orientation Icons are not implemented yet.
134  *  * The Properties Button(s) should call DocumentPropertiesA().
135  *  * Settings are not yet taken from a provided DevMode or 
136  *    default printer settings.
137  */
138 BOOL WINAPI PrintDlgA(
139                          LPPRINTDLGA lppd /* ptr to PRINTDLG32 struct */
140                          )
141 {
142 /* My implementing strategy:
143  * 
144  * step 1: display the dialog and implement the layout-flags
145  * step 2: enter valid information in the fields (e.g. real printers)
146  * step 3: fix the RETURN-TRUE-ALWAYS Fixme by checking lppd->Flags for
147  *         PD_RETURNDEFAULT
148  * step 4: implement all other specs
149  * step 5: allow customisation of the dialog box
150  *
151  * current implementation is in step 4.
152  */ 
153
154     HWND      hwndDialog;
155     BOOL      bRet = FALSE;
156     LPCVOID   ptr;
157     HANDLE    hResInfo, hDlgTmpl;
158     HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
159     DWORD     EnumBytesNeeded;
160     DWORD     CopyOfEnumBytesNeeded;
161     PRINT_PTRA PrintStructures;
162
163     TRACE("(lppd: %p)\n", lppd);
164     PrintStructures.lpPrintDlg      = lppd;
165     
166     /* load Dialog resources, 
167      * depending on Flags indicates Print32 or Print32_setup dialog 
168      */
169     if (lppd->Flags & PD_PRINTSETUP)
170         hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", RT_DIALOGA);
171     else
172         hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", RT_DIALOGA);
173     if (!hResInfo)
174       {
175            COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
176            return FALSE;
177       }
178     
179     if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
180         !(ptr = LockResource( hDlgTmpl )))
181       {
182        COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
183        return FALSE;
184       }
185
186     /* load Collate ICONs */
187     PrintStructures.hCollateIcon = 
188                               LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
189     PrintStructures.hNoCollateIcon = 
190                                 LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
191     if (PrintStructures.hCollateIcon==0 || PrintStructures.hNoCollateIcon==0)
192     {
193     ERR("no icon in resourcefile???");
194         COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
195         return FALSE;
196     }
197
198     /* load Paper Orientation ICON */
199         /* FIXME: not implemented yet */
200
201     /*
202      * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
203      * must be registered and the Help button must be shown.
204      */
205     if (lppd->Flags & PD_SHOWHELP)
206        {
207         if((PrintStructures.HelpMessageID = 
208                        RegisterWindowMessageA(HELPMSGSTRING)) == 0)
209             {
210              COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
211              return FALSE;
212             }
213        }
214     else
215         PrintStructures.HelpMessageID=0;
216         
217     /* Use EnumPrinters to obtain a list of PRINTER_INFO_2A's
218      * and store a pointer to this list in our "global structure"
219      * as reference for the rest of the PrintDlg routines
220      */
221     EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 
222         0, &EnumBytesNeeded, &PrintStructures.NrOfPrinterInfoEntries);
223     CopyOfEnumBytesNeeded=EnumBytesNeeded+16;
224     PrintStructures.lpPrinterInfo = malloc(CopyOfEnumBytesNeeded*sizeof(char));
225     EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, 
226         (LPBYTE)PrintStructures.lpPrinterInfo, 
227         CopyOfEnumBytesNeeded, &EnumBytesNeeded, 
228         &PrintStructures.NrOfPrinterInfoEntries);
229
230     /* Find the default printer.
231      * If not: display a warning message (unless PD_NOWARNING specified)
232      * and return PDERR_NODEFAULTPRN
233      */
234     /* FIXME: not implemented yet!!! */
235     if (!PrintStructures.NrOfPrinterInfoEntries)
236     {
237         COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
238         return FALSE;
239     }
240     PrintStructures.CurrentPrinter=0; 
241     PrintStructures.DefaultPrinter=0; 
242      
243     /* FIXME: Currently Unimplemented */
244     if (lppd->Flags & PD_NOWARNING)     
245            {
246             COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE); 
247             WARN(": PD_NOWARNING Flag is not yet implemented.\n");
248            }
249         
250     /*
251      * FIXME : Should respond to TEMPLATE and HOOK flags here
252      * For now, only the standard dialog works.
253      */
254     if (lppd->Flags & (PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE |
255                           PD_ENABLEPRINTTEMPLATEHANDLE | PD_ENABLESETUPHOOK | 
256                           PD_ENABLESETUPTEMPLATE|PD_ENABLESETUPTEMPLATEHANDLE)) 
257         FIXME(": unimplemented flag (ignored)\n");     
258         
259     /*
260      * if lppd->Flags PD_RETURNDEFAULT is specified, the PrintDlg function
261      * does not display the dialog box, but returns with valid entries
262      * for hDevMode and hDevNames .
263      *
264      * According to MSDN, it is required that hDevMode and hDevNames equal
265      * zero if this flag is set.
266      */
267     if (lppd->Flags & PD_RETURNDEFAULT)
268        {
269         TRACE(" PD_RETURNDEFAULT: was requested to return printer info only.\n");
270         if (lppd->hDevMode!=0 || lppd->hDevNames !=0)
271             {
272              COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE); 
273              return(FALSE);
274             }
275         return(PRINTDLG_ValidateAndDuplicateSettings(0, &PrintStructures));
276        }
277         
278     /* and create & process the dialog 
279      */
280         if (lppd->Flags & PD_PRINTSETUP)
281                 {
282          hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
283             (DLGPROC16)PrintSetupDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
284         }
285     else
286                 {
287          hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
288             (DLGPROC16)PrintDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
289         }
290     if (hwndDialog) 
291         bRet = DIALOG_DoDialogBox(hwndDialog, lppd->hwndOwner);  
292      
293     /* free memory & resources
294      */   
295     free(PrintStructures.lpPrinterInfo);
296     DeleteObject(PrintStructures.hCollateIcon);
297     DeleteObject(PrintStructures.hNoCollateIcon);
298     /* FIXME: don't forget to delete the paper orientation icons here! */
299
300   TRACE(" exit! (%d)", bRet);        
301   return bRet;            
302 }
303
304
305
306 /***********************************************************************
307  *           PrintDlg32W   (COMDLG32.18)
308  */
309 BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
310 {
311     FIXME("A really empty stub\n" );
312     return FALSE;
313 }
314
315
316 /***********************************************************************
317  *               PRINTDLG_UpdatePrinterInfoTexts               [internal]
318  */
319 void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, PRINT_PTRA* PrintStructures)
320 {
321     char   StatusMsg[256];
322     char   ResourceString[256];
323     int    i;
324     LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
325                                              [PrintStructures->CurrentPrinter]);
326     
327     /* Status Message */
328     StatusMsg[0]='\0';
329     /* FIXME: if default printer, add this first */
330     ;
331     /* add all status messages */
332     for (i=0; i< 25; i++)
333     {
334         if (lpPi->Status & (1<<i))
335         {
336          LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, 
337                         ResourceString, 255);
338          strcat(StatusMsg,ResourceString);
339         }
340     }
341     /* append "ready" */
342     /* FIXME: status==ready must only be appended if really so. 
343               but how to detect??? */
344     LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, 
345                         ResourceString, 255);
346     strcat(StatusMsg,ResourceString);
347   
348     SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
349
350     /* set all other printer info texts */
351     SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)lpPi->pDriverName);
352     if (lpPi->pLocation != NULL && lpPi->pLocation[0]!='\0')
353         SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pLocation);
354     else                                        
355         SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pPortName);
356     SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)lpPi->pComment);
357 }
358
359 /***********************************************************************
360  *        PRINTSETUP32DLG_ComboBox               [internal]
361  *
362  * Queries the DeviceCapabilities for a list of paper sizes / bin names
363  * and stores these in combobox cmb2 / cmb3.
364  * If there was already an item selected in the listbox,
365  * this item is looked up in the new list and reselected, 
366  * the accompanying ID (for BinNames, this is the dmDefaultSource value)
367  * is returned
368  *
369  * If any entries in the listbox existed, these are deleted
370  *
371  * RETURNS:
372  *   If an entry was selected and also exists in the new list,
373  *   its corresponding ID is returned.
374  * 
375  *   returns zero on not found, error or SelectedName==NULL.
376  *
377  *
378  * BUGS:
379  * * the lookup of a new entry shouldn't be done on stringname,
380  *   but on ID value, as some drivers name the same paper format 
381  *   differently (language differences, added paper size)
382  */
383 short PRINTSETUP32DLG_UpdateComboBox(HWND hDlg,
384                                       int   nIDComboBox,
385                                       char* PrinterName, 
386                                       char* PortName)
387 {
388     int     i;
389     DWORD   NrOfEntries;
390     char*   Names;
391     WORD*   Sizes;
392     HGLOBAL hTempMem;
393     short   returnvalue = 0;
394     char    SelectedName[256];
395     int     NamesSize;
396     int     fwCapability_Names;
397     int     fwCapability_Words;
398     
399     TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
400     
401     /* query the dialog box for the current selected value */
402     GetDlgItemTextA(hDlg, nIDComboBox, SelectedName, 255);
403
404     if (nIDComboBox == cmb2)
405         {
406          NamesSize          = 64;
407          fwCapability_Names = DC_PAPERNAMES;
408          fwCapability_Words = DC_PAPERS;
409         }
410     else
411         {
412          nIDComboBox        = cmb3;
413          NamesSize          = 24;
414          fwCapability_Names = DC_BINNAMES;
415          fwCapability_Words = DC_BINS;
416         }
417     
418     /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the 
419      * paper settings. As Wine doesn't allow VXDs, this results in a crash.
420      */
421     WARN(" if your printer driver uses VXDs, expect a crash now!\n");
422     NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
423                                       fwCapability_Names, NULL, NULL);
424     if (NrOfEntries == 0)
425         {
426          WARN(" no Name Entries found!\n");
427         }
428     hTempMem = GlobalAlloc(GMEM_MOVEABLE, NrOfEntries*NamesSize);
429     if (hTempMem == 0)
430         {
431          ERR(" Not enough memory to store Paper Size Names!\n");
432          return(0);
433         }
434     Names = GlobalLock(hTempMem);
435     NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
436                                       fwCapability_Names, Names, NULL);
437                                       
438     /* reset any current content in the combobox */
439     SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);
440     
441     /* store new content */
442     for (i=0; i<NrOfEntries; i++)
443       {
444        SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
445                         (LPARAM)(&Names[i*NamesSize]) );
446       }
447                         
448     /* select first entry */                        
449     SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0, 
450                         (LPARAM)(&Names[0]) );
451
452     /* lookup SelectedName and select it, if found */
453     if (SelectedName[0] != '\0')
454        {
455         for (i=0; i<NrOfEntries; i++)
456             {
457              if (strcmp(&Names[i*NamesSize], SelectedName)==0)
458                 {
459                  SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0, 
460                                      (LPARAM)(SelectedName));
461                  
462                  /* now, we need the i-th entry from the list of paper sizes */
463                  /* let's recycle the memory */
464                  DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words,
465                                      Names, NULL);
466                  Sizes = (WORD*) Names;
467                  returnvalue = Sizes[i];                 
468                  break; /* quit for loop */
469                 }
470             }
471        }
472                         
473     GlobalUnlock(hTempMem);
474     GlobalFree(hTempMem);
475  return(returnvalue);
476 }
477
478
479
480 /***********************************************************************
481  *           PRINTDLG_WMInitDialog                      [internal]
482  */
483 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
484                                      PRINT_PTRA* PrintStructures)
485 {
486  int               i;
487  LPPRINTDLGA       lppd     = PrintStructures->lpPrintDlg;
488  LPPRINTER_INFO_2A lppi     = PrintStructures->lpPrinterInfo;
489  PDEVMODEA         pDevMode = lppi[PrintStructures->CurrentPrinter].pDevMode; 
490  
491         SetWindowLongA(hDlg, DWL_USER, lParam); 
492         TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
493
494         if (lppd->lStructSize != sizeof(PRINTDLGA))
495         {
496                 FIXME("structure size failure !!!\n");
497 /*              EndDialog (hDlg, 0); 
498                 return FALSE; 
499 */      }
500
501 /* Fill Combobox according to info from PRINTER_INFO2A
502  * structure inside PrintStructures,
503  * select the default printer and generate an
504  * update-message to have the rest of the dialog box updated.
505  */ 
506     for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
507            SendDlgItemMessageA(hDlg, cmb4, CB_ADDSTRING, 0,
508                         (LPARAM)lppi[i].pPrinterName );
509     i=SendDlgItemMessageA(hDlg, cmb4, CB_SELECTSTRING, 
510         (WPARAM) -1,
511         (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
512     SendDlgItemMessageA(hDlg, cmb4, CB_SETCURSEL, 
513         (WPARAM)i, (LPARAM)0);
514     PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
515
516 /* Flag processing to set the according buttons on/off and
517  * Initialise the various values
518  */
519
520     /* Print range (All/Range/Selection) */
521     /* FIXME: I allow more freedom than either Win95 or WinNT,
522      *        which do not agree to what errors should be thrown or not
523      *        in case nToPage or nFromPage is out-of-range.
524      */
525     if (lppd->nMaxPage < lppd->nMinPage)
526         lppd->nMaxPage = lppd->nMinPage;
527     if (lppd->nMinPage == lppd->nMaxPage) 
528         lppd->Flags |= PD_NOPAGENUMS;        
529     if (lppd->nToPage < lppd->nMinPage)
530         lppd->nToPage = lppd->nMinPage;
531     if (lppd->nToPage > lppd->nMaxPage)
532         lppd->nToPage = lppd->nMaxPage;
533     if (lppd->nFromPage < lppd->nMinPage)
534         lppd->nFromPage = lppd->nMinPage;
535     if (lppd->nFromPage > lppd->nMaxPage)
536         lppd->nFromPage = lppd->nMaxPage;
537     SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
538     SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
539     CheckRadioButton(hDlg, rad1, rad3, rad1);           /* default */
540     if (lppd->Flags & PD_NOSELECTION)
541                 EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
542     else
543                 if (lppd->Flags & PD_SELECTION)
544                 CheckRadioButton(hDlg, rad1, rad3, rad2);
545     if (lppd->Flags & PD_NOPAGENUMS)
546        {
547                 EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
548                 EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
549                 EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
550                 EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
551                 EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
552        }
553     else
554        {
555                 if (lppd->Flags & PD_PAGENUMS)
556                 CheckRadioButton(hDlg, rad1, rad3, rad3);
557        }
558         /* "All xxx pages"... */
559     {
560      char        resourcestr[64];
561      char        result[64];
562      LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES, 
563                 resourcestr, 49);
564      sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
565      SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
566     }
567         
568     /* Collate pages 
569      *
570      * FIXME: The ico3 is not displayed for some reason. I don't know why.
571      */
572     if (lppd->Flags & PD_COLLATE)
573        {
574         SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
575                                     (LPARAM)PrintStructures->hCollateIcon);
576             CheckDlgButton(hDlg, chx2, 1);
577        }
578     else
579        {
580             SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
581                                     (LPARAM)PrintStructures->hNoCollateIcon);
582             CheckDlgButton(hDlg, chx2, 0);
583        }
584        
585     if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
586         lppd->Flags & PD_USEDEVMODECOPIES)
587         {
588          /* if printer doesn't support it: no Collate */
589          if (!(pDevMode->dmFields & DM_COLLATE))
590             {
591                 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);    
592                 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);    
593             }
594         }
595         
596     /* nCopies */
597     if (lppd->hDevMode == 0)
598         {
599          SetDlgItemInt(hDlg, edt3, lppd->nCopies, FALSE);
600         }
601     else
602         {
603          SetDlgItemInt(hDlg, edt1, pDevMode->dmCopies, FALSE);
604         }
605     if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
606         lppd->Flags & PD_USEDEVMODECOPIES)
607         {
608          /* if printer doesn't support it: no nCopies */
609          if (!(pDevMode->dmFields & DM_COPIES))
610             {
611                 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);    
612                 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);    
613             }
614         }
615
616     /* print to file */
617         CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
618     if (lppd->Flags & PD_DISABLEPRINTTOFILE)
619                 EnableWindow(GetDlgItem(hDlg, chx1), FALSE);    
620     if (lppd->Flags & PD_HIDEPRINTTOFILE)
621                 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
622
623     /* help button */
624         if ((lppd->Flags & PD_SHOWHELP)==0)
625         {       /* hide if PD_SHOWHELP not specified */
626                  ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);         
627         }
628
629   GlobalUnlock(lppd->hDevMode);
630   return TRUE;
631 }
632
633
634
635
636 /***********************************************************************
637  *           PRINTSETUP32DLG_WMInitDialog                      [internal]
638  */
639 static LRESULT PRINTSETUP32DLG_WMInitDialog(HWND hDlg, WPARAM wParam, 
640                      LPARAM lParam,
641                                      PRINT_PTRA* PrintStructures)
642 {
643  int               i;
644  LPPRINTDLGA       lppd     = PrintStructures->lpPrintDlg;
645  LPPRINTER_INFO_2A lppi     = PrintStructures->lpPrinterInfo;
646  
647         SetWindowLongA(hDlg, DWL_USER, lParam); 
648         TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
649
650         if (lppd->lStructSize != sizeof(PRINTDLGA))
651         {
652                 FIXME("structure size failure !!!\n");
653 /*              EndDialog (hDlg, 0); 
654                 return FALSE; 
655 */      }
656
657 /* Fill Combobox 1 according to info from PRINTER_INFO2A
658  * structure inside PrintStructures,
659  * select the default printer and generate an
660  * update-message to have the rest of the dialog box updated.
661  */ 
662     for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
663            SendDlgItemMessageA(hDlg, cmb1, CB_ADDSTRING, 0,
664                         (LPARAM)lppi[i].pPrinterName );
665     i=SendDlgItemMessageA(hDlg, cmb1, CB_SELECTSTRING, 
666         (WPARAM) -1,
667         (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
668     SendDlgItemMessageA(hDlg, cmb1, CB_SETCURSEL, 
669         (WPARAM)i, (LPARAM)0);
670     PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
671     
672 /* 
673  * fill both ComboBoxes with their info
674  */
675   PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
676                 lppi[PrintStructures->CurrentPrinter].pPrinterName,
677                 lppi[PrintStructures->CurrentPrinter].pPortName);
678   PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
679                 lppi[PrintStructures->CurrentPrinter].pPrinterName,
680                 lppi[PrintStructures->CurrentPrinter].pPortName);
681                 
682 /* 
683  * set the correct radiobutton & icon for print orientation
684  */
685   /* this should be dependent on a incoming DevMode 
686    * (FIXME: not implemented yet) */
687   CheckRadioButton(hDlg, rad1, rad2, rad1);
688   /* also set the correct icon (FIXME: not implemented yet) */
689                 
690   return TRUE;
691 }
692
693
694 /***********************************************************************
695  *             PRINTDLG_CreateDevNames          [internal]
696  *
697  *
698  *   creates a DevNames structure.
699  * RETURNS
700  *   HGLOBAL to DevNames memory object on success or
701  *   zero on faillure
702  */
703 HGLOBAL PRINTDLG_CreateDevNames(
704                     char* DeviceDriverName, 
705                     char* DeviceName, 
706                     char* OutputPort, 
707                     WORD  Flags)
708 {
709     long size;
710     HGLOBAL hDevNames;
711     char*   pDevNamesSpace;
712     char*   pTempPtr;
713     LPDEVNAMES lpDevNames;
714     
715     size = strlen(DeviceDriverName) +1
716             + strlen(DeviceName) + 1
717             + strlen(OutputPort) + 1
718             + sizeof(DEVNAMES);
719             
720     hDevNames = GlobalAlloc(GMEM_MOVEABLE, size*sizeof(char));
721     if (hDevNames != 0)
722     {
723         pDevNamesSpace = GlobalLock(hDevNames);
724         lpDevNames = (LPDEVNAMES) pDevNamesSpace;
725         
726         pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
727         strcpy(pTempPtr, DeviceDriverName);
728         lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;
729         
730         pTempPtr += strlen(DeviceDriverName) + 1;
731         strcpy(pTempPtr, DeviceName);
732         lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
733         
734         pTempPtr += strlen(DeviceName) + 1;
735         strcpy(pTempPtr, OutputPort);
736         lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
737         
738         lpDevNames->wDefault = Flags;
739         
740         GlobalUnlock(hDevNames);
741     }
742     return(hDevNames);
743 }
744             
745     
746            
747     
748 /***********************************************************************
749  *             PRINTDLG_ValidateAndDuplicateSettings          [internal]
750  *
751  *
752  *   updates the PrintDlg structure for returnvalues.
753  *   (yep, the name was chosen a bit stupid...)
754  *
755  *   if hDlg equals zero, only hDevModes and hDevNames are adapted.
756  *      
757  * RETURNS
758  *   FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
759  *   TRUE  if succesful.
760  */
761 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg, 
762                                                   PRINT_PTRA* PrintStructures)
763 {
764  LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
765                                              [PrintStructures->CurrentPrinter]);
766  LPPRINTDLGA       lppd = PrintStructures->lpPrintDlg;
767  PDEVMODEA         pDevMode;
768  
769  if (hDlg!=0)
770  {
771     /* check whether nFromPage and nToPage are within range defined by
772      * nMinPage and nMaxPage
773      */
774     if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED)
775     {
776         WORD nToPage;
777         WORD nFromPage;
778         nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
779         nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
780         if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
781             nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage)
782         {
783             char resourcestr[256];
784             char resultstr[256];
785             LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, 
786                 resourcestr, 255);
787             sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
788             LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE, 
789                 resourcestr, 255);
790             MessageBoxA(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING);
791             return(FALSE);
792         }
793         lppd->nFromPage = nFromPage;
794         lppd->nToPage   = nToPage;
795     }
796      
797     
798     if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED)
799        {
800         lppd->Flags |= PD_PRINTTOFILE;
801         lpPi->pPortName = "FILE:";
802        }
803
804     if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
805        {
806         FIXME("Collate lppd not yet implemented as output\n");
807        }
808  } /* end-of-if(hDlg!=0) */
809
810     /* 
811      * create or modify hDevMode 
812      */     
813     if (lppd->hDevMode == 0)
814        {
815         TRACE(" No hDevMode yet... Need to create my own\n");
816         /* FIXME: possible memory leak? Memory never freed again! */
817         lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, lpPi->pDevMode->dmSize);
818         pDevMode    = GlobalLock(lppd->hDevMode);
819         memcpy(pDevMode, lpPi->pDevMode, lpPi->pDevMode->dmSize);
820        }
821     else
822        {
823         FIXME(" already hDevMode... must adjust it... Not implemented yet\n");
824         pDevMode    = GlobalLock(lppd->hDevMode);
825        }
826               
827     /* If hDevNames already exists, trash it.
828      * But create a new one anyway
829      */
830     if (lppd->hDevNames != 0)
831        {
832         if ( (GlobalFlags(lppd->hDevNames)&0xFF) != 0)
833             ERR(" Tried to free hDevNames, but your application still has a"
834                 " lock on hDevNames. Possible program crash...");
835         GlobalFree(lppd->hDevNames);
836        }
837     /* FIXME: The first entry  of DevNames is fixed to "winspool", 
838      * because I don't know of any printerdriver which doesn't return 
839      * winspool there. But I guess they do exist... 
840      */
841     lppd->hDevNames = PRINTDLG_CreateDevNames("winspool",
842                       lpPi->pDriverName, lpPi->pPortName, 
843                       (PrintStructures->DefaultPrinter ==
844                                 PrintStructures->CurrentPrinter)?1:0);
845
846     /* set PD_Collate and nCopies */
847     if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
848         lppd->Flags & PD_USEDEVMODECOPIES)
849         {
850          /* if one of the above flags was set, the application doesn't
851            * (want to) support multiple copies or collate...
852            */
853          lppd->Flags &= ~PD_COLLATE;
854          lppd->nCopies = 1;
855           /* if the printer driver supports it... store info there
856            * otherwise no collate & multiple copies !
857            */
858          if (pDevMode->dmFields & DM_COLLATE)
859           {
860            pDevMode->dmCollate = 0;
861            if (hDlg!=0)
862              if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
863                    pDevMode->dmCollate = 1;      
864           }
865          if (pDevMode->dmFields & DM_COPIES)
866           {
867            pDevMode->dmCopies = 1;
868            if (hDlg!=0)
869                 pDevMode->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
870               }
871             }
872     else
873         {
874          if (hDlg!=0)
875            {
876                 /* set Collate & nCopies according to dialog */
877             if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
878                lppd->Flags |= PD_COLLATE;
879             else
880                lppd->Flags &= ~PD_COLLATE;
881             lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
882            }
883         else
884            {
885             /* stick to defaults */
886             lppd->Flags &= ~PD_COLLATE;
887             lppd->nCopies = 1;
888            }
889        }
890
891
892     GlobalUnlock(lppd->hDevMode);
893
894  return(TRUE);   
895 }
896
897
898     
899 /***********************************************************************
900  *      PRINTSETUP32DLG_ValidateAndDuplicateSettings          [internal]
901  *
902  *
903  *   updates the PrintDlg structure for returnvalues.
904  *   (yep, the name was chosen a bit stupid...)
905  *
906  *   if hDlg equals zero, only hDevModes and hDevNames are adapted.
907  *      
908  * RETURNS
909  *   FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
910  *   TRUE  if succesful.
911  */
912 static BOOL PRINTSETUP32DLG_ValidateAndDuplicateSettings(HWND hDlg, 
913                                                   PRINT_PTRA* PrintStructures)
914 {
915  LPPRINTDLGA       lppd = PrintStructures->lpPrintDlg;
916  LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
917                                              [PrintStructures->CurrentPrinter]);
918  PDEVMODEA         pDevMode;
919
920    if (PRINTDLG_ValidateAndDuplicateSettings(0, PrintStructures)==FALSE)
921       return(FALSE);
922
923    pDevMode    = GlobalLock(lppd->hDevMode);
924
925    /* set bin type and paper size to DevMode */
926    if (pDevMode->dmFields & DM_PAPERSIZE)
927      {
928       pDevMode->u1.s1.dmPaperSize = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
929                             lppi->pPrinterName,
930                             lppi->pPortName);
931       /* FIXME: should set dmPaperLength and dmPaperWidth also??? */
932      }                      
933    if (pDevMode->dmFields & DM_DEFAULTSOURCE)
934       pDevMode->dmDefaultSource = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
935                             lppi->pPrinterName,
936                             lppi->pPortName);
937  
938    /* set paper orientation to DevMode */
939    if (pDevMode->dmFields & DM_ORIENTATION)
940       {
941        if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED)
942            pDevMode->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
943        else
944            pDevMode->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
945       }
946       
947    GlobalUnlock(lppd->hDevMode);
948    
949  return(TRUE);
950 }
951
952
953
954 /***********************************************************************
955  *                              PRINTDLG_WMCommand               [internal]
956  */
957 static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, 
958                         LPARAM lParam, PRINT_PTRA* PrintStructures)
959 {
960     LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
961     LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
962                                         [PrintStructures->CurrentPrinter]);
963     
964
965     switch (LOWORD(wParam)) 
966     {
967          case IDOK:
968         TRACE(" OK button was hit\n");
969         if (PRINTDLG_ValidateAndDuplicateSettings(hDlg, PrintStructures)!=TRUE)
970                 return(FALSE);
971             DestroyWindow(hDlg);
972             return(TRUE);
973          case IDCANCEL:
974         TRACE(" CANCEL button was hit\n");
975         EndDialog(hDlg, FALSE);
976             return(FALSE);
977      case pshHelp:
978         TRACE(" HELP button was hit\n");
979         SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, 
980                                 (WPARAM) hDlg, (LPARAM) lppd);
981         break;
982      case chx2:                         /* collate pages checkbox */
983         if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
984             SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
985                                     (LPARAM)PrintStructures->hCollateIcon);
986         else
987             SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
988                                     (LPARAM)PrintStructures->hNoCollateIcon);
989         break;        
990      case edt1:                         /* from page nr editbox */
991      case edt2:                         /* to page nr editbox */
992         if (HIWORD(wParam)==EN_CHANGE)
993            {
994             WORD nToPage;
995                 WORD nFromPage;
996                 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
997                 nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
998             if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
999                             CheckRadioButton(hDlg, rad1, rad3, rad3);
1000     }
1001         break;
1002      case psh2:                         /* Properties button */
1003         {
1004 /*         HANDLE hPrinter;
1005          char   PrinterName[256];
1006          GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1007          if (OpenPrinterA(PrinterName, &hPrinter, NULL))
1008             {
1009              PrinterProperties(hDlg, hPrinter);
1010              ClosePrinter(hPrinter);
1011             }
1012          else
1013             WARN(" Call to OpenPrinter did not succeed!\n");
1014          break;
1015 */       MessageBoxA(hDlg, "Not implemented yet!", "PRINT", MB_OK);
1016         }
1017      case cmb4:                         /* Printer combobox */
1018         if (HIWORD(wParam)==CBN_SELCHANGE)
1019            {
1020             int i;
1021                 char   PrinterName[256];
1022
1023             /* look the newly selected Printer up in 
1024              * our array Printer_Info2As
1025              */
1026                 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1027             for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1028                    {
1029                 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName, 
1030                            PrinterName)==0)
1031                      break;
1032                }
1033             PrintStructures->CurrentPrinter = i;   
1034             PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1035             lppi = &(PrintStructures->lpPrinterInfo
1036                                        [PrintStructures->CurrentPrinter]);
1037             if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
1038                 lppd->Flags & PD_USEDEVMODECOPIES)
1039                 {
1040                  /* if printer doesn't support it: no nCopies */
1041                  if (!(lppi->pDevMode->dmFields & DM_COPIES))
1042                     {
1043                         EnableWindow(GetDlgItem(hDlg, edt3), FALSE);    
1044                         EnableWindow(GetDlgItem(hDlg, stc5), FALSE);    
1045                     }
1046                  else
1047                     {
1048                         EnableWindow(GetDlgItem(hDlg, edt3), TRUE);    
1049                         EnableWindow(GetDlgItem(hDlg, stc5), TRUE);    
1050                     }
1051                  /* if printer doesn't support it: no Collate */
1052                  if (!(lppi->pDevMode->dmFields & DM_COPIES))
1053                     {
1054                         EnableWindow(GetDlgItem(hDlg, ico3), FALSE);    
1055                         EnableWindow(GetDlgItem(hDlg, chx2), FALSE);    
1056                     }
1057                  else
1058                     {
1059                         EnableWindow(GetDlgItem(hDlg, ico3), TRUE);
1060                         EnableWindow(GetDlgItem(hDlg, chx2), TRUE);
1061                     }
1062                 }
1063
1064            }
1065         break;
1066     }
1067     return FALSE;
1068 }    
1069
1070
1071 /***********************************************************************
1072  *                  PRINTSETUP32DLG_WMCommand               [internal]
1073  */
1074 static LRESULT PRINTSETUP32DLG_WMCommand(HWND hDlg, WPARAM wParam, 
1075                         LPARAM lParam, PRINT_PTRA* PrintStructures)
1076 {
1077     LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
1078     LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
1079                                         [PrintStructures->CurrentPrinter]);
1080     
1081
1082     switch (LOWORD(wParam)) 
1083     {
1084      case IDOK:
1085         TRACE(" OK button was hit\n");
1086         if (PRINTSETUP32DLG_ValidateAndDuplicateSettings(hDlg, PrintStructures) != TRUE)
1087                 return(FALSE);
1088         DestroyWindow(hDlg);
1089         return(TRUE);
1090      case IDCANCEL:
1091         TRACE(" CANCEL button was hit\n");
1092         EndDialog(hDlg, FALSE);
1093         return(FALSE);
1094      case pshHelp:
1095         TRACE(" HELP button was hit\n");
1096         SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, 
1097                                 (WPARAM) hDlg, (LPARAM) lppd);
1098         break;
1099      case psh2:                         /* Properties button */
1100        MessageBoxA(hDlg, "Not implemented yet!", "PRINT SETUP", MB_OK);
1101        break;
1102      case cmb1:                         /* Printer combobox */
1103         if (HIWORD(wParam)==CBN_SELCHANGE)
1104            {
1105             int i;
1106                 char   Name[256];
1107
1108             /* look the newly selected Printer up in 
1109              * our array Printer_Info2As
1110              */
1111                 GetDlgItemTextA(hDlg, cmb1, Name, 255);
1112             for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1113                    {
1114                 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName, 
1115                            Name)==0)
1116                      break;
1117                }
1118             PrintStructures->CurrentPrinter = i;   
1119             PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1120             lppi = &(PrintStructures->
1121                         lpPrinterInfo[PrintStructures->CurrentPrinter]);
1122                     
1123             /* Update both ComboBoxes to the items available for the new
1124              * printer. Keep the same entry selected, if possible
1125              */
1126             PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2, lppi->pPrinterName,
1127                                              lppi->pPortName);
1128             PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3, lppi->pPrinterName,
1129                                              lppi->pPortName);
1130            }
1131         break;
1132     }
1133     return FALSE;
1134 }    
1135
1136
1137 /***********************************************************************
1138  *           PrintDlgProcA                      [internal]
1139  */
1140 LRESULT WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1141                                     LPARAM lParam)
1142 {
1143   PRINT_PTRA* PrintStructures;
1144   LRESULT res=FALSE;
1145   if (uMsg!=WM_INITDIALOG)
1146   {
1147    PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);   
1148    if (!PrintStructures)
1149     return FALSE;
1150 }
1151   else
1152   {
1153     PrintStructures=(PRINT_PTRA*) lParam;
1154     if (!PRINTDLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures)) 
1155     {
1156       TRACE("PRINTDLG_WMInitDialog returned FALSE\n");
1157       return FALSE;
1158     }  
1159   }
1160   switch (uMsg)
1161   {
1162         case WM_COMMAND:
1163        return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1164     case WM_DESTROY:
1165             return FALSE;
1166   }
1167   
1168  return res;
1169 }
1170
1171
1172
1173
1174 /***********************************************************************
1175  *           PrintDlgProc16   (COMMDLG.21)
1176  */
1177 LRESULT WINAPI PrintDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1178                             LPARAM lParam)
1179 {
1180   switch (wMsg)
1181     {
1182     case WM_INITDIALOG:
1183       TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1184       ShowWindow16(hWnd, SW_SHOWNORMAL);
1185       return (TRUE);
1186     case WM_COMMAND:
1187       switch (wParam)
1188         {
1189         case IDOK:
1190           EndDialog(hWnd, TRUE);
1191           return(TRUE);
1192         case IDCANCEL:
1193           EndDialog(hWnd, FALSE);
1194           return(TRUE);
1195         }
1196       return(FALSE);
1197     }
1198   return FALSE;
1199 }
1200
1201
1202 /***********************************************************************
1203  *           PrintSetupDlgProc   (COMMDLG.22)
1204  */
1205 LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1206                                  LPARAM lParam)
1207 {
1208   switch (wMsg)
1209     {
1210     case WM_INITDIALOG:
1211       TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1212       ShowWindow16(hWnd, SW_SHOWNORMAL);
1213       return (TRUE);
1214     case WM_COMMAND:
1215       switch (wParam) {
1216       case IDOK:
1217         EndDialog(hWnd, TRUE);
1218         return(TRUE);
1219       case IDCANCEL:
1220         EndDialog(hWnd, FALSE);
1221         return(TRUE);
1222       }
1223       return(FALSE);
1224     }
1225   return FALSE;
1226 }
1227
1228
1229 /***********************************************************************
1230  *           PrintSetupDlgProcA                 [???]
1231  *
1232  *   FIXME:
1233  *   note: I don't know whether this function actually is allowed
1234  *         to exist (i.e. is exported/overrideable from the DLL)
1235  *         For now, this function is local only.
1236  *         If necessary, this call can be merged with PrintDlgProcA,
1237  *         as it is very similar.
1238  */
1239 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1240                                     LPARAM lParam)
1241 {
1242   PRINT_PTRA* PrintStructures;
1243   LRESULT res=FALSE;
1244   if (uMsg!=WM_INITDIALOG)
1245   {
1246    PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);   
1247    if (!PrintStructures)
1248     return FALSE;
1249 }
1250   else
1251   {
1252     PrintStructures=(PRINT_PTRA*) lParam;
1253     if (!PRINTSETUP32DLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures)) 
1254     {
1255       TRACE("PRINTSETUP32DLG_WMInitDialog returned FALSE\n");
1256       return FALSE;
1257     }  
1258   }
1259   switch (uMsg)
1260   {
1261         case WM_COMMAND:
1262        return PRINTSETUP32DLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1263     case WM_DESTROY:
1264             return FALSE;
1265   }
1266   
1267  return res;
1268 }
1269
1270
1271
1272
1273
1274 /***********************************************************************
1275  *            PageSetupDlgA  (COMDLG32.15)
1276  */
1277 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
1278         FIXME("(%p), stub!\n",setupdlg);
1279         return FALSE;
1280 }