2 * COMMDLG - Print Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
16 #include "wine/winbase16.h"
17 #include "wine/winuser16.h"
23 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(commdlg
);
34 /* This PRINTDLGA internal structure stores
35 * pointers to several throughout useful structures.
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
;
46 HICON hCollateIcon
; /* PrintDlg only */
47 HICON hNoCollateIcon
; /* PrintDlg only */
48 HICON hPortraitIcon
; /* PrintSetupDlg only */
49 HICON hLandscapeIcon
; /* PrintSetupDlg only */
54 static BOOL
PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg
,
55 PRINT_PTRA
* PrintStructures
);
57 LRESULT WINAPI
PrintSetupDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
61 /***********************************************************************
62 * PrintDlg16 (COMMDLG.20)
64 * Displays the the PRINT dialog box, which enables the user to specify
65 * specific properties of the print job.
68 * nonzero if the user pressed the OK button
69 * zero if the user cancelled the window or an error occurred
72 * * calls up to the 32-bit versions of the Dialogs, which look different
73 * * Customizing is *not* implemented.
75 BOOL16 WINAPI
PrintDlg16( LPPRINTDLG16 lpPrint
)
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;*/
97 if(lpPrint
->lpfnSetupHook
) {
98 FIXME("Need to allocate thunk\n");
99 /* Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
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
;
106 ret
= PrintDlgA(&Print32
);
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
;
120 /***********************************************************************
121 * PrintDlgA (COMDLG32.17)
123 * Displays the the PRINT dialog box, which enables the user to specify
124 * specific properties of the print job.
127 * nonzero if the user pressed the OK button
128 * zero if the user cancelled the window or an error occurred
132 * * The Collate Icons do not display, even though they are in the code.
133 * * The Properties Button(s) should call DocumentPropertiesA().
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.
140 BOOL WINAPI
PrintDlgA(
141 LPPRINTDLGA lppd
/* ptr to PRINTDLG32 struct */
144 /* My implementing strategy:
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
150 * step 4: implement all other specs
151 * step 5: allow customisation of the dialog box
153 * current implementation is in step 4.
159 HANDLE hResInfo
, hDlgTmpl
;
160 HINSTANCE hInst
= GetWindowLongA( lppd
->hwndOwner
, GWL_HINSTANCE
);
161 DWORD EnumBytesNeeded
;
162 DWORD CopyOfEnumBytesNeeded
;
163 PRINT_PTRA PrintStructures
;
165 TRACE("(lppd: %p)\n", lppd
);
166 PrintStructures
.lpPrintDlg
= lppd
;
168 /* load Dialog resources,
169 * depending on Flags indicates Print32 or Print32_setup dialog
171 if (lppd
->Flags
& PD_PRINTSETUP
)
172 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP", RT_DIALOGA
);
174 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32", RT_DIALOGA
);
177 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
181 if (!(hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
)) ||
182 !(ptr
= LockResource( hDlgTmpl
)))
184 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
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)
195 ERR("no icon in resourcefile???");
196 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
200 /* load Paper Orientation ICON */
201 /* FIXME: not implemented yet */
204 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
205 * must be registered and the Help button must be shown.
207 if (lppd
->Flags
& PD_SHOWHELP
)
209 if((PrintStructures
.HelpMessageID
=
210 RegisterWindowMessageA(HELPMSGSTRING
)) == 0)
212 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
217 PrintStructures
.HelpMessageID
=0;
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
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
);
232 /* Find the default printer.
233 * If not: display a warning message (unless PD_NOWARNING specified)
234 * and return PDERR_NODEFAULTPRN
236 /* FIXME: not implemented yet!!! */
237 if (!PrintStructures
.NrOfPrinterInfoEntries
)
239 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
242 PrintStructures
.CurrentPrinter
=0;
243 PrintStructures
.DefaultPrinter
=0;
245 /* FIXME: Currently Unimplemented */
246 if (lppd
->Flags
& PD_NOWARNING
)
248 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE
);
249 WARN(": PD_NOWARNING Flag is not yet implemented.\n");
253 * FIXME : Should respond to TEMPLATE and HOOK flags here
254 * For now, only the standard dialog works.
256 if (lppd
->Flags
& (PD_ENABLEPRINTHOOK
| PD_ENABLEPRINTTEMPLATE
|
257 PD_ENABLEPRINTTEMPLATEHANDLE
| PD_ENABLESETUPHOOK
|
258 PD_ENABLESETUPTEMPLATE
|PD_ENABLESETUPTEMPLATEHANDLE
))
259 FIXME(": unimplemented flag (ignored)\n");
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 .
266 * According to MSDN, it is required that hDevMode and hDevNames equal
267 * zero if this flag is set.
269 if (lppd
->Flags
& PD_RETURNDEFAULT
)
271 TRACE(" PD_RETURNDEFAULT: was requested to return printer info only.\n");
272 if (lppd
->hDevMode
!=0 || lppd
->hDevNames
!=0)
274 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE
);
277 return(PRINTDLG_ValidateAndDuplicateSettings(0, &PrintStructures
));
280 /* and create & process the dialog
282 if (lppd
->Flags
& PD_PRINTSETUP
)
284 hwndDialog
= DIALOG_CreateIndirect(hInst
, ptr
, TRUE
, lppd
->hwndOwner
,
285 (DLGPROC16
)PrintSetupDlgProcA
, (LPARAM
)&PrintStructures
, WIN_PROC_32A
);
289 hwndDialog
= DIALOG_CreateIndirect(hInst
, ptr
, TRUE
, lppd
->hwndOwner
,
290 (DLGPROC16
)PrintDlgProcA
, (LPARAM
)&PrintStructures
, WIN_PROC_32A
);
293 bRet
= DIALOG_DoDialogBox(hwndDialog
, lppd
->hwndOwner
);
295 /* free memory & resources
297 free(PrintStructures
.lpPrinterInfo
);
298 DeleteObject(PrintStructures
.hCollateIcon
);
299 DeleteObject(PrintStructures
.hNoCollateIcon
);
300 /* FIXME: don't forget to delete the paper orientation icons here! */
302 TRACE(" exit! (%d)", bRet
);
308 /***********************************************************************
309 * PrintDlgW (COMDLG32.18)
311 BOOL WINAPI
PrintDlgW( LPPRINTDLGW printdlg
)
313 FIXME("A really empty stub\n" );
318 /***********************************************************************
319 * PRINTDLG_UpdatePrinterInfoTexts [internal]
321 static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg
, PRINT_PTRA
* PrintStructures
)
324 char ResourceString
[256];
326 LPPRINTER_INFO_2A lpPi
= &(PrintStructures
->lpPrinterInfo
327 [PrintStructures
->CurrentPrinter
]);
331 /* FIXME: if default printer, add this first */
333 /* add all status messages */
334 for (i
=0; i
< 25; i
++)
336 if (lpPi
->Status
& (1<<i
))
338 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
339 ResourceString
, 255);
340 strcat(StatusMsg
,ResourceString
);
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
);
350 SendDlgItemMessageA(hDlg
, stc12
, WM_SETTEXT
, 0, (LPARAM
)StatusMsg
);
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
);
357 SendDlgItemMessageA(hDlg
, stc14
, WM_SETTEXT
, 0,(LPARAM
)lpPi
->pPortName
);
358 SendDlgItemMessageA(hDlg
, stc13
, WM_SETTEXT
, 0, (LPARAM
)lpPi
->pComment
);
361 /***********************************************************************
362 * PRINTSETUP32DLG_ComboBox [internal]
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)
371 * If any entries in the listbox existed, these are deleted
374 * If an entry was selected and also exists in the new list,
375 * its corresponding ID is returned.
377 * returns zero on not found, error or SelectedName==NULL.
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)
385 static short PRINTSETUP32DLG_UpdateComboBox(HWND hDlg
,
395 short returnvalue
= 0;
396 char SelectedName
[256];
398 int fwCapability_Names
;
399 int fwCapability_Words
;
401 TRACE(" Printer: %s, ComboID: %d\n",PrinterName
,nIDComboBox
);
403 /* query the dialog box for the current selected value */
404 GetDlgItemTextA(hDlg
, nIDComboBox
, SelectedName
, 255);
406 if (nIDComboBox
== cmb2
)
409 fwCapability_Names
= DC_PAPERNAMES
;
410 fwCapability_Words
= DC_PAPERS
;
416 fwCapability_Names
= DC_BINNAMES
;
417 fwCapability_Words
= DC_BINS
;
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.
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)
428 WARN(" no Name Entries found!\n");
430 hTempMem
= GlobalAlloc(GMEM_MOVEABLE
, NrOfEntries
*NamesSize
);
433 ERR(" Not enough memory to store Paper Size Names!\n");
436 Names
= GlobalLock(hTempMem
);
437 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
438 fwCapability_Names
, Names
, NULL
);
440 /* reset any current content in the combobox */
441 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
443 /* store new content */
444 for (i
=0; i
<NrOfEntries
; i
++)
446 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
447 (LPARAM
)(&Names
[i
*NamesSize
]) );
450 /* select first entry */
451 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SELECTSTRING
, 0,
452 (LPARAM
)(&Names
[0]) );
454 /* lookup SelectedName and select it, if found */
455 if (SelectedName
[0] != '\0')
457 for (i
=0; i
<NrOfEntries
; i
++)
459 if (strcmp(&Names
[i
*NamesSize
], SelectedName
)==0)
461 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SELECTSTRING
, 0,
462 (LPARAM
)(SelectedName
));
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
,
468 Sizes
= (WORD
*) Names
;
469 returnvalue
= Sizes
[i
];
470 break; /* quit for loop */
475 GlobalUnlock(hTempMem
);
476 GlobalFree(hTempMem
);
482 /***********************************************************************
483 * PRINTDLG_WMInitDialog [internal]
485 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
, LPARAM lParam
,
486 PRINT_PTRA
* PrintStructures
)
489 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
490 LPPRINTER_INFO_2A lppi
= PrintStructures
->lpPrinterInfo
;
491 PDEVMODEA pDevMode
= lppi
[PrintStructures
->CurrentPrinter
].pDevMode
;
493 SetWindowLongA(hDlg
, DWL_USER
, lParam
);
494 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
496 if (lppd
->lStructSize
!= sizeof(PRINTDLGA
))
498 FIXME("structure size failure !!!\n");
499 /* EndDialog (hDlg, 0);
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.
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
,
513 (LPARAM
) lppi
[PrintStructures
->CurrentPrinter
].pPrinterName
);
514 SendDlgItemMessageA(hDlg
, cmb4
, CB_SETCURSEL
,
515 (WPARAM
)i
, (LPARAM
)0);
516 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
518 /* Flag processing to set the according buttons on/off and
519 * Initialise the various values
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.
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
);
545 if (lppd
->Flags
& PD_SELECTION
)
546 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
547 if (lppd
->Flags
& PD_NOPAGENUMS
)
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
);
557 if (lppd
->Flags
& PD_PAGENUMS
)
558 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
560 /* "All xxx pages"... */
562 char resourcestr
[64];
564 LoadStringA(COMDLG32_hInstance
, PD32_PRINT_ALL_X_PAGES
,
566 sprintf(result
,resourcestr
,lppd
->nMaxPage
- lppd
->nMinPage
+ 1);
567 SendDlgItemMessageA(hDlg
, rad1
, WM_SETTEXT
, 0, (LPARAM
) result
);
572 * FIXME: The ico3 is not displayed for some reason. I don't know why.
574 if (lppd
->Flags
& PD_COLLATE
)
576 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
577 (LPARAM
)PrintStructures
->hCollateIcon
);
578 CheckDlgButton(hDlg
, chx2
, 1);
582 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
583 (LPARAM
)PrintStructures
->hNoCollateIcon
);
584 CheckDlgButton(hDlg
, chx2
, 0);
587 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
||
588 lppd
->Flags
& PD_USEDEVMODECOPIES
)
590 /* if printer doesn't support it: no Collate */
591 if (!(pDevMode
->dmFields
& DM_COLLATE
))
593 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
594 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
599 if (lppd
->hDevMode
== 0)
601 SetDlgItemInt(hDlg
, edt3
, lppd
->nCopies
, FALSE
);
605 SetDlgItemInt(hDlg
, edt1
, pDevMode
->dmCopies
, FALSE
);
607 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
||
608 lppd
->Flags
& PD_USEDEVMODECOPIES
)
610 /* if printer doesn't support it: no nCopies */
611 if (!(pDevMode
->dmFields
& DM_COPIES
))
613 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
614 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
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
);
626 if ((lppd
->Flags
& PD_SHOWHELP
)==0)
627 { /* hide if PD_SHOWHELP not specified */
628 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
631 GlobalUnlock(lppd
->hDevMode
);
638 /***********************************************************************
639 * PRINTSETUP32DLG_WMInitDialog [internal]
641 static LRESULT
PRINTSETUP32DLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
643 PRINT_PTRA
* PrintStructures
)
646 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
647 LPPRINTER_INFO_2A lppi
= PrintStructures
->lpPrinterInfo
;
649 SetWindowLongA(hDlg
, DWL_USER
, lParam
);
650 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
652 if (lppd
->lStructSize
!= sizeof(PRINTDLGA
))
654 FIXME("structure size failure !!!\n");
655 /* EndDialog (hDlg, 0);
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.
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
,
669 (LPARAM
) lppi
[PrintStructures
->CurrentPrinter
].pPrinterName
);
670 SendDlgItemMessageA(hDlg
, cmb1
, CB_SETCURSEL
,
671 (WPARAM
)i
, (LPARAM
)0);
672 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
675 * fill both ComboBoxes with their info
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
);
685 * set the correct radiobutton & icon for print orientation
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) */
696 /***********************************************************************
697 * PRINTDLG_CreateDevNames [internal]
700 * creates a DevNames structure.
702 * HGLOBAL to DevNames memory object on success or
705 static HGLOBAL
PRINTDLG_CreateDevNames(
706 char* DeviceDriverName
,
713 char* pDevNamesSpace
;
715 LPDEVNAMES lpDevNames
;
717 size
= strlen(DeviceDriverName
) +1
718 + strlen(DeviceName
) + 1
719 + strlen(OutputPort
) + 1
722 hDevNames
= GlobalAlloc(GMEM_MOVEABLE
, size
*sizeof(char));
725 pDevNamesSpace
= GlobalLock(hDevNames
);
726 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
728 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
729 strcpy(pTempPtr
, DeviceDriverName
);
730 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
732 pTempPtr
+= strlen(DeviceDriverName
) + 1;
733 strcpy(pTempPtr
, DeviceName
);
734 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
736 pTempPtr
+= strlen(DeviceName
) + 1;
737 strcpy(pTempPtr
, OutputPort
);
738 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
740 lpDevNames
->wDefault
= Flags
;
742 GlobalUnlock(hDevNames
);
750 /***********************************************************************
751 * PRINTDLG_ValidateAndDuplicateSettings [internal]
754 * updates the PrintDlg structure for returnvalues.
755 * (yep, the name was chosen a bit stupid...)
757 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
760 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
763 static BOOL
PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg
,
764 PRINT_PTRA
* PrintStructures
)
766 LPPRINTER_INFO_2A lpPi
= &(PrintStructures
->lpPrinterInfo
767 [PrintStructures
->CurrentPrinter
]);
768 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
773 /* check whether nFromPage and nToPage are within range defined by
774 * nMinPage and nMaxPage
776 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
)
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
)
785 char resourcestr
[256];
787 LoadStringA(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
789 sprintf(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
790 LoadStringA(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
792 MessageBoxA(hDlg
, resultstr
, resourcestr
, MB_OK
| MB_ICONWARNING
);
795 lppd
->nFromPage
= nFromPage
;
796 lppd
->nToPage
= nToPage
;
800 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
)
802 lppd
->Flags
|= PD_PRINTTOFILE
;
803 lpPi
->pPortName
= "FILE:";
806 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
808 FIXME("Collate lppd not yet implemented as output\n");
810 } /* end-of-if(hDlg!=0) */
813 * create or modify hDevMode
815 if (lppd
->hDevMode
== 0)
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
);
825 FIXME(" already hDevMode... must adjust it... Not implemented yet\n");
826 pDevMode
= GlobalLock(lppd
->hDevMode
);
829 /* If hDevNames already exists, trash it.
830 * But create a new one anyway
832 if (lppd
->hDevNames
!= 0)
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
);
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...
843 lppd
->hDevNames
= PRINTDLG_CreateDevNames("winspool",
844 lpPi
->pDriverName
, lpPi
->pPortName
,
845 (PrintStructures
->DefaultPrinter
==
846 PrintStructures
->CurrentPrinter
)?1:0);
848 /* set PD_Collate and nCopies */
849 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
||
850 lppd
->Flags
& PD_USEDEVMODECOPIES
)
852 /* if one of the above flags was set, the application doesn't
853 * (want to) support multiple copies or collate...
855 lppd
->Flags
&= ~PD_COLLATE
;
857 /* if the printer driver supports it... store info there
858 * otherwise no collate & multiple copies !
860 if (pDevMode
->dmFields
& DM_COLLATE
)
862 pDevMode
->dmCollate
= 0;
864 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
865 pDevMode
->dmCollate
= 1;
867 if (pDevMode
->dmFields
& DM_COPIES
)
869 pDevMode
->dmCopies
= 1;
871 pDevMode
->dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
878 /* set Collate & nCopies according to dialog */
879 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
880 lppd
->Flags
|= PD_COLLATE
;
882 lppd
->Flags
&= ~PD_COLLATE
;
883 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
887 /* stick to defaults */
888 lppd
->Flags
&= ~PD_COLLATE
;
894 if (lppd
->Flags
& PD_RETURNDC
){
895 lppd
->hDC
= CreateDCA(NULL
, lpPi
->pPrinterName
, NULL
, NULL
);
899 GlobalUnlock(lppd
->hDevMode
);
906 /***********************************************************************
907 * PRINTSETUP32DLG_ValidateAndDuplicateSettings [internal]
910 * updates the PrintDlg structure for returnvalues.
911 * (yep, the name was chosen a bit stupid...)
913 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
916 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
919 static BOOL
PRINTSETUP32DLG_ValidateAndDuplicateSettings(HWND hDlg
,
920 PRINT_PTRA
* PrintStructures
)
922 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
923 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
924 [PrintStructures
->CurrentPrinter
]);
927 if (PRINTDLG_ValidateAndDuplicateSettings(0, PrintStructures
)==FALSE
)
930 pDevMode
= GlobalLock(lppd
->hDevMode
);
932 /* set bin type and paper size to DevMode */
933 if (pDevMode
->dmFields
& DM_PAPERSIZE
)
935 pDevMode
->u1
.s1
.dmPaperSize
= PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb2
,
938 /* FIXME: should set dmPaperLength and dmPaperWidth also??? */
940 if (pDevMode
->dmFields
& DM_DEFAULTSOURCE
)
941 pDevMode
->dmDefaultSource
= PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb3
,
945 /* set paper orientation to DevMode */
946 if (pDevMode
->dmFields
& DM_ORIENTATION
)
948 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
)
949 pDevMode
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
951 pDevMode
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
954 GlobalUnlock(lppd
->hDevMode
);
961 /***********************************************************************
962 * PRINTDLG_WMCommand [internal]
964 static LRESULT
PRINTDLG_WMCommand(HWND hDlg
, WPARAM wParam
,
965 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
967 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
968 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
969 [PrintStructures
->CurrentPrinter
]);
972 switch (LOWORD(wParam
))
975 TRACE(" OK button was hit\n");
976 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg
, PrintStructures
)!=TRUE
)
981 TRACE(" CANCEL button was hit\n");
982 EndDialog(hDlg
, FALSE
);
985 TRACE(" HELP button was hit\n");
986 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
987 (WPARAM
) hDlg
, (LPARAM
) lppd
);
989 case chx2
: /* collate pages checkbox */
990 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
991 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
992 (LPARAM
)PrintStructures
->hCollateIcon
);
994 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
995 (LPARAM
)PrintStructures
->hNoCollateIcon
);
997 case edt1
: /* from page nr editbox */
998 case edt2
: /* to page nr editbox */
999 if (HIWORD(wParam
)==EN_CHANGE
)
1003 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1004 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1005 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1006 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1009 case psh2
: /* Properties button */
1012 char PrinterName[256];
1013 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1014 if (OpenPrinterA(PrinterName, &hPrinter, NULL))
1016 PrinterProperties(hDlg, hPrinter);
1017 ClosePrinter(hPrinter);
1020 WARN(" Call to OpenPrinter did not succeed!\n");
1022 */ MessageBoxA(hDlg
, "Not implemented yet!", "PRINT", MB_OK
);
1024 case cmb4
: /* Printer combobox */
1025 if (HIWORD(wParam
)==CBN_SELCHANGE
)
1028 char PrinterName
[256];
1030 /* look the newly selected Printer up in
1031 * our array Printer_Info2As
1033 GetDlgItemTextA(hDlg
, cmb4
, PrinterName
, 255);
1034 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
1036 if (strcmp(PrintStructures
->lpPrinterInfo
[i
].pPrinterName
,
1040 PrintStructures
->CurrentPrinter
= i
;
1041 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
1042 lppi
= &(PrintStructures
->lpPrinterInfo
1043 [PrintStructures
->CurrentPrinter
]);
1044 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
||
1045 lppd
->Flags
& PD_USEDEVMODECOPIES
)
1047 /* if printer doesn't support it: no nCopies */
1048 if (!(lppi
->pDevMode
->dmFields
& DM_COPIES
))
1050 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1051 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1055 EnableWindow(GetDlgItem(hDlg
, edt3
), TRUE
);
1056 EnableWindow(GetDlgItem(hDlg
, stc5
), TRUE
);
1058 /* if printer doesn't support it: no Collate */
1059 if (!(lppi
->pDevMode
->dmFields
& DM_COPIES
))
1061 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1062 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1066 EnableWindow(GetDlgItem(hDlg
, ico3
), TRUE
);
1067 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1078 /***********************************************************************
1079 * PRINTSETUP32DLG_WMCommand [internal]
1081 static LRESULT
PRINTSETUP32DLG_WMCommand(HWND hDlg
, WPARAM wParam
,
1082 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1084 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1085 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
1086 [PrintStructures
->CurrentPrinter
]);
1089 switch (LOWORD(wParam
))
1092 TRACE(" OK button was hit\n");
1093 if (PRINTSETUP32DLG_ValidateAndDuplicateSettings(hDlg
, PrintStructures
) != TRUE
)
1095 DestroyWindow(hDlg
);
1098 TRACE(" CANCEL button was hit\n");
1099 EndDialog(hDlg
, FALSE
);
1102 TRACE(" HELP button was hit\n");
1103 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1104 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1106 case psh2
: /* Properties button */
1107 MessageBoxA(hDlg
, "Not implemented yet!", "PRINT SETUP", MB_OK
);
1109 case cmb1
: /* Printer combobox */
1110 if (HIWORD(wParam
)==CBN_SELCHANGE
)
1115 /* look the newly selected Printer up in
1116 * our array Printer_Info2As
1118 GetDlgItemTextA(hDlg
, cmb1
, Name
, 255);
1119 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
1121 if (strcmp(PrintStructures
->lpPrinterInfo
[i
].pPrinterName
,
1125 PrintStructures
->CurrentPrinter
= i
;
1126 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
1127 lppi
= &(PrintStructures
->
1128 lpPrinterInfo
[PrintStructures
->CurrentPrinter
]);
1130 /* Update both ComboBoxes to the items available for the new
1131 * printer. Keep the same entry selected, if possible
1133 PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb2
, lppi
->pPrinterName
,
1135 PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb3
, lppi
->pPrinterName
,
1144 /***********************************************************************
1145 * PrintDlgProcA [internal]
1147 LRESULT WINAPI
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1150 PRINT_PTRA
* PrintStructures
;
1152 if (uMsg
!=WM_INITDIALOG
)
1154 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
1155 if (!PrintStructures
)
1160 PrintStructures
=(PRINT_PTRA
*) lParam
;
1161 if (!PRINTDLG_WMInitDialog(hDlg
, wParam
, lParam
, PrintStructures
))
1163 TRACE("PRINTDLG_WMInitDialog returned FALSE\n");
1170 return PRINTDLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
1181 /***********************************************************************
1182 * PrintDlgProc16 (COMMDLG.21)
1184 LRESULT WINAPI
PrintDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
1190 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
1191 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
1197 EndDialog(hWnd
, TRUE
);
1200 EndDialog(hWnd
, FALSE
);
1209 /***********************************************************************
1210 * PrintSetupDlgProc (COMMDLG.22)
1212 LRESULT WINAPI
PrintSetupDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
1218 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
1219 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
1224 EndDialog(hWnd
, TRUE
);
1227 EndDialog(hWnd
, FALSE
);
1236 /***********************************************************************
1237 * PrintSetupDlgProcA [???]
1240 * note: I don't know whether this function actually is allowed
1241 * to exist (i.e. is exported/overrideable from the DLL)
1242 * For now, this function is local only.
1243 * If necessary, this call can be merged with PrintDlgProcA,
1244 * as it is very similar.
1246 LRESULT WINAPI
PrintSetupDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1249 PRINT_PTRA
* PrintStructures
;
1251 if (uMsg
!=WM_INITDIALOG
)
1253 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
1254 if (!PrintStructures
)
1259 PrintStructures
=(PRINT_PTRA
*) lParam
;
1260 if (!PRINTSETUP32DLG_WMInitDialog(hDlg
, wParam
, lParam
, PrintStructures
))
1262 TRACE("PRINTSETUP32DLG_WMInitDialog returned FALSE\n");
1269 return PRINTSETUP32DLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
1281 /***********************************************************************
1282 * PageSetupDlgA (COMDLG32.15)
1284 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
1285 FIXME("(%p), stub!\n",setupdlg
);