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