2 * COMMDLG - Print Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
7 * Copyright 2000 Huw D M Davies
16 #include "wine/wingdi16.h"
18 #include "wine/winuser16.h"
21 #include "debugtools.h"
26 DEFAULT_DEBUG_CHANNEL(commdlg
);
30 /* This PRINTDLGA internal structure stores
31 * pointers to several throughout useful structures.
38 LPPRINTDLGA lpPrintDlg
;
39 LPPRINTDLG16 lpPrintDlg16
;
41 LPPRINTER_INFO_2A lpPrinterInfo
;
43 HICON hCollateIcon
; /* PrintDlg only */
44 HICON hNoCollateIcon
; /* PrintDlg only */
45 HICON hPortraitIcon
; /* PrintSetupDlg only */
46 HICON hLandscapeIcon
; /* PrintSetupDlg only */
50 static struct pd_flags
{
54 {PD_SELECTION
, "PD_SELECTION "},
55 {PD_PAGENUMS
, "PD_PAGENUMS "},
56 {PD_NOSELECTION
, "PD_NOSELECTION "},
57 {PD_NOPAGENUMS
, "PD_NOPAGENUMS "},
58 {PD_COLLATE
, "PD_COLLATE "},
59 {PD_PRINTTOFILE
, "PD_PRINTTOFILE "},
60 {PD_PRINTSETUP
, "PD_PRINTSETUP "},
61 {PD_NOWARNING
, "PD_NOWARNING "},
62 {PD_RETURNDC
, "PD_RETURNDC "},
63 {PD_RETURNIC
, "PD_RETURNIC "},
64 {PD_RETURNDEFAULT
, "PD_RETURNDEFAULT "},
65 {PD_SHOWHELP
, "PD_SHOWHELP "},
66 {PD_ENABLEPRINTHOOK
, "PD_ENABLEPRINTHOOK "},
67 {PD_ENABLESETUPHOOK
, "PD_ENABLESETUPHOOK "},
68 {PD_ENABLEPRINTTEMPLATE
, "PD_ENABLEPRINTTEMPLATE "},
69 {PD_ENABLESETUPTEMPLATE
, "PD_ENABLESETUPTEMPLATE "},
70 {PD_ENABLEPRINTTEMPLATEHANDLE
, "PD_ENABLEPRINTTEMPLATEHANDLE "},
71 {PD_ENABLESETUPTEMPLATEHANDLE
, "PD_ENABLESETUPTEMPLATEHANDLE "},
72 {PD_USEDEVMODECOPIES
, "PD_USEDEVMODECOPIES[ANDCOLLATE] "},
73 {PD_DISABLEPRINTTOFILE
, "PD_DISABLEPRINTTOFILE "},
74 {PD_HIDEPRINTTOFILE
, "PD_HIDEPRINTTOFILE "},
75 {PD_NONETWORKBUTTON
, "PD_NONETWORKBUTTON "},
80 /***********************************************************************
81 * PRINTDLG_GetDefaultPrinterName
83 * Returns the default printer name in buf.
84 * Even under WinNT/2000 default printer is retrieved via GetProfileString -
85 * these entries are mapped somewhere in the registry rather than win.ini.
87 * Returns TRUE on success else FALSE
89 static BOOL
PRINTDLG_GetDefaultPrinterName(LPSTR buf
, DWORD len
)
93 if(!GetProfileStringA("windows", "device", "", buf
, len
)) {
94 TRACE("No profile entry for default printer found.\n");
97 if((ptr
= strchr(buf
, ',')) == NULL
) {
98 FIXME("bad format for default printer (%s)!\n",buf
);
105 /***********************************************************************
106 * PRINTDLG_OpenDefaultPrinter
108 * Returns a winspool printer handle to the default printer in *hprn
109 * Caller must call ClosePrinter on the handle
111 * Returns TRUE on success else FALSE
113 static BOOL
PRINTDLG_OpenDefaultPrinter(HANDLE
*hprn
)
117 if(!PRINTDLG_GetDefaultPrinterName(buf
, sizeof(buf
)))
119 res
= OpenPrinterA(buf
, hprn
, NULL
);
121 FIXME("Could not open printer %s?!\n",buf
);
125 /***********************************************************************
126 * PRINTDLG_SetUpPrinterListCombo
128 * Initializes printer list combox.
129 * hDlg: HWND of dialog
130 * id: Control id of combo
131 * name: Name of printer to select
133 * Initializes combo with list of available printers. Selects printer 'name'
134 * If name is NULL or does not exist select the default printer.
136 * Returns number of printers added to list.
138 static INT
PRINTDLG_SetUpPrinterListCombo(HWND hDlg
, UINT id
, LPCSTR name
)
142 LPPRINTER_INFO_2A pi
;
143 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
144 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
145 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
148 for(i
= 0; i
< num
; i
++) {
149 SendDlgItemMessageA(hDlg
, id
, CB_ADDSTRING
, 0,
150 (LPARAM
)pi
[i
].pPrinterName
);
152 HeapFree(GetProcessHeap(), 0, pi
);
154 (i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
155 (LPARAM
)name
)) == CB_ERR
) {
158 FIXME("Can't find '%s' in printer list so trying to find default\n",
160 if(!PRINTDLG_GetDefaultPrinterName(buf
, sizeof(buf
)))
162 i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
164 FIXME("Can't find default printer in printer list\n");
166 SendDlgItemMessageA(hDlg
, id
, CB_SETCURSEL
, i
, 0);
170 /***********************************************************************
171 * PRINTDLG_CreateDevNames [internal]
174 * creates a DevNames structure.
176 * (NB. when we handle unicode the offsets will be in wchars).
178 static BOOL
PRINTDLG_CreateDevNames(HGLOBAL
*hmem
, char* DeviceDriverName
,
179 char* DeviceName
, char* OutputPort
)
182 char* pDevNamesSpace
;
184 LPDEVNAMES lpDevNames
;
187 size
= strlen(DeviceDriverName
) + 1
188 + strlen(DeviceName
) + 1
189 + strlen(OutputPort
) + 1
193 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
195 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
199 pDevNamesSpace
= GlobalLock(*hmem
);
200 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
202 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
203 strcpy(pTempPtr
, DeviceDriverName
);
204 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
206 pTempPtr
+= strlen(DeviceDriverName
) + 1;
207 strcpy(pTempPtr
, DeviceName
);
208 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
210 pTempPtr
+= strlen(DeviceName
) + 1;
211 strcpy(pTempPtr
, OutputPort
);
212 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
214 PRINTDLG_GetDefaultPrinterName(buf
, sizeof(buf
));
215 lpDevNames
->wDefault
= (strcmp(buf
, DeviceName
) == 0) ? 1 : 0;
220 static BOOL
PRINTDLG_CreateDevNames16(HGLOBAL16
*hmem
, char* DeviceDriverName
,
221 char* DeviceName
, char* OutputPort
)
224 char* pDevNamesSpace
;
226 LPDEVNAMES lpDevNames
;
229 size
= strlen(DeviceDriverName
) + 1
230 + strlen(DeviceName
) + 1
231 + strlen(OutputPort
) + 1
235 *hmem
= GlobalReAlloc16(*hmem
, size
, GMEM_MOVEABLE
);
237 *hmem
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
241 pDevNamesSpace
= GlobalLock16(*hmem
);
242 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
244 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
245 strcpy(pTempPtr
, DeviceDriverName
);
246 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
248 pTempPtr
+= strlen(DeviceDriverName
) + 1;
249 strcpy(pTempPtr
, DeviceName
);
250 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
252 pTempPtr
+= strlen(DeviceName
) + 1;
253 strcpy(pTempPtr
, OutputPort
);
254 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
256 PRINTDLG_GetDefaultPrinterName(buf
, sizeof(buf
));
257 lpDevNames
->wDefault
= (strcmp(buf
, DeviceName
) == 0) ? 1 : 0;
258 GlobalUnlock16(*hmem
);
263 /***********************************************************************
264 * PRINTDLG_UpdatePrintDlg [internal]
267 * updates the PrintDlg structure for returnvalues.
270 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
273 static BOOL
PRINTDLG_UpdatePrintDlg(HWND hDlg
,
274 PRINT_PTRA
* PrintStructures
)
276 LPPRINTDLGA lppd
= PrintStructures
->dlg
.lpPrintDlg
;
277 PDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
278 LPPRINTER_INFO_2A pi
= PrintStructures
->lpPrinterInfo
;
282 FIXME("No lpdm ptr?\n");
287 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
288 /* check whether nFromPage and nToPage are within range defined by
289 * nMinPage and nMaxPage
291 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
294 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
295 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
296 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
297 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
298 char resourcestr
[256];
300 LoadStringA(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
302 sprintf(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
303 LoadStringA(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
305 MessageBoxA(hDlg
, resultstr
, resourcestr
,
306 MB_OK
| MB_ICONWARNING
);
309 lppd
->nFromPage
= nFromPage
;
310 lppd
->nToPage
= nToPage
;
313 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
314 lppd
->Flags
|= PD_PRINTTOFILE
;
315 pi
->pPortName
= "FILE:";
318 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
319 FIXME("Collate lppd not yet implemented as output\n");
322 /* set PD_Collate and nCopies */
323 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
324 /* The application doesn't support multiple copies or collate...
326 lppd
->Flags
&= ~PD_COLLATE
;
328 /* if the printer driver supports it... store info there
329 * otherwise no collate & multiple copies !
331 if (lpdm
->dmFields
& DM_COLLATE
)
333 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
334 if (lpdm
->dmFields
& DM_COPIES
)
335 lpdm
->dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
337 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
338 lppd
->Flags
|= PD_COLLATE
;
340 lppd
->Flags
&= ~PD_COLLATE
;
341 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
348 /************************************************************************
349 * PRINTDLG_SetUpPaperComboBox
351 * Initialize either the papersize or inputslot combos of the Printer Setup
352 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
353 * We also try to re-select the old selection.
355 static BOOL
PRINTDLG_SetUpPaperComboBox(HWND hDlg
,
368 int fwCapability_Names
;
369 int fwCapability_Words
;
371 TRACE(" Printer: %s, ComboID: %d\n",PrinterName
,nIDComboBox
);
373 /* query the dialog box for the current selected value */
374 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
376 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, Sel
,
380 if (nIDComboBox
== cmb2
) {
382 fwCapability_Names
= DC_PAPERNAMES
;
383 fwCapability_Words
= DC_PAPERS
;
387 fwCapability_Names
= DC_BINNAMES
;
388 fwCapability_Words
= DC_BINS
;
391 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
392 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
394 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
395 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
396 fwCapability_Names
, NULL
, dm
);
397 if (NrOfEntries
== 0)
398 WARN("no Name Entries found!\n");
400 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
402 ERR("Number of caps is different\n");
406 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*NamesSize
);
407 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
408 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
409 fwCapability_Names
, Names
, dm
);
410 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
411 fwCapability_Words
, (LPSTR
)Words
, dm
);
413 /* reset any current content in the combobox */
414 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
416 /* store new content */
417 for (i
= 0; i
< NrOfEntries
; i
++) {
418 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
419 (LPARAM
)(&Names
[i
*NamesSize
]) );
420 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
424 /* Look for old selection - can't do this is previous loop since
425 item order will change as more items are added */
427 for (i
= 0; i
< NrOfEntries
; i
++) {
428 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
434 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
436 HeapFree(GetProcessHeap(),0,Words
);
437 HeapFree(GetProcessHeap(),0,Names
);
441 /***********************************************************************
442 * PRINTDLG_UpdatePrinterInfoTexts [internal]
444 static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg
, LPPRINTER_INFO_2A pi
)
447 char ResourceString
[256];
453 /* add all status messages */
454 for (i
= 0; i
< 25; i
++) {
455 if (pi
->Status
& (1<<i
)) {
456 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
457 ResourceString
, 255);
458 strcat(StatusMsg
,ResourceString
);
462 /* FIXME: status==ready must only be appended if really so.
463 but how to detect? */
464 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
465 ResourceString
, 255);
466 strcat(StatusMsg
,ResourceString
);
468 SendDlgItemMessageA(hDlg
, stc12
, WM_SETTEXT
, 0, (LPARAM
)StatusMsg
);
470 /* set all other printer info texts */
471 SendDlgItemMessageA(hDlg
, stc11
, WM_SETTEXT
, 0, (LPARAM
)pi
->pDriverName
);
472 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
473 SendDlgItemMessageA(hDlg
, stc14
, WM_SETTEXT
, 0,(LPARAM
)pi
->pLocation
);
475 SendDlgItemMessageA(hDlg
, stc14
, WM_SETTEXT
, 0,(LPARAM
)pi
->pPortName
);
476 SendDlgItemMessageA(hDlg
, stc13
, WM_SETTEXT
, 0, (LPARAM
)pi
->pComment
);
481 /*******************************************************************
483 * PRINTDLG_ChangePrinter
486 static BOOL
PRINTDLG_ChangePrinter(HWND hDlg
, char *name
,
487 PRINT_PTRA
*PrintStructures
)
489 LPPRINTDLGA lppd
= PrintStructures
->dlg
.lpPrintDlg
;
490 LPDEVMODEA lpdm
= NULL
;
495 if(PrintStructures
->lpPrinterInfo
)
496 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
497 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
498 ERR("Can't open printer %s\n", name
);
501 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
502 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
503 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
507 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
->lpPrinterInfo
);
509 if(PrintStructures
->lpDevMode
) {
510 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
511 PrintStructures
->lpDevMode
= NULL
;
514 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
516 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
519 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
520 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
522 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
523 !strcmp(lpdm
->dmDeviceName
,
524 PrintStructures
->lpDevMode
->dmDeviceName
)) {
525 /* Supplied devicemode matches current printer so try to use it */
526 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
527 DM_OUT_BUFFER
| DM_IN_BUFFER
);
530 GlobalUnlock(lppd
->hDevMode
);
532 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
534 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
535 /* Print range (All/Range/Selection) */
536 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
537 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
538 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
539 if (lppd
->Flags
& PD_NOSELECTION
)
540 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
542 if (lppd
->Flags
& PD_SELECTION
)
543 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
544 if (lppd
->Flags
& PD_NOPAGENUMS
) {
545 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
546 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
547 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
548 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
549 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
551 if (lppd
->Flags
& PD_PAGENUMS
)
552 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
554 /* "All xxx pages"... */
556 char resourcestr
[64];
558 LoadStringA(COMDLG32_hInstance
, PD32_PRINT_ALL_X_PAGES
,
560 sprintf(result
,resourcestr
,lppd
->nMaxPage
- lppd
->nMinPage
+ 1);
561 SendDlgItemMessageA(hDlg
, rad1
, WM_SETTEXT
, 0, (LPARAM
) result
);
566 * FIXME: The ico3 is not displayed for some reason. I don't know why.
568 if (lppd
->Flags
& PD_COLLATE
) {
569 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
570 (LPARAM
)PrintStructures
->hCollateIcon
);
571 CheckDlgButton(hDlg
, chx2
, 1);
573 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
574 (LPARAM
)PrintStructures
->hNoCollateIcon
);
575 CheckDlgButton(hDlg
, chx2
, 0);
578 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
579 /* if printer doesn't support it: no Collate */
580 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
581 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
582 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
587 if (lppd
->hDevMode
== 0)
588 SetDlgItemInt(hDlg
, edt3
, lppd
->nCopies
, FALSE
);
590 SetDlgItemInt(hDlg
, edt3
, lpdm
->dmCopies
, FALSE
);
592 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
593 /* if printer doesn't support it: no nCopies */
594 if (!(lpdm
->dmFields
& DM_COPIES
)) {
595 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
596 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
601 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
602 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
603 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
604 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
605 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
607 } else { /* PD_PRINTSETUP */
608 PRINTDLG_SetUpPaperComboBox(hDlg
, cmb2
,
609 PrintStructures
->lpPrinterInfo
->pPrinterName
,
610 PrintStructures
->lpPrinterInfo
->pPortName
,
612 PRINTDLG_SetUpPaperComboBox(hDlg
, cmb3
,
613 PrintStructures
->lpPrinterInfo
->pPrinterName
,
614 PrintStructures
->lpPrinterInfo
->pPortName
,
616 CheckRadioButton(hDlg
, rad1
, rad2
,
617 (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
) ?
622 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
623 /* hide if PD_SHOWHELP not specified */
624 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
629 /***********************************************************************
630 * PRINTDLG_WMInitDialog [internal]
632 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
633 PRINT_PTRA
* PrintStructures
)
635 LPPRINTDLGA lppd
= PrintStructures
->dlg
.lpPrintDlg
;
639 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
641 /* load Collate ICONs */
642 PrintStructures
->hCollateIcon
=
643 LoadIconA(COMDLG32_hInstance
, "PD32_COLLATE");
644 PrintStructures
->hNoCollateIcon
=
645 LoadIconA(COMDLG32_hInstance
, "PD32_NOCOLLATE");
646 if(PrintStructures
->hCollateIcon
== 0 ||
647 PrintStructures
->hNoCollateIcon
== 0) {
648 ERR("no icon in resourcefile\n");
649 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
650 EndDialog(hDlg
, FALSE
);
653 /* load Paper Orientation ICON */
654 /* FIXME: not implemented yet */
657 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
658 * must be registered and the Help button must be shown.
660 if (lppd
->Flags
& PD_SHOWHELP
) {
661 if((PrintStructures
->HelpMessageID
=
662 RegisterWindowMessageA(HELPMSGSTRING
)) == 0) {
663 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
667 PrintStructures
->HelpMessageID
= 0;
669 /* FIXME: I allow more freedom than either Win95 or WinNT,
670 * which do not agree to what errors should be thrown or not
671 * in case nToPage or nFromPage is out-of-range.
673 if (lppd
->nMaxPage
< lppd
->nMinPage
)
674 lppd
->nMaxPage
= lppd
->nMinPage
;
675 if (lppd
->nMinPage
== lppd
->nMaxPage
)
676 lppd
->Flags
|= PD_NOPAGENUMS
;
677 if (lppd
->nToPage
< lppd
->nMinPage
)
678 lppd
->nToPage
= lppd
->nMinPage
;
679 if (lppd
->nToPage
> lppd
->nMaxPage
)
680 lppd
->nToPage
= lppd
->nMaxPage
;
681 if (lppd
->nFromPage
< lppd
->nMinPage
)
682 lppd
->nFromPage
= lppd
->nMinPage
;
683 if (lppd
->nFromPage
> lppd
->nMaxPage
)
684 lppd
->nFromPage
= lppd
->nMaxPage
;
686 /* if we have the combo box, fill it */
687 if (GetDlgItem(hDlg
,comboID
)) {
690 pdn
= GlobalLock(lppd
->hDevNames
);
691 pdm
= GlobalLock(lppd
->hDevMode
);
693 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
695 name
= pdm
->dmDeviceName
;
696 PRINTDLG_SetUpPrinterListCombo(hDlg
, comboID
, name
);
697 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
698 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
700 /* Now find selected printer and update rest of dlg */
701 name
= HeapAlloc(GetProcessHeap(),0,256);
702 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
703 PRINTDLG_ChangePrinter(hDlg
, name
, PrintStructures
);
704 HeapFree(GetProcessHeap(),0,name
);
706 /* else use default printer */
708 BOOL ret
= PRINTDLG_GetDefaultPrinterName(name
, sizeof(name
));
711 PRINTDLG_ChangePrinter(hDlg
, name
, PrintStructures
);
713 FIXME("No default printer found, expect problems!\n");
718 /***********************************************************************
719 * PRINTDLG_WMInitDialog [internal]
721 static LRESULT
PRINTDLG_WMInitDialog16(HWND hDlg
, WPARAM wParam
,
722 PRINT_PTRA
* PrintStructures
)
724 LPPRINTDLG16 lppd
= PrintStructures
->dlg
.lpPrintDlg16
;
728 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
730 /* load Collate ICONs */
731 PrintStructures
->hCollateIcon
=
732 LoadIconA(COMDLG32_hInstance
, "PD32_COLLATE");
733 PrintStructures
->hNoCollateIcon
=
734 LoadIconA(COMDLG32_hInstance
, "PD32_NOCOLLATE");
735 if(PrintStructures
->hCollateIcon
== 0 ||
736 PrintStructures
->hNoCollateIcon
== 0) {
737 ERR("no icon in resourcefile\n");
738 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
739 EndDialog(hDlg
, FALSE
);
742 /* load Paper Orientation ICON */
743 /* FIXME: not implemented yet */
746 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
747 * must be registered and the Help button must be shown.
749 if (lppd
->Flags
& PD_SHOWHELP
) {
750 if((PrintStructures
->HelpMessageID
=
751 RegisterWindowMessageA(HELPMSGSTRING
)) == 0) {
752 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
756 PrintStructures
->HelpMessageID
= 0;
758 /* FIXME: I allow more freedom than either Win95 or WinNT,
759 * which do not agree to what errors should be thrown or not
760 * in case nToPage or nFromPage is out-of-range.
762 if (lppd
->nMaxPage
< lppd
->nMinPage
)
763 lppd
->nMaxPage
= lppd
->nMinPage
;
764 if (lppd
->nMinPage
== lppd
->nMaxPage
)
765 lppd
->Flags
|= PD_NOPAGENUMS
;
766 if (lppd
->nToPage
< lppd
->nMinPage
)
767 lppd
->nToPage
= lppd
->nMinPage
;
768 if (lppd
->nToPage
> lppd
->nMaxPage
)
769 lppd
->nToPage
= lppd
->nMaxPage
;
770 if (lppd
->nFromPage
< lppd
->nMinPage
)
771 lppd
->nFromPage
= lppd
->nMinPage
;
772 if (lppd
->nFromPage
> lppd
->nMaxPage
)
773 lppd
->nFromPage
= lppd
->nMaxPage
;
775 /* If the printer combo box is in the dialog, fill it */
776 if (GetDlgItem(hDlg
,comboID
)) {
779 pdn
= GlobalLock16(lppd
->hDevNames
);
780 pdm
= GlobalLock16(lppd
->hDevMode
);
782 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
784 name
= pdm
->dmDeviceName
;
785 PRINTDLG_SetUpPrinterListCombo(hDlg
, comboID
, name
);
786 if(pdm
) GlobalUnlock16(lppd
->hDevMode
);
787 if(pdn
) GlobalUnlock16(lppd
->hDevNames
);
789 /* Now find selected printer and update rest of dlg */
790 name
= HeapAlloc(GetProcessHeap(),0,256);
791 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
792 PRINTDLG_ChangePrinter(hDlg
, name
, PrintStructures
);
794 /* else just use default printer */
796 BOOL ret
= PRINTDLG_GetDefaultPrinterName(name
, sizeof(name
));
799 PRINTDLG_ChangePrinter(hDlg
, name
, PrintStructures
);
801 FIXME("No default printer found, expect problems!\n");
803 HeapFree(GetProcessHeap(),0,name
);
808 /***********************************************************************
809 * PRINTDLG_WMCommand [internal]
811 static LRESULT
PRINTDLG_WMCommand(HWND hDlg
, WPARAM wParam
,
812 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
814 LPPRINTDLGA lppd
= PrintStructures
->dlg
.lpPrintDlg
;
815 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
816 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
818 switch (LOWORD(wParam
)) {
820 TRACE(" OK button was hit\n");
821 if (PRINTDLG_UpdatePrintDlg(hDlg
, PrintStructures
)!=TRUE
) {
822 FIXME("Update printdlg was not successful!\n");
825 EndDialog(hDlg
, TRUE
);
829 TRACE(" CANCEL button was hit\n");
830 EndDialog(hDlg
, FALSE
);
834 TRACE(" HELP button was hit\n");
835 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
836 (WPARAM
) hDlg
, (LPARAM
) lppd
);
839 case chx2
: /* collate pages checkbox */
840 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
841 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
842 (LPARAM
)PrintStructures
->hCollateIcon
);
844 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
845 (LPARAM
)PrintStructures
->hNoCollateIcon
);
847 case edt1
: /* from page nr editbox */
848 case edt2
: /* to page nr editbox */
849 if (HIWORD(wParam
)==EN_CHANGE
) {
852 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
853 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
854 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
855 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
858 case psh2
: /* Properties button */
861 char PrinterName
[256];
863 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
864 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
865 FIXME(" Call to OpenPrinter did not succeed!\n");
868 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
869 PrintStructures
->lpDevMode
,
870 PrintStructures
->lpDevMode
,
871 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
872 ClosePrinter(hPrinter
);
877 case cmb4
: /* Printer combobox */
878 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
879 char PrinterName
[256];
880 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
881 PRINTDLG_ChangePrinter(hDlg
, PrinterName
, PrintStructures
);
885 case cmb2
: /* Papersize */
887 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
889 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
897 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
899 lpdm
->dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
908 /***********************************************************************
909 * PrintDlgProcA [internal]
911 BOOL WINAPI
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
914 PRINT_PTRA
* PrintStructures
;
917 if (uMsg
!=WM_INITDIALOG
) {
918 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
919 if (!PrintStructures
)
922 PrintStructures
= (PRINT_PTRA
*) lParam
;
923 SetWindowLongA(hDlg
, DWL_USER
, lParam
);
924 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
926 if(PrintStructures
->dlg
.lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
927 res
= PrintStructures
->dlg
.lpPrintDlg
->lpfnPrintHook(
928 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->dlg
.lpPrintDlg
933 if(PrintStructures
->dlg
.lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
934 res
= PrintStructures
->dlg
.lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
941 return PRINTDLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
944 DestroyIcon(PrintStructures
->hCollateIcon
);
945 DestroyIcon(PrintStructures
->hNoCollateIcon
);
946 /* FIXME: don't forget to delete the paper orientation icons here! */
953 /************************************************************
955 * PRINTDLG_GetDlgTemplate
958 static HGLOBAL
PRINTDLG_GetDlgTemplate(PRINTDLGA
*lppd
)
960 HGLOBAL hDlgTmpl
, hResInfo
;
962 if (lppd
->Flags
& PD_PRINTSETUP
) {
963 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
964 hDlgTmpl
= lppd
->hSetupTemplate
;
965 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
966 hResInfo
= FindResourceA(lppd
->hInstance
,
967 lppd
->lpSetupTemplateName
, RT_DIALOGA
);
968 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
970 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
972 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
975 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
976 hDlgTmpl
= lppd
->hPrintTemplate
;
977 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
978 hResInfo
= FindResourceA(lppd
->hInstance
,
979 lppd
->lpPrintTemplateName
,
981 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
983 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
985 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
991 /************************************************************
993 * PRINTDLG_GetDlgTemplate
996 static HGLOBAL16
PRINTDLG_GetDlgTemplate16(PRINTDLG16
*lppd
)
998 HGLOBAL16 hDlgTmpl
, hResInfo
;
1000 if (lppd
->Flags
& PD_PRINTSETUP
) {
1001 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1002 hDlgTmpl
= lppd
->hSetupTemplate
;
1003 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1004 hResInfo
= FindResource16(lppd
->hInstance
,
1005 MapSL(lppd
->lpSetupTemplateName
), RT_DIALOGA
);
1006 hDlgTmpl
= LoadResource16(lppd
->hInstance
, hResInfo
);
1008 ERR("no comctl32 templates for printing setup currently!\n");
1012 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1013 hDlgTmpl
= lppd
->hPrintTemplate
;
1014 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1015 hResInfo
= FindResource16(lppd
->hInstance
,
1016 MapSL(lppd
->lpPrintTemplateName
),
1018 hDlgTmpl
= LoadResource16(lppd
->hInstance
, hResInfo
);
1020 ERR("no comctl32 templates for printing currently!\n");
1027 /***********************************************************************
1032 static BOOL
PRINTDLG_CreateDC(LPPRINTDLGA lppd
)
1034 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
1035 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
1037 if(lppd
->Flags
& PD_RETURNDC
) {
1038 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
1039 (char*)pdn
+ pdn
->wDeviceOffset
,
1040 (char*)pdn
+ pdn
->wOutputOffset
,
1042 } else if(lppd
->Flags
& PD_RETURNIC
) {
1043 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
1044 (char*)pdn
+ pdn
->wDeviceOffset
,
1045 (char*)pdn
+ pdn
->wOutputOffset
,
1048 GlobalUnlock(lppd
->hDevNames
);
1049 GlobalUnlock(lppd
->hDevMode
);
1050 return lppd
->hDC
? TRUE
: FALSE
;
1053 static BOOL
PRINTDLG_CreateDC16(LPPRINTDLG16 lppd
)
1055 DEVNAMES
*pdn
= GlobalLock16(lppd
->hDevNames
);
1056 DEVMODEA
*pdm
= GlobalLock16(lppd
->hDevMode
);
1058 if(lppd
->Flags
& PD_RETURNDC
) {
1059 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
1060 (char*)pdn
+ pdn
->wDeviceOffset
,
1061 (char*)pdn
+ pdn
->wOutputOffset
,
1063 } else if(lppd
->Flags
& PD_RETURNIC
) {
1064 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
1065 (char*)pdn
+ pdn
->wDeviceOffset
,
1066 (char*)pdn
+ pdn
->wOutputOffset
,
1069 GlobalUnlock16(lppd
->hDevNames
);
1070 GlobalUnlock16(lppd
->hDevMode
);
1071 return lppd
->hDC
? TRUE
: FALSE
;
1074 /***********************************************************************
1075 * PrintDlgA (COMDLG32.17)
1077 * Displays the the PRINT dialog box, which enables the user to specify
1078 * specific properties of the print job.
1081 * nonzero if the user pressed the OK button
1082 * zero if the user cancelled the window or an error occurred
1086 * * The Collate Icons do not display, even though they are in the code.
1087 * * The Properties Button(s) should call DocumentPropertiesA().
1089 * * The Paper Orientation Icons are not implemented yet.
1090 * * The Properties Button(s) should call DocumentPropertiesA().
1091 * * Settings are not yet taken from a provided DevMode or
1092 * default printer settings.
1094 BOOL WINAPI
PrintDlgA(
1095 LPPRINTDLGA lppd
/* [in/out] ptr to PRINTDLG32 struct */
1100 HINSTANCE hInst
= GetWindowLongA( lppd
->hwndOwner
, GWL_HINSTANCE
);
1102 if(TRACE_ON(commdlg
)) {
1103 char flagstr
[1000] = "";
1104 struct pd_flags
*pflag
= pd_flags
;
1105 for( ; pflag
->name
; pflag
++) {
1106 if(lppd
->Flags
& pflag
->flag
)
1107 strcat(flagstr
, pflag
->name
);
1109 TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
1110 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n"
1111 "flags %08lx (%s)\n",
1112 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
1113 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
1114 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
1117 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
1118 WARN("structure size failure !!!\n");
1119 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
1123 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
1124 PRINTER_INFO_2A
*pbuf
;
1128 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
1129 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
1130 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
1133 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
1134 WARN("Can't find default printer\n");
1135 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
1139 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
1140 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
1141 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
1143 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
), "winspool",
1144 pbuf
->pDevMode
->dmDeviceName
,
1146 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
1147 pbuf
->pDevMode
->dmDriverExtra
);
1148 ptr
= GlobalLock(lppd
->hDevMode
);
1149 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
1150 pbuf
->pDevMode
->dmDriverExtra
);
1151 GlobalUnlock(lppd
->hDevMode
);
1152 HeapFree(GetProcessHeap(), 0, pbuf
);
1156 PRINT_PTRA
*PrintStructures
;
1158 /* load Dialog resources,
1159 * depending on Flags indicates Print32 or Print32_setup dialog
1161 hDlgTmpl
= PRINTDLG_GetDlgTemplate(lppd
);
1163 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1166 ptr
= LockResource( hDlgTmpl
);
1168 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1172 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1173 sizeof(PRINT_PTRA
));
1174 PrintStructures
->dlg
.lpPrintDlg
= lppd
;
1176 /* and create & process the dialog .
1177 * -1 is failure, 0 is broken hwnd, everything else is ok.
1179 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
1181 (LPARAM
)PrintStructures
));
1184 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
1185 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
1187 if (lppd
->hDevMode
== 0) {
1188 TRACE(" No hDevMode yet... Need to create my own\n");
1189 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
1190 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
1193 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
1194 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
1196 GlobalUnlock(lppd
->hDevMode
);
1197 TRACE("Now got %d locks\n", locks
);
1200 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
1201 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
1204 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
1205 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
1207 if (lppd
->hDevNames
!= 0) {
1209 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
1210 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
1212 GlobalUnlock(lppd
->hDevNames
);
1215 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
), "winspool",
1216 lpdmReturn
->dmDeviceName
, pi
->pPortName
);
1217 GlobalUnlock(lppd
->hDevMode
);
1219 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1220 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
1221 HeapFree(GetProcessHeap(), 0, PrintStructures
);
1223 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
1224 bRet
= PRINTDLG_CreateDC(lppd
);
1226 TRACE("exit! (%d)\n", bRet
);
1230 /***********************************************************************
1231 * PrintDlg16 (COMMDLG.20)
1233 * Displays the the PRINT dialog box, which enables the user to specify
1234 * specific properties of the print job.
1237 * nonzero if the user pressed the OK button
1238 * zero if the user cancelled the window or an error occurred
1241 * * calls up to the 32-bit versions of the Dialogs, which look different
1242 * * Customizing is *not* implemented.
1245 BOOL16 WINAPI
PrintDlg16(
1246 LPPRINTDLG16 lppd
/* [in/out] ptr to PRINTDLG struct */
1250 HINSTANCE hInst
= GetWindowLongA( lppd
->hwndOwner
, GWL_HINSTANCE
);
1252 if(TRACE_ON(commdlg
)) {
1253 char flagstr
[1000] = "";
1254 struct pd_flags
*pflag
= pd_flags
;
1255 for( ; pflag
->name
; pflag
++) {
1256 if(lppd
->Flags
& pflag
->flag
)
1257 strcat(flagstr
, pflag
->name
);
1259 TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
1260 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n"
1261 "flags %08lx (%s)\n",
1262 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
1263 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
1264 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
1267 if(lppd
->lStructSize
!= sizeof(PRINTDLG16
)) {
1268 ERR("structure size (%ld/%d)\n",lppd
->lStructSize
,sizeof(PRINTDLG16
));
1269 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
1273 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
1274 PRINTER_INFO_2A
*pbuf
;
1278 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
1279 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
1280 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
1283 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
1284 WARN("Can't find default printer\n");
1285 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
1289 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
1290 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
1291 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
1293 PRINTDLG_CreateDevNames16(&(lppd
->hDevNames
), "winspool",
1294 pbuf
->pDevMode
->dmDeviceName
,
1296 lppd
->hDevMode
= GlobalAlloc16(GMEM_MOVEABLE
,pbuf
->pDevMode
->dmSize
+
1297 pbuf
->pDevMode
->dmDriverExtra
);
1298 ptr
= GlobalLock16(lppd
->hDevMode
);
1299 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
1300 pbuf
->pDevMode
->dmDriverExtra
);
1301 GlobalUnlock16(lppd
->hDevMode
);
1302 HeapFree(GetProcessHeap(), 0, pbuf
);
1306 PRINT_PTRA
*PrintStructures
;
1308 /* load Dialog resources,
1309 * depending on Flags indicates Print32 or Print32_setup dialog
1311 hDlgTmpl
= PRINTDLG_GetDlgTemplate16(lppd
);
1313 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1316 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1317 sizeof(PRINT_PTRA
));
1318 PrintStructures
->dlg
.lpPrintDlg16
= lppd
;
1319 PrintStructures
->dlg
.lpPrintDlg
= (LPPRINTDLGA
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(PRINTDLGA
));
1320 #define CVAL(x) PrintStructures->dlg.lpPrintDlg->x = lppd->x;
1321 #define MVAL(x) PrintStructures->dlg.lpPrintDlg->x = MapSL(lppd->x);
1322 CVAL(Flags
);CVAL(hwndOwner
);CVAL(hDC
);
1323 CVAL(nFromPage
);CVAL(nToPage
);CVAL(nMinPage
);CVAL(nMaxPage
);
1324 CVAL(nCopies
);CVAL(hInstance
);CVAL(lCustData
);
1325 MVAL(lpPrintTemplateName
);MVAL(lpSetupTemplateName
);
1326 /* Don't copy rest, it is 16 bit specific */
1330 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(),0,sizeof(DEVMODEA
));
1332 /* and create & process the dialog .
1333 * -1 is failure, 0 is broken hwnd, everything else is ok.
1335 bRet
= (0<DialogBoxIndirectParam16(
1336 hInst
, hDlgTmpl
, lppd
->hwndOwner
,
1337 (DLGPROC16
)GetProcAddress16(GetModuleHandle16("COMMDLG"),(LPCSTR
)21),
1338 (LPARAM
)PrintStructures
1341 if (!PrintStructures
->lpPrinterInfo
) bRet
= FALSE
;
1343 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
1344 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
1346 if (lppd
->hDevMode
== 0) {
1347 TRACE(" No hDevMode yet... Need to create my own\n");
1348 lppd
->hDevMode
= GlobalAlloc16(GMEM_MOVEABLE
,
1349 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
1352 if((locks
= (GlobalFlags16(lppd
->hDevMode
)&GMEM_LOCKCOUNT
))) {
1353 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
1355 GlobalUnlock16(lppd
->hDevMode
);
1356 TRACE("Now got %d locks\n", locks
);
1359 lppd
->hDevMode
= GlobalReAlloc16(lppd
->hDevMode
,
1360 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
1363 lpdmReturn
= GlobalLock16(lppd
->hDevMode
);
1364 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
1366 if (lppd
->hDevNames
!= 0) {
1368 if((locks
= (GlobalFlags16(lppd
->hDevNames
)&GMEM_LOCKCOUNT
))) {
1369 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
1371 GlobalUnlock16(lppd
->hDevNames
);
1374 PRINTDLG_CreateDevNames16(&(lppd
->hDevNames
), "winspool",
1375 lpdmReturn
->dmDeviceName
, pi
->pPortName
);
1376 GlobalUnlock16(lppd
->hDevMode
);
1378 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1379 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
1380 HeapFree(GetProcessHeap(), 0, PrintStructures
);
1382 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
1383 bRet
= PRINTDLG_CreateDC16(lppd
);
1385 TRACE("exit! (%d)\n", bRet
);
1391 /***********************************************************************
1392 * PrintDlgW (COMDLG32.18)
1394 BOOL WINAPI
PrintDlgW( LPPRINTDLGW printdlg
)
1396 FIXME("A really empty stub\n" );
1400 /***********************************************************************
1405 /***********************************************************************
1406 * PageSetupDlgA (COMDLG32.15)
1408 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
1409 FIXME("(%p), stub!\n",setupdlg
);
1412 /***********************************************************************
1413 * PageSetupDlgW (COMDLG32.16)
1415 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
1416 FIXME("(%p), stub!\n",setupdlg
);
1420 /**********************************************************************
1425 /***********************************************************************
1426 * PrintDlgProc16 (COMMDLG.21)
1428 LRESULT WINAPI
PrintDlgProc16(HWND16 hDlg
, UINT16 uMsg
, WPARAM16 wParam
,
1431 PRINT_PTRA
* PrintStructures
;
1434 if (uMsg
!=WM_INITDIALOG
) {
1435 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
1436 if (!PrintStructures
)
1439 PrintStructures
= (PRINT_PTRA
*) lParam
;
1440 SetWindowLongA(hDlg
, DWL_USER
, lParam
);
1441 res
= PRINTDLG_WMInitDialog16(hDlg
, wParam
, PrintStructures
);
1443 if(PrintStructures
->dlg
.lpPrintDlg16
->Flags
& PD_ENABLEPRINTHOOK
) {
1444 res
= CallWindowProc16(
1445 (WNDPROC16
)PrintStructures
->dlg
.lpPrintDlg16
->lpfnPrintHook
,
1446 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->dlg
.lpPrintDlg16
1452 if(PrintStructures
->dlg
.lpPrintDlg16
->Flags
& PD_ENABLEPRINTHOOK
) {
1453 res
= CallWindowProc16(
1454 (WNDPROC16
)PrintStructures
->dlg
.lpPrintDlg16
->lpfnPrintHook
,
1455 hDlg
,uMsg
, wParam
, lParam
1462 return PRINTDLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
1465 DestroyIcon(PrintStructures
->hCollateIcon
);
1466 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1467 /* FIXME: don't forget to delete the paper orientation icons here! */
1475 /***********************************************************************
1476 * PrintSetupDlgProc16 (COMMDLG.22)
1478 LRESULT WINAPI
PrintSetupDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
1484 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
1485 ShowWindow(hWnd
, SW_SHOWNORMAL
);
1490 EndDialog(hWnd
, TRUE
);
1493 EndDialog(hWnd
, FALSE
);
1502 /***********************************************************************
1505 HRESULT WINAPI
PrintDlgExA(LPVOID lpPrintDlgExA
) /* [???] FIXME: LPPRINTDLGEXA */
1510 /***********************************************************************
1513 HRESULT WINAPI
PrintDlgExW(LPVOID lpPrintDlgExW
) /* [???] FIXME: LPPRINTDLGEXW */