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 * PrintDlg32W (COMDLG32.18)
311 BOOL WINAPI
PrintDlgW( LPPRINTDLGW printdlg
)
313 FIXME("A really empty stub\n" );
318 /***********************************************************************
319 * PRINTDLG_UpdatePrinterInfoTexts [internal]
321 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 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 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 GlobalUnlock(lppd
->hDevMode
);
901 /***********************************************************************
902 * PRINTSETUP32DLG_ValidateAndDuplicateSettings [internal]
905 * updates the PrintDlg structure for returnvalues.
906 * (yep, the name was chosen a bit stupid...)
908 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
911 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
914 static BOOL
PRINTSETUP32DLG_ValidateAndDuplicateSettings(HWND hDlg
,
915 PRINT_PTRA
* PrintStructures
)
917 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
918 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
919 [PrintStructures
->CurrentPrinter
]);
922 if (PRINTDLG_ValidateAndDuplicateSettings(0, PrintStructures
)==FALSE
)
925 pDevMode
= GlobalLock(lppd
->hDevMode
);
927 /* set bin type and paper size to DevMode */
928 if (pDevMode
->dmFields
& DM_PAPERSIZE
)
930 pDevMode
->u1
.s1
.dmPaperSize
= PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb2
,
933 /* FIXME: should set dmPaperLength and dmPaperWidth also??? */
935 if (pDevMode
->dmFields
& DM_DEFAULTSOURCE
)
936 pDevMode
->dmDefaultSource
= PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb3
,
940 /* set paper orientation to DevMode */
941 if (pDevMode
->dmFields
& DM_ORIENTATION
)
943 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
)
944 pDevMode
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
946 pDevMode
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
949 GlobalUnlock(lppd
->hDevMode
);
956 /***********************************************************************
957 * PRINTDLG_WMCommand [internal]
959 static LRESULT
PRINTDLG_WMCommand(HWND hDlg
, WPARAM wParam
,
960 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
962 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
963 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
964 [PrintStructures
->CurrentPrinter
]);
967 switch (LOWORD(wParam
))
970 TRACE(" OK button was hit\n");
971 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg
, PrintStructures
)!=TRUE
)
976 TRACE(" CANCEL button was hit\n");
977 EndDialog(hDlg
, FALSE
);
980 TRACE(" HELP button was hit\n");
981 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
982 (WPARAM
) hDlg
, (LPARAM
) lppd
);
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
);
989 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
990 (LPARAM
)PrintStructures
->hNoCollateIcon
);
992 case edt1
: /* from page nr editbox */
993 case edt2
: /* to page nr editbox */
994 if (HIWORD(wParam
)==EN_CHANGE
)
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
);
1004 case psh2
: /* Properties button */
1007 char PrinterName[256];
1008 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1009 if (OpenPrinterA(PrinterName, &hPrinter, NULL))
1011 PrinterProperties(hDlg, hPrinter);
1012 ClosePrinter(hPrinter);
1015 WARN(" Call to OpenPrinter did not succeed!\n");
1017 */ MessageBoxA(hDlg
, "Not implemented yet!", "PRINT", MB_OK
);
1019 case cmb4
: /* Printer combobox */
1020 if (HIWORD(wParam
)==CBN_SELCHANGE
)
1023 char PrinterName
[256];
1025 /* look the newly selected Printer up in
1026 * our array Printer_Info2As
1028 GetDlgItemTextA(hDlg
, cmb4
, PrinterName
, 255);
1029 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
1031 if (strcmp(PrintStructures
->lpPrinterInfo
[i
].pPrinterName
,
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
)
1042 /* if printer doesn't support it: no nCopies */
1043 if (!(lppi
->pDevMode
->dmFields
& DM_COPIES
))
1045 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1046 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1050 EnableWindow(GetDlgItem(hDlg
, edt3
), TRUE
);
1051 EnableWindow(GetDlgItem(hDlg
, stc5
), TRUE
);
1053 /* if printer doesn't support it: no Collate */
1054 if (!(lppi
->pDevMode
->dmFields
& DM_COPIES
))
1056 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1057 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1061 EnableWindow(GetDlgItem(hDlg
, ico3
), TRUE
);
1062 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1073 /***********************************************************************
1074 * PRINTSETUP32DLG_WMCommand [internal]
1076 static LRESULT
PRINTSETUP32DLG_WMCommand(HWND hDlg
, WPARAM wParam
,
1077 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1079 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1080 LPPRINTER_INFO_2A lppi
= &(PrintStructures
->lpPrinterInfo
1081 [PrintStructures
->CurrentPrinter
]);
1084 switch (LOWORD(wParam
))
1087 TRACE(" OK button was hit\n");
1088 if (PRINTSETUP32DLG_ValidateAndDuplicateSettings(hDlg
, PrintStructures
) != TRUE
)
1090 DestroyWindow(hDlg
);
1093 TRACE(" CANCEL button was hit\n");
1094 EndDialog(hDlg
, FALSE
);
1097 TRACE(" HELP button was hit\n");
1098 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1099 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1101 case psh2
: /* Properties button */
1102 MessageBoxA(hDlg
, "Not implemented yet!", "PRINT SETUP", MB_OK
);
1104 case cmb1
: /* Printer combobox */
1105 if (HIWORD(wParam
)==CBN_SELCHANGE
)
1110 /* look the newly selected Printer up in
1111 * our array Printer_Info2As
1113 GetDlgItemTextA(hDlg
, cmb1
, Name
, 255);
1114 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
1116 if (strcmp(PrintStructures
->lpPrinterInfo
[i
].pPrinterName
,
1120 PrintStructures
->CurrentPrinter
= i
;
1121 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
1122 lppi
= &(PrintStructures
->
1123 lpPrinterInfo
[PrintStructures
->CurrentPrinter
]);
1125 /* Update both ComboBoxes to the items available for the new
1126 * printer. Keep the same entry selected, if possible
1128 PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb2
, lppi
->pPrinterName
,
1130 PRINTSETUP32DLG_UpdateComboBox(hDlg
, cmb3
, lppi
->pPrinterName
,
1139 /***********************************************************************
1140 * PrintDlgProcA [internal]
1142 LRESULT WINAPI
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1145 PRINT_PTRA
* PrintStructures
;
1147 if (uMsg
!=WM_INITDIALOG
)
1149 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
1150 if (!PrintStructures
)
1155 PrintStructures
=(PRINT_PTRA
*) lParam
;
1156 if (!PRINTDLG_WMInitDialog(hDlg
, wParam
, lParam
, PrintStructures
))
1158 TRACE("PRINTDLG_WMInitDialog returned FALSE\n");
1165 return PRINTDLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
1176 /***********************************************************************
1177 * PrintDlgProc16 (COMMDLG.21)
1179 LRESULT WINAPI
PrintDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
1185 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
1186 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
1192 EndDialog(hWnd
, TRUE
);
1195 EndDialog(hWnd
, FALSE
);
1204 /***********************************************************************
1205 * PrintSetupDlgProc (COMMDLG.22)
1207 LRESULT WINAPI
PrintSetupDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
1213 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
1214 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
1219 EndDialog(hWnd
, TRUE
);
1222 EndDialog(hWnd
, FALSE
);
1231 /***********************************************************************
1232 * PrintSetupDlgProcA [???]
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.
1241 LRESULT WINAPI
PrintSetupDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1244 PRINT_PTRA
* PrintStructures
;
1246 if (uMsg
!=WM_INITDIALOG
)
1248 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
1249 if (!PrintStructures
)
1254 PrintStructures
=(PRINT_PTRA
*) lParam
;
1255 if (!PRINTSETUP32DLG_WMInitDialog(hDlg
, wParam
, lParam
, PrintStructures
))
1257 TRACE("PRINTSETUP32DLG_WMInitDialog returned FALSE\n");
1264 return PRINTSETUP32DLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
1276 /***********************************************************************
1277 * PageSetupDlgA (COMDLG32.15)
1279 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
1280 FIXME("(%p), stub!\n",setupdlg
);