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
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
38 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
49 /* Yes these constants are the same, but we're just copying win98 */
50 #define UPDOWN_ID 0x270f
51 #define MAX_COPIES 9999
54 static const struct pd_flags psd_flags
[] = {
55 {PSD_MINMARGINS
,"PSD_MINMARGINS"},
56 {PSD_MARGINS
,"PSD_MARGINS"},
57 {PSD_INTHOUSANDTHSOFINCHES
,"PSD_INTHOUSANDTHSOFINCHES"},
58 {PSD_INHUNDREDTHSOFMILLIMETERS
,"PSD_INHUNDREDTHSOFMILLIMETERS"},
59 {PSD_DISABLEMARGINS
,"PSD_DISABLEMARGINS"},
60 {PSD_DISABLEPRINTER
,"PSD_DISABLEPRINTER"},
61 {PSD_NOWARNING
,"PSD_NOWARNING"},
62 {PSD_DISABLEORIENTATION
,"PSD_DISABLEORIENTATION"},
63 {PSD_RETURNDEFAULT
,"PSD_RETURNDEFAULT"},
64 {PSD_DISABLEPAPER
,"PSD_DISABLEPAPER"},
65 {PSD_SHOWHELP
,"PSD_SHOWHELP"},
66 {PSD_ENABLEPAGESETUPHOOK
,"PSD_ENABLEPAGESETUPHOOK"},
67 {PSD_ENABLEPAGESETUPTEMPLATE
,"PSD_ENABLEPAGESETUPTEMPLATE"},
68 {PSD_ENABLEPAGESETUPTEMPLATEHANDLE
,"PSD_ENABLEPAGESETUPTEMPLATEHANDLE"},
69 {PSD_ENABLEPAGEPAINTHOOK
,"PSD_ENABLEPAGEPAINTHOOK"},
70 {PSD_DISABLEPAGEPAINTING
,"PSD_DISABLEPAGEPAINTING"},
74 /* address of wndproc for subclassed Static control */
75 static WNDPROC lpfnStaticWndProc
;
76 /* the text of the fake document to render for the Page Setup dialog */
77 static WCHAR wszFakeDocumentText
[1024];
79 /***********************************************************************
80 * PRINTDLG_OpenDefaultPrinter
82 * Returns a winspool printer handle to the default printer in *hprn
83 * Caller must call ClosePrinter on the handle
85 * Returns TRUE on success else FALSE
87 BOOL
PRINTDLG_OpenDefaultPrinter(HANDLE
*hprn
)
90 DWORD dwBufLen
= sizeof(buf
) / sizeof(buf
[0]);
92 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
94 res
= OpenPrinterW(buf
, hprn
, NULL
);
96 WARN("Could not open printer %s\n", debugstr_w(buf
));
100 /***********************************************************************
101 * PRINTDLG_SetUpPrinterListCombo
103 * Initializes printer list combox.
104 * hDlg: HWND of dialog
105 * id: Control id of combo
106 * name: Name of printer to select
108 * Initializes combo with list of available printers. Selects printer 'name'
109 * If name is NULL or does not exist select the default printer.
111 * Returns number of printers added to list.
113 INT
PRINTDLG_SetUpPrinterListComboA(HWND hDlg
, UINT id
, LPCSTR name
)
117 LPPRINTER_INFO_2A pi
;
118 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
119 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
120 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
123 SendDlgItemMessageA(hDlg
, id
, CB_RESETCONTENT
, 0, 0);
125 for(i
= 0; i
< num
; i
++) {
126 SendDlgItemMessageA(hDlg
, id
, CB_ADDSTRING
, 0,
127 (LPARAM
)pi
[i
].pPrinterName
);
129 HeapFree(GetProcessHeap(), 0, pi
);
131 (i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
132 (LPARAM
)name
)) == CB_ERR
) {
135 DWORD dwBufLen
= sizeof(buf
);
137 WARN("Can't find %s in printer list so trying to find default\n",
139 if(!GetDefaultPrinterA(buf
, &dwBufLen
))
141 i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
143 FIXME("Can't find default printer in printer list\n");
145 SendDlgItemMessageA(hDlg
, id
, CB_SETCURSEL
, i
, 0);
149 static INT
PRINTDLG_SetUpPrinterListComboW(HWND hDlg
, UINT id
, LPCWSTR name
)
153 LPPRINTER_INFO_2W pi
;
154 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
155 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
156 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
159 for(i
= 0; i
< num
; i
++) {
160 SendDlgItemMessageW(hDlg
, id
, CB_ADDSTRING
, 0,
161 (LPARAM
)pi
[i
].pPrinterName
);
163 HeapFree(GetProcessHeap(), 0, pi
);
165 (i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
166 (LPARAM
)name
)) == CB_ERR
) {
168 DWORD dwBufLen
= sizeof(buf
)/sizeof(buf
[0]);
170 WARN("Can't find %s in printer list so trying to find default\n",
172 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
174 i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
176 TRACE("Can't find default printer in printer list\n");
178 SendDlgItemMessageW(hDlg
, id
, CB_SETCURSEL
, i
, 0);
182 /***********************************************************************
183 * PRINTDLG_CreateDevNames [internal]
186 * creates a DevNames structure.
188 * (NB. when we handle unicode the offsets will be in wchars).
190 static BOOL
PRINTDLG_CreateDevNames(HGLOBAL
*hmem
, const char* DeviceDriverName
,
191 const char* DeviceName
, const char* OutputPort
)
194 char* pDevNamesSpace
;
196 LPDEVNAMES lpDevNames
;
198 DWORD dwBufLen
= sizeof(buf
);
200 size
= strlen(DeviceDriverName
) + 1
201 + strlen(DeviceName
) + 1
202 + strlen(OutputPort
) + 1
206 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
208 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
212 pDevNamesSpace
= GlobalLock(*hmem
);
213 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
215 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
216 strcpy(pTempPtr
, DeviceDriverName
);
217 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
219 pTempPtr
+= strlen(DeviceDriverName
) + 1;
220 strcpy(pTempPtr
, DeviceName
);
221 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
223 pTempPtr
+= strlen(DeviceName
) + 1;
224 strcpy(pTempPtr
, OutputPort
);
225 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
227 GetDefaultPrinterA(buf
, &dwBufLen
);
228 lpDevNames
->wDefault
= (strcmp(buf
, DeviceName
) == 0) ? 1 : 0;
233 static BOOL
PRINTDLG_CreateDevNamesW(HGLOBAL
*hmem
, LPCWSTR DeviceDriverName
,
234 LPCWSTR DeviceName
, LPCWSTR OutputPort
)
237 LPWSTR pDevNamesSpace
;
239 LPDEVNAMES lpDevNames
;
241 DWORD dwBufLen
= sizeof(bufW
) / sizeof(WCHAR
);
243 size
= sizeof(WCHAR
)*lstrlenW(DeviceDriverName
) + 2
244 + sizeof(WCHAR
)*lstrlenW(DeviceName
) + 2
245 + sizeof(WCHAR
)*lstrlenW(OutputPort
) + 2
249 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
251 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
255 pDevNamesSpace
= GlobalLock(*hmem
);
256 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
258 pTempPtr
= (LPWSTR
)((LPDEVNAMES
)pDevNamesSpace
+ 1);
259 lstrcpyW(pTempPtr
, DeviceDriverName
);
260 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
262 pTempPtr
+= lstrlenW(DeviceDriverName
) + 1;
263 lstrcpyW(pTempPtr
, DeviceName
);
264 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
266 pTempPtr
+= lstrlenW(DeviceName
) + 1;
267 lstrcpyW(pTempPtr
, OutputPort
);
268 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
270 GetDefaultPrinterW(bufW
, &dwBufLen
);
271 lpDevNames
->wDefault
= (lstrcmpW(bufW
, DeviceName
) == 0) ? 1 : 0;
276 /***********************************************************************
277 * PRINTDLG_UpdatePrintDlg [internal]
280 * updates the PrintDlg structure for return values.
283 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
284 * TRUE if successful.
286 static BOOL
PRINTDLG_UpdatePrintDlgA(HWND hDlg
,
287 PRINT_PTRA
* PrintStructures
)
289 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
290 PDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
291 LPPRINTER_INFO_2A pi
= PrintStructures
->lpPrinterInfo
;
295 FIXME("No lpdm ptr?\n");
300 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
301 /* check whether nFromPage and nToPage are within range defined by
302 * nMinPage and nMaxPage
304 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
307 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
308 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
309 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
310 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
311 WCHAR resourcestr
[256];
312 WCHAR resultstr
[256];
313 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
, resourcestr
, 255);
314 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
315 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
, resourcestr
, 255);
316 MessageBoxW(hDlg
, resultstr
, resourcestr
, MB_OK
| MB_ICONWARNING
);
319 lppd
->nFromPage
= nFromPage
;
320 lppd
->nToPage
= nToPage
;
321 lppd
->Flags
|= PD_PAGENUMS
;
324 lppd
->Flags
&= ~PD_PAGENUMS
;
326 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
327 lppd
->Flags
|= PD_SELECTION
;
329 lppd
->Flags
&= ~PD_SELECTION
;
331 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
332 static char file
[] = "FILE:";
333 lppd
->Flags
|= PD_PRINTTOFILE
;
334 pi
->pPortName
= file
;
337 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
338 FIXME("Collate lppd not yet implemented as output\n");
341 /* set PD_Collate and nCopies */
342 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
343 /* The application doesn't support multiple copies or collate...
345 lppd
->Flags
&= ~PD_COLLATE
;
347 /* if the printer driver supports it... store info there
348 * otherwise no collate & multiple copies !
350 if (lpdm
->dmFields
& DM_COLLATE
)
352 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
353 if (lpdm
->dmFields
& DM_COPIES
)
354 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
356 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
357 lppd
->Flags
|= PD_COLLATE
;
359 lppd
->Flags
&= ~PD_COLLATE
;
360 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
363 /* Print quality, PrintDlg16 */
364 if(GetDlgItem(hDlg
, cmb1
))
366 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
367 int Sel
= SendMessageA(hQuality
, CB_GETCURSEL
, 0, 0);
371 LONG dpi
= SendMessageA(hQuality
, CB_GETITEMDATA
, Sel
, 0);
372 lpdm
->dmFields
|= DM_PRINTQUALITY
| DM_YRESOLUTION
;
373 lpdm
->u1
.s1
.dmPrintQuality
= LOWORD(dpi
);
374 lpdm
->dmYResolution
= HIWORD(dpi
);
381 static BOOL
PRINTDLG_UpdatePrintDlgW(HWND hDlg
,
382 PRINT_PTRW
* PrintStructures
)
384 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
385 PDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
386 LPPRINTER_INFO_2W pi
= PrintStructures
->lpPrinterInfo
;
390 FIXME("No lpdm ptr?\n");
395 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
396 /* check whether nFromPage and nToPage are within range defined by
397 * nMinPage and nMaxPage
399 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
402 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
403 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
404 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
405 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
406 WCHAR resourcestr
[256];
407 WCHAR resultstr
[256];
408 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
410 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
411 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
413 MessageBoxW(hDlg
, resultstr
, resourcestr
,
414 MB_OK
| MB_ICONWARNING
);
417 lppd
->nFromPage
= nFromPage
;
418 lppd
->nToPage
= nToPage
;
419 lppd
->Flags
|= PD_PAGENUMS
;
422 lppd
->Flags
&= ~PD_PAGENUMS
;
424 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
425 lppd
->Flags
|= PD_SELECTION
;
427 lppd
->Flags
&= ~PD_SELECTION
;
429 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
430 static WCHAR file
[] = {'F','I','L','E',':',0};
431 lppd
->Flags
|= PD_PRINTTOFILE
;
432 pi
->pPortName
= file
;
435 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
436 FIXME("Collate lppd not yet implemented as output\n");
439 /* set PD_Collate and nCopies */
440 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
441 /* The application doesn't support multiple copies or collate...
443 lppd
->Flags
&= ~PD_COLLATE
;
445 /* if the printer driver supports it... store info there
446 * otherwise no collate & multiple copies !
448 if (lpdm
->dmFields
& DM_COLLATE
)
450 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
451 if (lpdm
->dmFields
& DM_COPIES
)
452 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
454 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
455 lppd
->Flags
|= PD_COLLATE
;
457 lppd
->Flags
&= ~PD_COLLATE
;
458 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
464 static BOOL
PRINTDLG_PaperSizeA(
465 PRINTDLGA
*pdlga
,const WORD PaperSize
,LPPOINT size
469 LPSTR devname
,portname
;
473 POINT
*points
= NULL
;
476 dn
= GlobalLock(pdlga
->hDevNames
);
477 dm
= GlobalLock(pdlga
->hDevMode
);
478 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
479 portname
= ((char*)dn
)+dn
->wOutputOffset
;
482 NrOfEntries
= DeviceCapabilitiesA(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
484 FIXME("No papernames found for %s/%s\n",devname
,portname
);
487 if (NrOfEntries
== -1) {
488 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
492 Words
= HeapAlloc(GetProcessHeap(),0,NrOfEntries
*sizeof(WORD
));
493 if (NrOfEntries
!= (ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERS
,(LPSTR
)Words
,dm
))) {
494 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
497 for (i
=0;i
<NrOfEntries
;i
++)
498 if (Words
[i
] == PaperSize
)
500 if (i
== NrOfEntries
) {
501 FIXME("Papersize %d not found in list?\n",PaperSize
);
504 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
505 if (NrOfEntries
!=(ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERSIZE
,(LPSTR
)points
,dm
))) {
506 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
509 /* this is _10ths_ of a millimeter */
514 GlobalUnlock(pdlga
->hDevNames
);
515 GlobalUnlock(pdlga
->hDevMode
);
516 HeapFree(GetProcessHeap(),0,Words
);
517 HeapFree(GetProcessHeap(),0,points
);
521 static BOOL
PRINTDLG_PaperSizeW(
522 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
526 LPWSTR devname
,portname
;
530 POINT
*points
= NULL
;
533 dn
= GlobalLock(pdlga
->hDevNames
);
534 dm
= GlobalLock(pdlga
->hDevMode
);
535 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
536 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
539 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
541 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
544 if (NrOfEntries
== -1) {
545 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
549 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
550 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
551 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
554 for (i
=0;i
<NrOfEntries
;i
++)
555 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
557 if (i
==NrOfEntries
) {
558 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
561 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
562 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
563 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
566 /* this is _10ths_ of a millimeter */
571 GlobalUnlock(pdlga
->hDevNames
);
572 GlobalUnlock(pdlga
->hDevMode
);
573 HeapFree(GetProcessHeap(),0,Names
);
574 HeapFree(GetProcessHeap(),0,points
);
579 /************************************************************************
580 * PRINTDLG_SetUpPaperComboBox
582 * Initialize either the papersize or inputslot combos of the Printer Setup
583 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
584 * We also try to re-select the old selection.
586 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
599 int fwCapability_Names
;
600 int fwCapability_Words
;
602 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
604 /* query the dialog box for the current selected value */
605 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
607 /* we enter here only if a different printer is selected after
608 * the Print Setup dialog is opened. The current settings are
609 * stored into the newly selected printer.
611 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
614 if (nIDComboBox
== cmb2
)
615 dm
->u1
.s1
.dmPaperSize
= oldWord
;
617 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
621 /* we enter here only when the Print setup dialog is initially
622 * opened. In this case the settings are restored from when
623 * the dialog was last closed.
626 if (nIDComboBox
== cmb2
)
627 oldWord
= dm
->u1
.s1
.dmPaperSize
;
629 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
633 if (nIDComboBox
== cmb2
) {
635 fwCapability_Names
= DC_PAPERNAMES
;
636 fwCapability_Words
= DC_PAPERS
;
640 fwCapability_Names
= DC_BINNAMES
;
641 fwCapability_Words
= DC_BINS
;
644 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
645 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
647 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
648 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
649 fwCapability_Names
, NULL
, dm
);
650 if (NrOfEntries
== 0)
651 WARN("no Name Entries found!\n");
652 else if (NrOfEntries
< 0)
655 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
657 ERR("Number of caps is different\n");
661 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
662 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
663 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
664 fwCapability_Names
, Names
, dm
);
665 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
666 fwCapability_Words
, (LPSTR
)Words
, dm
);
668 /* reset any current content in the combobox */
669 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
671 /* store new content */
672 for (i
= 0; i
< NrOfEntries
; i
++) {
673 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
674 (LPARAM
)(&Names
[i
*NamesSize
]) );
675 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
679 /* Look for old selection - can't do this is previous loop since
680 item order will change as more items are added */
682 for (i
= 0; i
< NrOfEntries
; i
++) {
683 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
689 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
691 HeapFree(GetProcessHeap(),0,Words
);
692 HeapFree(GetProcessHeap(),0,Names
);
696 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
698 const WCHAR
* PrinterName
,
699 const WCHAR
* PortName
,
709 int fwCapability_Names
;
710 int fwCapability_Words
;
712 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
714 /* query the dialog box for the current selected value */
715 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
717 /* we enter here only if a different printer is selected after
718 * the Print Setup dialog is opened. The current settings are
719 * stored into the newly selected printer.
721 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
724 if (nIDComboBox
== cmb2
)
725 dm
->u1
.s1
.dmPaperSize
= oldWord
;
727 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
731 /* we enter here only when the Print setup dialog is initially
732 * opened. In this case the settings are restored from when
733 * the dialog was last closed.
736 if (nIDComboBox
== cmb2
)
737 oldWord
= dm
->u1
.s1
.dmPaperSize
;
739 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
743 if (nIDComboBox
== cmb2
) {
745 fwCapability_Names
= DC_PAPERNAMES
;
746 fwCapability_Words
= DC_PAPERS
;
750 fwCapability_Names
= DC_BINNAMES
;
751 fwCapability_Words
= DC_BINS
;
754 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
755 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
757 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
758 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
759 fwCapability_Names
, NULL
, dm
);
760 if (NrOfEntries
== 0)
761 WARN("no Name Entries found!\n");
762 else if (NrOfEntries
< 0)
765 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
767 ERR("Number of caps is different\n");
771 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
772 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
773 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
774 fwCapability_Names
, Names
, dm
);
775 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
776 fwCapability_Words
, (LPWSTR
)Words
, dm
);
778 /* reset any current content in the combobox */
779 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
781 /* store new content */
782 for (i
= 0; i
< NrOfEntries
; i
++) {
783 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
784 (LPARAM
)(&Names
[i
*NamesSize
]) );
785 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
789 /* Look for old selection - can't do this is previous loop since
790 item order will change as more items are added */
792 for (i
= 0; i
< NrOfEntries
; i
++) {
793 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
799 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
801 HeapFree(GetProcessHeap(),0,Words
);
802 HeapFree(GetProcessHeap(),0,Names
);
807 /***********************************************************************
808 * PRINTDLG_UpdatePrinterInfoTexts [internal]
810 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
813 char ResourceString
[256];
819 /* add all status messages */
820 for (i
= 0; i
< 25; i
++) {
821 if (pi
->Status
& (1<<i
)) {
822 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
823 ResourceString
, 255);
824 strcat(StatusMsg
,ResourceString
);
828 /* FIXME: status==ready must only be appended if really so.
829 but how to detect? */
830 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
831 ResourceString
, 255);
832 strcat(StatusMsg
,ResourceString
);
833 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
835 /* set all other printer info texts */
836 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
838 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
839 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
841 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
842 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
846 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
848 WCHAR StatusMsg
[256];
849 WCHAR ResourceString
[256];
850 static const WCHAR emptyW
[] = {0};
856 /* add all status messages */
857 for (i
= 0; i
< 25; i
++) {
858 if (pi
->Status
& (1<<i
)) {
859 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
860 ResourceString
, 255);
861 lstrcatW(StatusMsg
,ResourceString
);
865 /* FIXME: status==ready must only be appended if really so.
866 but how to detect? */
867 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
868 ResourceString
, 255);
869 lstrcatW(StatusMsg
,ResourceString
);
870 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
872 /* set all other printer info texts */
873 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
874 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
875 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
877 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
878 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
882 /*******************************************************************
884 * PRINTDLG_ChangePrinter
887 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
888 PRINT_PTRA
*PrintStructures
)
890 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
891 LPDEVMODEA lpdm
= NULL
;
896 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
897 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
898 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
899 ERR("Can't open printer %s\n", name
);
902 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
903 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
904 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
906 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
907 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
908 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
910 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
915 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
917 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
918 PrintStructures
->lpDevMode
= NULL
;
920 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
922 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
925 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
926 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
928 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
929 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
930 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
931 /* Supplied devicemode matches current printer so try to use it */
932 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
933 DM_OUT_BUFFER
| DM_IN_BUFFER
);
936 GlobalUnlock(lppd
->hDevMode
);
938 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
940 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
941 /* Print range (All/Range/Selection) */
942 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
943 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
944 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
945 if (lppd
->Flags
& PD_NOSELECTION
)
946 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
948 if (lppd
->Flags
& PD_SELECTION
)
949 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
950 if (lppd
->Flags
& PD_NOPAGENUMS
) {
951 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
952 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
953 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
954 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
955 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
957 if (lppd
->Flags
& PD_PAGENUMS
)
958 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
963 * FIXME: The ico3 is not displayed for some reason. I don't know why.
965 if (lppd
->Flags
& PD_COLLATE
) {
966 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
967 (LPARAM
)PrintStructures
->hCollateIcon
);
968 CheckDlgButton(hDlg
, chx2
, 1);
970 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
971 (LPARAM
)PrintStructures
->hNoCollateIcon
);
972 CheckDlgButton(hDlg
, chx2
, 0);
975 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
976 /* if printer doesn't support it: no Collate */
977 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
978 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
979 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
986 if (lppd
->hDevMode
== 0)
987 copies
= lppd
->nCopies
;
989 copies
= lpdm
->u1
.s1
.dmCopies
;
990 if(copies
== 0) copies
= 1;
991 else if(copies
< 0) copies
= MAX_COPIES
;
992 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
995 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
996 /* if printer doesn't support it: no nCopies */
997 if (!(lpdm
->dmFields
& DM_COPIES
)) {
998 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
999 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1004 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1005 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1006 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1007 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1008 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1010 /* Fill print quality combo, PrintDlg16 */
1011 if(GetDlgItem(hDlg
, cmb1
))
1013 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1014 PrintStructures
->lpPrinterInfo
->pPortName
,
1015 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
1017 if(numResolutions
!= -1)
1019 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
1024 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
1025 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1028 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
1029 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1030 PrintStructures
->lpPrinterInfo
->pPortName
,
1031 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
1033 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1034 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1035 DeleteDC(hPrinterDC
);
1037 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1038 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1040 BOOL IsDefault
= FALSE
;
1043 if(Resolutions
[i
] == Resolutions
[i
+1])
1045 if(dpiX
== Resolutions
[i
])
1047 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1050 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1052 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1055 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1058 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1060 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1062 HeapFree(GetProcessHeap(), 0, Resolutions
);
1065 } else { /* PD_PRINTSETUP */
1066 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1068 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1069 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1070 PrintStructures
->lpPrinterInfo
->pPortName
,
1072 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1073 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1074 PrintStructures
->lpPrinterInfo
->pPortName
,
1076 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1077 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1078 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1079 PrintStructures
->hLandscapeIcon
));
1084 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1085 /* hide if PD_SHOWHELP not specified */
1086 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1091 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1092 PRINT_PTRW
*PrintStructures
)
1094 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1095 LPDEVMODEW lpdm
= NULL
;
1100 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1101 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1102 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1103 ERR("Can't open printer %s\n", debugstr_w(name
));
1106 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1107 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1108 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1110 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1111 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1112 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1114 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1119 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1121 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1122 PrintStructures
->lpDevMode
= NULL
;
1124 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1126 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1129 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1130 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1132 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1133 !lstrcmpW(lpdm
->dmDeviceName
,
1134 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1135 /* Supplied devicemode matches current printer so try to use it */
1136 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1137 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1140 GlobalUnlock(lppd
->hDevMode
);
1142 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1144 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1145 /* Print range (All/Range/Selection) */
1146 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1147 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1148 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1149 if (lppd
->Flags
& PD_NOSELECTION
)
1150 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1152 if (lppd
->Flags
& PD_SELECTION
)
1153 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1154 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1155 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1156 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1157 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1158 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1159 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1161 if (lppd
->Flags
& PD_PAGENUMS
)
1162 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1167 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1169 if (lppd
->Flags
& PD_COLLATE
) {
1170 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1171 (LPARAM
)PrintStructures
->hCollateIcon
);
1172 CheckDlgButton(hDlg
, chx2
, 1);
1174 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1175 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1176 CheckDlgButton(hDlg
, chx2
, 0);
1179 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1180 /* if printer doesn't support it: no Collate */
1181 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1182 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1183 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1190 if (lppd
->hDevMode
== 0)
1191 copies
= lppd
->nCopies
;
1193 copies
= lpdm
->u1
.s1
.dmCopies
;
1194 if(copies
== 0) copies
= 1;
1195 else if(copies
< 0) copies
= MAX_COPIES
;
1196 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1199 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1200 /* if printer doesn't support it: no nCopies */
1201 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1202 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1203 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1208 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1209 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1210 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1211 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1212 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1214 } else { /* PD_PRINTSETUP */
1215 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1217 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1218 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1219 PrintStructures
->lpPrinterInfo
->pPortName
,
1221 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1222 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1223 PrintStructures
->lpPrinterInfo
->pPortName
,
1225 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1226 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1227 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1228 PrintStructures
->hLandscapeIcon
));
1233 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1234 /* hide if PD_SHOWHELP not specified */
1235 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1240 /***********************************************************************
1241 * check_printer_setup [internal]
1243 static LRESULT
check_printer_setup(HWND hDlg
)
1246 WCHAR resourcestr
[256],resultstr
[256];
1249 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1252 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1258 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1259 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1260 res
= MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1265 /***********************************************************************
1266 * PRINTDLG_WMInitDialog [internal]
1268 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1269 PRINT_PTRA
* PrintStructures
)
1271 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1275 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1277 /* load Collate ICONs */
1278 /* We load these with LoadImage because they are not a standard
1279 size and we don't want them rescaled */
1280 PrintStructures
->hCollateIcon
=
1281 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1282 PrintStructures
->hNoCollateIcon
=
1283 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1285 /* These can be done with LoadIcon */
1286 PrintStructures
->hPortraitIcon
=
1287 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1288 PrintStructures
->hLandscapeIcon
=
1289 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1291 /* display the collate/no_collate icon */
1292 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1293 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1295 if(PrintStructures
->hCollateIcon
== 0 ||
1296 PrintStructures
->hNoCollateIcon
== 0 ||
1297 PrintStructures
->hPortraitIcon
== 0 ||
1298 PrintStructures
->hLandscapeIcon
== 0) {
1299 ERR("no icon in resourcefile\n");
1300 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1301 EndDialog(hDlg
, FALSE
);
1305 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1306 * must be registered and the Help button must be shown.
1308 if (lppd
->Flags
& PD_SHOWHELP
) {
1309 if((PrintStructures
->HelpMessageID
=
1310 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1311 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1315 PrintStructures
->HelpMessageID
= 0;
1317 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1318 PrintStructures
->hwndUpDown
=
1319 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1320 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1321 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1322 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1323 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1326 /* FIXME: I allow more freedom than either Win95 or WinNT,
1327 * which do not agree to what errors should be thrown or not
1328 * in case nToPage or nFromPage is out-of-range.
1330 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1331 lppd
->nMaxPage
= lppd
->nMinPage
;
1332 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1333 lppd
->Flags
|= PD_NOPAGENUMS
;
1334 if (lppd
->nToPage
< lppd
->nMinPage
)
1335 lppd
->nToPage
= lppd
->nMinPage
;
1336 if (lppd
->nToPage
> lppd
->nMaxPage
)
1337 lppd
->nToPage
= lppd
->nMaxPage
;
1338 if (lppd
->nFromPage
< lppd
->nMinPage
)
1339 lppd
->nFromPage
= lppd
->nMinPage
;
1340 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1341 lppd
->nFromPage
= lppd
->nMaxPage
;
1343 /* if we have the combo box, fill it */
1344 if (GetDlgItem(hDlg
,comboID
)) {
1347 pdn
= GlobalLock(lppd
->hDevNames
);
1348 pdm
= GlobalLock(lppd
->hDevMode
);
1350 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1352 name
= (char*)pdm
->dmDeviceName
;
1353 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1354 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1355 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1357 /* Now find selected printer and update rest of dlg */
1358 name
= HeapAlloc(GetProcessHeap(),0,256);
1359 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1360 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1361 HeapFree(GetProcessHeap(),0,name
);
1363 /* else use default printer */
1365 DWORD dwBufLen
= sizeof(name
);
1366 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1369 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1371 FIXME("No default printer found, expect problems!\n");
1376 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1377 PRINT_PTRW
* PrintStructures
)
1379 static const WCHAR PD32_COLLATE
[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
1380 static const WCHAR PD32_NOCOLLATE
[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
1381 static const WCHAR PD32_PORTRAIT
[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
1382 static const WCHAR PD32_LANDSCAPE
[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
1383 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1387 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1389 /* load Collate ICONs */
1390 /* We load these with LoadImage because they are not a standard
1391 size and we don't want them rescaled */
1392 PrintStructures
->hCollateIcon
=
1393 LoadImageW(COMDLG32_hInstance
, PD32_COLLATE
, IMAGE_ICON
, 0, 0, 0);
1394 PrintStructures
->hNoCollateIcon
=
1395 LoadImageW(COMDLG32_hInstance
, PD32_NOCOLLATE
, IMAGE_ICON
, 0, 0, 0);
1397 /* These can be done with LoadIcon */
1398 PrintStructures
->hPortraitIcon
=
1399 LoadIconW(COMDLG32_hInstance
, PD32_PORTRAIT
);
1400 PrintStructures
->hLandscapeIcon
=
1401 LoadIconW(COMDLG32_hInstance
, PD32_LANDSCAPE
);
1403 /* display the collate/no_collate icon */
1404 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1405 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1407 if(PrintStructures
->hCollateIcon
== 0 ||
1408 PrintStructures
->hNoCollateIcon
== 0 ||
1409 PrintStructures
->hPortraitIcon
== 0 ||
1410 PrintStructures
->hLandscapeIcon
== 0) {
1411 ERR("no icon in resourcefile\n");
1412 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1413 EndDialog(hDlg
, FALSE
);
1417 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1418 * must be registered and the Help button must be shown.
1420 if (lppd
->Flags
& PD_SHOWHELP
) {
1421 if((PrintStructures
->HelpMessageID
=
1422 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1423 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1427 PrintStructures
->HelpMessageID
= 0;
1429 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1430 PrintStructures
->hwndUpDown
=
1431 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1432 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1433 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1434 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1435 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1438 /* FIXME: I allow more freedom than either Win95 or WinNT,
1439 * which do not agree to what errors should be thrown or not
1440 * in case nToPage or nFromPage is out-of-range.
1442 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1443 lppd
->nMaxPage
= lppd
->nMinPage
;
1444 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1445 lppd
->Flags
|= PD_NOPAGENUMS
;
1446 if (lppd
->nToPage
< lppd
->nMinPage
)
1447 lppd
->nToPage
= lppd
->nMinPage
;
1448 if (lppd
->nToPage
> lppd
->nMaxPage
)
1449 lppd
->nToPage
= lppd
->nMaxPage
;
1450 if (lppd
->nFromPage
< lppd
->nMinPage
)
1451 lppd
->nFromPage
= lppd
->nMinPage
;
1452 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1453 lppd
->nFromPage
= lppd
->nMaxPage
;
1455 /* if we have the combo box, fill it */
1456 if (GetDlgItem(hDlg
,comboID
)) {
1459 pdn
= GlobalLock(lppd
->hDevNames
);
1460 pdm
= GlobalLock(lppd
->hDevMode
);
1462 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1464 name
= pdm
->dmDeviceName
;
1465 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1466 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1467 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1469 /* Now find selected printer and update rest of dlg */
1470 /* ansi is ok here */
1471 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1472 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1473 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1474 HeapFree(GetProcessHeap(),0,name
);
1476 /* else use default printer */
1478 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1479 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1482 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1484 FIXME("No default printer found, expect problems!\n");
1489 /***********************************************************************
1490 * PRINTDLG_WMCommand [internal]
1492 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1493 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1495 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1496 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1497 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1499 switch (LOWORD(wParam
)) {
1501 TRACE(" OK button was hit\n");
1502 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1503 FIXME("Update printdlg was not successful!\n");
1506 EndDialog(hDlg
, TRUE
);
1510 TRACE(" CANCEL button was hit\n");
1511 EndDialog(hDlg
, FALSE
);
1515 TRACE(" HELP button was hit\n");
1516 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1517 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1520 case chx2
: /* collate pages checkbox */
1521 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1522 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1523 (LPARAM
)PrintStructures
->hCollateIcon
);
1525 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1526 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1528 case edt1
: /* from page nr editbox */
1529 case edt2
: /* to page nr editbox */
1530 if (HIWORD(wParam
)==EN_CHANGE
) {
1533 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1534 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1535 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1536 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1541 if(HIWORD(wParam
) == EN_CHANGE
) {
1542 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1544 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1546 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1551 case psh1
: /* Print Setup */
1555 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1556 FIXME("The 32bit print dialog does not have this button!?\n");
1560 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1561 pdlg
.Flags
|= PD_PRINTSETUP
;
1562 pdlg
.hwndOwner
= HWND_16(hDlg
);
1563 if (!PrintDlg16(&pdlg
))
1568 case psh2
: /* Properties button */
1571 char PrinterName
[256];
1573 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1574 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1575 FIXME(" Call to OpenPrinter did not succeed!\n");
1578 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1579 PrintStructures
->lpDevMode
,
1580 PrintStructures
->lpDevMode
,
1581 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1582 ClosePrinter(hPrinter
);
1586 case rad1
: /* Paperorientation */
1587 if (lppd
->Flags
& PD_PRINTSETUP
)
1589 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1590 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1591 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1595 case rad2
: /* Paperorientation */
1596 if (lppd
->Flags
& PD_PRINTSETUP
)
1598 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1599 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1600 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1604 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1605 if (PrinterComboID
!= LOWORD(wParam
)) {
1609 case cmb4
: /* Printer combobox */
1610 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1611 char PrinterName
[256];
1612 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1613 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1617 case cmb2
: /* Papersize */
1619 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1621 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1627 case cmb3
: /* Bin */
1629 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1631 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1632 CB_GETITEMDATA
, Sel
,
1637 if(lppd
->Flags
& PD_PRINTSETUP
) {
1638 switch (LOWORD(wParam
)) {
1639 case rad1
: /* orientation */
1641 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1642 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1643 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1644 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1646 (LPARAM
)PrintStructures
->hPortraitIcon
);
1647 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1649 (LPARAM
)PrintStructures
->hPortraitIcon
);
1652 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1653 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1654 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1656 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1657 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1659 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1668 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1669 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1671 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1672 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1673 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1675 switch (LOWORD(wParam
)) {
1677 TRACE(" OK button was hit\n");
1678 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1679 FIXME("Update printdlg was not successful!\n");
1682 EndDialog(hDlg
, TRUE
);
1686 TRACE(" CANCEL button was hit\n");
1687 EndDialog(hDlg
, FALSE
);
1691 TRACE(" HELP button was hit\n");
1692 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1693 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1696 case chx2
: /* collate pages checkbox */
1697 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1698 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1699 (LPARAM
)PrintStructures
->hCollateIcon
);
1701 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1702 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1704 case edt1
: /* from page nr editbox */
1705 case edt2
: /* to page nr editbox */
1706 if (HIWORD(wParam
)==EN_CHANGE
) {
1709 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1710 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1711 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1712 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1717 if(HIWORD(wParam
) == EN_CHANGE
) {
1718 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1720 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1722 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1726 case psh1
: /* Print Setup */
1728 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1731 case psh2
: /* Properties button */
1734 WCHAR PrinterName
[256];
1736 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1737 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1738 FIXME(" Call to OpenPrinter did not succeed!\n");
1741 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1742 PrintStructures
->lpDevMode
,
1743 PrintStructures
->lpDevMode
,
1744 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1745 ClosePrinter(hPrinter
);
1749 case rad1
: /* Paperorientation */
1750 if (lppd
->Flags
& PD_PRINTSETUP
)
1752 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1753 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1754 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1758 case rad2
: /* Paperorientation */
1759 if (lppd
->Flags
& PD_PRINTSETUP
)
1761 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1762 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1763 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1767 case cmb1
: /* Printer Combobox in PRINT SETUP */
1769 case cmb4
: /* Printer combobox */
1770 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1771 WCHAR PrinterName
[256];
1772 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1773 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1777 case cmb2
: /* Papersize */
1779 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1781 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1787 case cmb3
: /* Bin */
1789 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1791 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1792 CB_GETITEMDATA
, Sel
,
1797 if(lppd
->Flags
& PD_PRINTSETUP
) {
1798 switch (LOWORD(wParam
)) {
1799 case rad1
: /* orientation */
1801 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1802 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1803 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1804 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1806 (LPARAM
)PrintStructures
->hPortraitIcon
);
1807 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1809 (LPARAM
)PrintStructures
->hPortraitIcon
);
1812 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1813 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1814 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1816 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1817 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1819 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1828 /***********************************************************************
1829 * PrintDlgProcA [internal]
1831 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1834 PRINT_PTRA
* PrintStructures
;
1835 INT_PTR res
= FALSE
;
1837 if (uMsg
!=WM_INITDIALOG
) {
1838 PrintStructures
= (PRINT_PTRA
*)GetPropA(hDlg
,"__WINE_PRINTDLGDATA");
1839 if (!PrintStructures
)
1842 PrintStructures
= (PRINT_PTRA
*) lParam
;
1843 SetPropA(hDlg
,"__WINE_PRINTDLGDATA",PrintStructures
);
1844 if(!check_printer_setup(hDlg
))
1846 EndDialog(hDlg
,FALSE
);
1849 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1851 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1852 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1853 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1858 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1859 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1866 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1869 DestroyIcon(PrintStructures
->hCollateIcon
);
1870 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1871 DestroyIcon(PrintStructures
->hPortraitIcon
);
1872 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1873 if(PrintStructures
->hwndUpDown
)
1874 DestroyWindow(PrintStructures
->hwndUpDown
);
1880 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1883 static const WCHAR propW
[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
1884 PRINT_PTRW
* PrintStructures
;
1885 INT_PTR res
= FALSE
;
1887 if (uMsg
!=WM_INITDIALOG
) {
1888 PrintStructures
= (PRINT_PTRW
*) GetPropW(hDlg
, propW
);
1889 if (!PrintStructures
)
1892 PrintStructures
= (PRINT_PTRW
*) lParam
;
1893 SetPropW(hDlg
, propW
, PrintStructures
);
1894 if(!check_printer_setup(hDlg
))
1896 EndDialog(hDlg
,FALSE
);
1899 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1901 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1902 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1906 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1907 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1913 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1916 DestroyIcon(PrintStructures
->hCollateIcon
);
1917 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1918 DestroyIcon(PrintStructures
->hPortraitIcon
);
1919 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1920 if(PrintStructures
->hwndUpDown
)
1921 DestroyWindow(PrintStructures
->hwndUpDown
);
1927 /************************************************************
1929 * PRINTDLG_GetDlgTemplate
1932 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1937 if (lppd
->Flags
& PD_PRINTSETUP
) {
1938 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1939 hDlgTmpl
= lppd
->hSetupTemplate
;
1940 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1941 hResInfo
= FindResourceA(lppd
->hInstance
,
1942 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1943 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1945 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1947 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1950 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1951 hDlgTmpl
= lppd
->hPrintTemplate
;
1952 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1953 hResInfo
= FindResourceA(lppd
->hInstance
,
1954 lppd
->lpPrintTemplateName
,
1956 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1958 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1960 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1966 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1970 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1971 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1973 if (lppd
->Flags
& PD_PRINTSETUP
) {
1974 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1975 hDlgTmpl
= lppd
->hSetupTemplate
;
1976 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1977 hResInfo
= FindResourceW(lppd
->hInstance
,
1978 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1979 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1981 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
1982 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1985 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1986 hDlgTmpl
= lppd
->hPrintTemplate
;
1987 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1988 hResInfo
= FindResourceW(lppd
->hInstance
,
1989 lppd
->lpPrintTemplateName
,
1991 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1993 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
1994 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2000 /***********************************************************************
2005 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
2007 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2008 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
2010 if(lppd
->Flags
& PD_RETURNDC
) {
2011 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
2012 (char*)pdn
+ pdn
->wDeviceOffset
,
2013 (char*)pdn
+ pdn
->wOutputOffset
,
2015 } else if(lppd
->Flags
& PD_RETURNIC
) {
2016 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
2017 (char*)pdn
+ pdn
->wDeviceOffset
,
2018 (char*)pdn
+ pdn
->wOutputOffset
,
2021 GlobalUnlock(lppd
->hDevNames
);
2022 GlobalUnlock(lppd
->hDevMode
);
2023 return lppd
->hDC
? TRUE
: FALSE
;
2026 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
2028 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2029 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
2031 if(lppd
->Flags
& PD_RETURNDC
) {
2032 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2033 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2034 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2036 } else if(lppd
->Flags
& PD_RETURNIC
) {
2037 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2038 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2039 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2042 GlobalUnlock(lppd
->hDevNames
);
2043 GlobalUnlock(lppd
->hDevMode
);
2044 return lppd
->hDC
? TRUE
: FALSE
;
2047 /***********************************************************************
2048 * PrintDlgA (COMDLG32.@)
2050 * Displays the PRINT dialog box, which enables the user to specify
2051 * specific properties of the print job.
2054 * lppd [IO] ptr to PRINTDLG32 struct
2057 * nonzero if the user pressed the OK button
2058 * zero if the user cancelled the window or an error occurred
2062 * * The Collate Icons do not display, even though they are in the code.
2063 * * The Properties Button(s) should call DocumentPropertiesA().
2066 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2074 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2078 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2079 if(TRACE_ON(commdlg
)) {
2080 char flagstr
[1000] = "";
2081 const struct pd_flags
*pflag
= pd_flags
;
2082 for( ; pflag
->name
; pflag
++) {
2083 if(lppd
->Flags
& pflag
->flag
)
2084 strcat(flagstr
, pflag
->name
);
2086 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2087 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2088 "flags %08x (%s)\n",
2089 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2090 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2091 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2094 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2095 WARN("structure size failure !!!\n");
2096 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2100 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2101 PRINTER_INFO_2A
*pbuf
;
2102 DRIVER_INFO_3A
*dbuf
;
2106 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2107 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2108 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2111 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2112 WARN("Can't find default printer\n");
2113 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2117 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2118 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2119 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2121 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2122 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2123 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2124 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2125 GetLastError(),pbuf
->pPrinterName
);
2126 HeapFree(GetProcessHeap(), 0, dbuf
);
2127 HeapFree(GetProcessHeap(), 0, pbuf
);
2128 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2133 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2137 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2138 pbuf
->pDevMode
->dmDriverExtra
);
2139 ptr
= GlobalLock(lppd
->hDevMode
);
2140 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2141 pbuf
->pDevMode
->dmDriverExtra
);
2142 GlobalUnlock(lppd
->hDevMode
);
2143 HeapFree(GetProcessHeap(), 0, pbuf
);
2144 HeapFree(GetProcessHeap(), 0, dbuf
);
2148 PRINT_PTRA
*PrintStructures
;
2150 /* load Dialog resources,
2151 * depending on Flags indicates Print32 or Print32_setup dialog
2153 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2155 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2158 ptr
= LockResource( hDlgTmpl
);
2160 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2164 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2165 sizeof(PRINT_PTRA
));
2166 PrintStructures
->lpPrintDlg
= lppd
;
2168 /* and create & process the dialog .
2169 * -1 is failure, 0 is broken hwnd, everything else is ok.
2171 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2173 (LPARAM
)PrintStructures
));
2176 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2177 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2178 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2180 if (lppd
->hDevMode
== 0) {
2181 TRACE(" No hDevMode yet... Need to create my own\n");
2182 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2183 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2185 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2186 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2189 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2190 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2192 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2197 GlobalUnlock(lppd
->hDevMode
);
2199 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2200 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2201 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2202 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2204 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2205 bRet
= PRINTDLG_CreateDCA(lppd
);
2207 TRACE("exit! (%d)\n", bRet
);
2211 /***********************************************************************
2212 * PrintDlgW (COMDLG32.@)
2216 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2224 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2228 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2229 if(TRACE_ON(commdlg
)) {
2230 char flagstr
[1000] = "";
2231 const struct pd_flags
*pflag
= pd_flags
;
2232 for( ; pflag
->name
; pflag
++) {
2233 if(lppd
->Flags
& pflag
->flag
)
2234 strcat(flagstr
, pflag
->name
);
2236 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2237 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2238 "flags %08x (%s)\n",
2239 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2240 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2241 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2244 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2245 WARN("structure size failure !!!\n");
2246 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2250 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2251 PRINTER_INFO_2W
*pbuf
;
2252 DRIVER_INFO_3W
*dbuf
;
2256 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2257 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2258 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2261 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2262 WARN("Can't find default printer\n");
2263 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2267 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2268 pbuf
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*needed
);
2269 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2271 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2272 dbuf
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
2273 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2274 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2275 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2276 HeapFree(GetProcessHeap(), 0, dbuf
);
2277 HeapFree(GetProcessHeap(), 0, pbuf
);
2278 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2283 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2287 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2288 pbuf
->pDevMode
->dmDriverExtra
);
2289 ptr
= GlobalLock(lppd
->hDevMode
);
2290 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2291 pbuf
->pDevMode
->dmDriverExtra
);
2292 GlobalUnlock(lppd
->hDevMode
);
2293 HeapFree(GetProcessHeap(), 0, pbuf
);
2294 HeapFree(GetProcessHeap(), 0, dbuf
);
2298 PRINT_PTRW
*PrintStructures
;
2300 /* load Dialog resources,
2301 * depending on Flags indicates Print32 or Print32_setup dialog
2303 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2305 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2308 ptr
= LockResource( hDlgTmpl
);
2310 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2314 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2315 sizeof(PRINT_PTRW
));
2316 PrintStructures
->lpPrintDlg
= lppd
;
2318 /* and create & process the dialog .
2319 * -1 is failure, 0 is broken hwnd, everything else is ok.
2321 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2323 (LPARAM
)PrintStructures
));
2326 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2327 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2328 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2330 if (lppd
->hDevMode
== 0) {
2331 TRACE(" No hDevMode yet... Need to create my own\n");
2332 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2333 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2336 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2337 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2339 GlobalUnlock(lppd
->hDevMode
);
2340 TRACE("Now got %d locks\n", locks
);
2343 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2344 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2347 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2348 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2350 if (lppd
->hDevNames
!= 0) {
2352 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2353 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2355 GlobalUnlock(lppd
->hDevNames
);
2358 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2363 GlobalUnlock(lppd
->hDevMode
);
2365 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2366 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2367 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2368 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2370 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2371 bRet
= PRINTDLG_CreateDCW(lppd
);
2373 TRACE("exit! (%d)\n", bRet
);
2377 /***********************************************************************
2382 * cmb1 - printer select (not in standard dialog template)
2384 * cmb3 - source (tray?)
2385 * edt4 - border left
2387 * edt6 - border right
2388 * edt7 - border bottom
2389 * psh3 - "Printer..."
2393 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2395 HWND hDlg
; /* Page Setup dialog handler */
2396 PAGESETUPDLGA curdlg
; /* Stores the current dialog state */
2397 RECT rtDrawRect
; /* Drawing rect for page */
2401 LPPAGESETUPDLGW dlgw
;
2403 PAGESETUPDLGW curdlg
; /* Current dialog state */
2407 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2412 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2413 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2414 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2415 hResInfo
= FindResourceA(lppd
->hInstance
,
2416 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2417 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2419 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2420 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2425 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2430 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2431 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2432 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2433 hResInfo
= FindResourceW(lppd
->hInstance
,
2434 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2435 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2437 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2438 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2444 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2445 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2446 return 10*size
*100/254;
2447 /* If we don't have a flag, we can choose one. Use millimeters
2448 * to avoid confusing me
2450 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2456 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2457 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2459 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2460 return (size
*254)/100;
2461 /* if we don't have a flag, we can choose one. Use millimeters
2462 * to avoid confusing me
2464 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2465 return (size
*254)/100;
2469 _c_size2strA(PageSetupDataA
*pda
,DWORD size
,LPSTR strout
) {
2470 strcpy(strout
,"<undef>");
2471 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2472 sprintf(strout
,"%d",(size
)/100);
2475 if (pda
->dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2476 sprintf(strout
,"%din",(size
)/1000);
2479 pda
->dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2480 sprintf(strout
,"%d",(size
)/100);
2484 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2485 static const char mm_fmt
[] = "%.2f mm";
2486 static const char in_fmt
[] = "%.2f in";
2488 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2489 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2490 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2491 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2493 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2494 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2497 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2501 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2506 if (!sscanf(strin
,"%f%s",&val
,rest
))
2509 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2510 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2513 return val
*25.4*100;
2515 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2516 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2518 if (!strcmp(rest
,"mm")) {
2519 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2522 return 1000.0*val
/25.4;
2524 if (rest
[0]=='\0') {
2525 /* use application supplied default */
2526 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2530 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2535 ERR("Did not find a conversion for type '%s'!\n",rest
);
2541 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2544 /* this W -> A transition is OK */
2545 /* we need a unicode version of sscanf to avoid it */
2546 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2547 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2551 /****************************************************************************
2552 * PRINTDLG_PS_UpdateDlgStructA
2554 * Updates pda->dlga structure
2555 * Function calls when user presses OK button
2558 * hDlg [in] main window dialog HANDLE
2559 * pda [in/out] ptr to PageSetupDataA structure
2565 PRINTDLG_PS_UpdateDlgStructA(HWND hDlg
, PageSetupDataA
*pda
) {
2570 memcpy(pda
->dlga
, &pda
->curdlg
, sizeof(pda
->curdlg
));
2571 pda
->dlga
->hDevMode
= pda
->pdlg
.hDevMode
;
2572 pda
->dlga
->hDevNames
= pda
->pdlg
.hDevNames
;
2574 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2575 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2577 /* Save paper orientation into device context */
2578 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
)
2579 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2581 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2583 /* Save paper size into the device context */
2584 paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2585 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2586 if (paperword
!= CB_ERR
)
2587 dm
->u1
.s1
.dmPaperSize
= paperword
;
2589 FIXME("could not get dialog text for papersize cmbbox?\n");
2591 /* Save paper source into the device context */
2592 paperword
= SendDlgItemMessageA(hDlg
,cmb1
,CB_GETITEMDATA
,
2593 SendDlgItemMessageA(hDlg
, cmb1
, CB_GETCURSEL
, 0, 0), 0);
2594 if (paperword
!= CB_ERR
)
2595 dm
->u1
.s1
.dmDefaultSource
= paperword
;
2597 FIXME("could not get dialog text for papersize cmbbox?\n");
2599 GlobalUnlock(pda
->pdlg
.hDevNames
);
2600 GlobalUnlock(pda
->pdlg
.hDevMode
);
2606 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2609 LPWSTR devname
,portname
;
2610 WCHAR papername
[64];
2613 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2614 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2615 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2616 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2618 /* Save paper size into device context */
2619 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2620 /* Save paper source into device context */
2621 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2623 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2624 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2625 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2626 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2628 FIXME("could not get dialog text for papersize cmbbox?\n");
2629 #define GETVAL(id,val) if (GetDlgItemTextW(hDlg,id,buf,sizeof(buf)/sizeof(buf[0]))>0) { val = _c_str2sizeW(pdw->dlgw,buf); } else { FIXME("could not get dlgitemtextw for %x\n",id); }
2630 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2631 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2632 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2633 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2636 /* If we are in landscape, swap x and y of page size */
2637 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2639 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2640 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2641 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2644 /* Save orientation */
2645 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2646 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2648 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2650 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2651 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2655 /**********************************************************************************************
2656 * PRINTDLG_PS_ChangeActivePrinerA
2658 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2661 * name [in] Name of a printer for activation
2662 * pda [in/out] ptr to PageSetupDataA structure
2669 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2672 LPPRINTER_INFO_2A lpPrinterInfo
;
2673 LPDRIVER_INFO_3A lpDriverInfo
;
2674 DEVMODEA
*pDevMode
, *dm
;
2676 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2677 ERR("Can't open printer %s\n", name
);
2680 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2681 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2682 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2683 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2684 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2685 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2686 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2687 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2688 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2693 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2695 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2696 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2697 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2700 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2701 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2703 pda
->pdlg
.hDevMode
= GlobalReAlloc(pda
->pdlg
.hDevMode
,
2704 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2706 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2707 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2709 PRINTDLG_CreateDevNames(&(pda
->pdlg
.hDevNames
),
2710 lpDriverInfo
->pDriverPath
,
2711 lpPrinterInfo
->pPrinterName
,
2712 lpPrinterInfo
->pPortName
);
2714 GlobalUnlock(pda
->pdlg
.hDevMode
);
2715 HeapFree(GetProcessHeap(), 0, pDevMode
);
2716 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2717 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2721 /****************************************************************************************
2722 * PRINTDLG_PS_ChangePrinterA
2724 * Fills Printers, Paper and Source combo
2730 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2733 LPSTR devname
,portname
;
2735 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2736 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2737 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2738 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2739 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2740 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2741 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2742 GlobalUnlock(pda
->pdlg
.hDevNames
);
2743 GlobalUnlock(pda
->pdlg
.hDevMode
);
2747 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2749 WCHAR PaperName
[64];
2751 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2752 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2753 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2754 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2756 if(IsDlgButtonChecked(hDlg
, rad2
))
2758 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2759 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2760 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2764 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2769 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2774 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2775 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2777 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2779 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2782 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2784 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2788 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2791 LPWSTR devname
,portname
;
2793 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2794 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2795 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2796 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2797 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2798 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2800 /* Landscape orientation */
2801 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2802 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2803 else /* this is default if papersize is not set */
2804 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2806 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2807 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2809 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2814 /******************************************************************************************
2815 * PRINTDLG_PS_ChangePaperPrev
2817 * Changes paper preview size / position
2820 * pda [i] Pointer for current PageSetupDataA structure
2826 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2828 LONG width
, height
, x
, y
;
2831 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) {
2832 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2833 height
= pda
->curdlg
.ptPaperSize
.y
* width
/ pda
->curdlg
.ptPaperSize
.x
;
2835 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2836 width
= pda
->curdlg
.ptPaperSize
.x
* height
/ pda
->curdlg
.ptPaperSize
.y
;
2838 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2839 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2840 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2841 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2842 x
, y
, width
, height
);
2845 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2846 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2847 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2848 rtTmp
= pda
->rtDrawRect
;
2849 rtTmp
.right
+= SHADOW
;
2850 rtTmp
.bottom
+= SHADOW
;
2853 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2857 #define GETVAL(idc,val) \
2858 if(msg == EN_CHANGE){ \
2859 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2860 val = _c_str2sizeA(pda->dlga,buf); \
2862 FIXME("could not get dlgitemtexta for %x\n",id); \
2865 /********************************************************************************
2866 * PRINTDLG_PS_WMCommandA
2867 * process WM_COMMAND message for PageSetupDlgA
2870 * hDlg [in] Main dialog HANDLE
2871 * wParam [in] WM_COMMAND wParam
2872 * lParam [in] WM_COMMAND lParam
2873 * pda [in/out] ptr to PageSetupDataA
2877 PRINTDLG_PS_WMCommandA(
2878 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2880 WORD msg
= HIWORD(wParam
);
2881 WORD id
= LOWORD(wParam
);
2884 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2885 LOWORD(lParam
),wParam
,lParam
);
2888 if (!PRINTDLG_PS_UpdateDlgStructA(hDlg
, pda
))
2890 EndDialog(hDlg
, TRUE
);
2894 EndDialog(hDlg
, FALSE
);
2898 pda
->pdlg
.Flags
= 0;
2899 pda
->pdlg
.hwndOwner
= hDlg
;
2900 if (PrintDlgA(&(pda
->pdlg
)))
2901 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2906 if((id
== rad1
&& pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) ||
2907 (id
== rad2
&& pda
->curdlg
.ptPaperSize
.y
> pda
->curdlg
.ptPaperSize
.x
))
2911 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2913 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2914 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2916 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2917 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2918 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2919 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2921 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2922 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2923 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2924 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2926 PRINTDLG_PS_ChangePaperPrev(pda
);
2929 case cmb1
: /* Printer combo */
2930 if(msg
== CBN_SELCHANGE
){
2931 char crPrinterName
[256];
2932 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2933 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2934 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2937 case cmb2
: /* Paper combo */
2938 if(msg
== CBN_SELCHANGE
){
2939 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2940 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2941 if (paperword
!= CB_ERR
) {
2942 PRINTDLG_PaperSizeA(&(pda
->pdlg
), paperword
,&(pda
->curdlg
.ptPaperSize
));
2943 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.x
);
2944 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.y
);
2946 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2947 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2948 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2949 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2951 PRINTDLG_PS_ChangePaperPrev(pda
);
2953 FIXME("could not get dialog text for papersize cmbbox?\n");
2957 if(msg
== CBN_SELCHANGE
){
2958 DEVMODEA
*dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2959 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2960 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2961 GlobalUnlock(pda
->pdlg
.hDevMode
);
2964 case psh2
: /* Printer Properties button */
2967 char PrinterName
[256];
2972 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2973 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2974 FIXME("Call to OpenPrinter did not succeed!\n");
2977 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2978 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2979 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2980 ClosePrinter(hPrinter
);
2981 /* Changing paper */
2982 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &(pda
->curdlg
.ptPaperSize
));
2983 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
2984 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
2985 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
2986 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2987 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2988 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2989 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2992 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2993 /* Changing paper preview */
2994 PRINTDLG_PS_ChangePaperPrev(pda
);
2995 /* Selecting paper in combo */
2996 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
2997 if(count
!= CB_ERR
){
2998 for(i
=0; i
<count
; ++i
){
2999 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
3000 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
3006 GlobalUnlock(pda
->pdlg
.hDevMode
);
3010 GETVAL(id
, pda
->curdlg
.rtMargin
.left
);
3013 GETVAL(id
, pda
->curdlg
.rtMargin
.top
);
3016 GETVAL(id
, pda
->curdlg
.rtMargin
.right
);
3019 GETVAL(id
, pda
->curdlg
.rtMargin
.bottom
);
3022 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3028 PRINTDLG_PS_WMCommandW(
3029 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3031 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3032 LOWORD(lParam
),wParam
,lParam
);
3033 switch (LOWORD(wParam
)) {
3035 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3037 EndDialog(hDlg
, TRUE
);
3041 EndDialog(hDlg
, FALSE
);
3046 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3047 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3051 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3053 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3054 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3056 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3057 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3058 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3059 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3061 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3062 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3063 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3064 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3069 pdw
->pdlg
.Flags
= 0;
3070 pdw
->pdlg
.hwndOwner
= hDlg
;
3071 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3072 if (PrintDlgW(&(pdw
->pdlg
)))
3073 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3081 /***********************************************************************
3082 * DefaultPagePaintHook
3083 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3084 * whenever the sample page is redrawn.
3088 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3089 const PageSetupDataA
*pda
)
3091 LPRECT lprc
= (LPRECT
) lParam
;
3092 HDC hdc
= (HDC
) wParam
;
3095 HFONT hfont
, holdfont
;
3097 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3098 /* Call user paint hook if enable */
3099 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3100 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3104 /* LPPAGESETUPDLG in lParam */
3105 case WM_PSD_PAGESETUPDLG
:
3106 /* Inform about the sample page rectangle */
3107 case WM_PSD_FULLPAGERECT
:
3108 /* Inform about the margin rectangle */
3109 case WM_PSD_MINMARGINRECT
:
3112 /* Draw dashed rectangle showing margins */
3113 case WM_PSD_MARGINRECT
:
3114 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3115 holdpen
= SelectObject(hdc
, hpen
);
3116 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3117 DeleteObject(SelectObject(hdc
, holdpen
));
3119 /* Draw the fake document */
3120 case WM_PSD_GREEKTEXTRECT
:
3121 /* select a nice scalable font, because we want the text really small */
3122 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3123 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3124 hfont
= CreateFontIndirectW(&lf
);
3125 holdfont
= SelectObject(hdc
, hfont
);
3127 /* if text not loaded, then do so now */
3128 if (wszFakeDocumentText
[0] == '\0')
3129 LoadStringW(COMDLG32_hInstance
,
3131 wszFakeDocumentText
,
3132 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3134 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3135 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3136 SetBkMode(hdc
, oldbkmode
);
3138 DeleteObject(SelectObject(hdc
, holdfont
));
3141 /* Envelope stamp */
3142 case WM_PSD_ENVSTAMPRECT
:
3143 /* Return address */
3144 case WM_PSD_YAFULLPAGERECT
:
3145 FIXME("envelope/stamp is not implemented\n");
3148 FIXME("Unknown message %x\n",uMsg
);
3154 /***********************************************************************
3156 * The main paint procedure for the PageSetupDlg function.
3157 * The Page Setup dialog box includes an image of a sample page that shows how
3158 * the user's selections affect the appearance of the printed output.
3159 * The image consists of a rectangle that represents the selected paper
3160 * or envelope type, with a dotted-line rectangle representing
3161 * the current margins, and partial (Greek text) characters
3162 * to show how text looks on the printed page.
3164 * The following messages in the order sends to user hook procedure:
3165 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3166 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3167 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3168 * WM_PSD_MARGINRECT Draw the margin rectangle
3169 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3170 * If any of first three messages returns TRUE, painting done.
3173 * hWnd [in] Handle to the Page Setup dialog box
3174 * uMsg [in] Received message
3177 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3178 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3181 * FALSE if all done correctly
3186 static LRESULT CALLBACK
3187 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3190 RECT rcClient
, rcMargin
;
3193 HBRUSH hbrush
, holdbrush
;
3194 PageSetupDataA
*pda
;
3195 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3196 double scalx
, scaly
;
3197 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3199 if (uMsg
!= WM_PAINT
)
3200 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3202 /* Processing WM_PAINT message */
3203 pda
= (PageSetupDataA
*)GetPropA(hWnd
, "__WINE_PAGESETUPDLGDATA");
3205 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3208 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3211 hdc
= BeginPaint(hWnd
, &ps
);
3212 GetClientRect(hWnd
, &rcClient
);
3214 scalx
= rcClient
.right
/ (double)pda
->curdlg
.ptPaperSize
.x
;
3215 scaly
= rcClient
.bottom
/ (double)pda
->curdlg
.ptPaperSize
.y
;
3216 rcMargin
= rcClient
;
3218 rcMargin
.left
+= pda
->curdlg
.rtMargin
.left
* scalx
;
3219 rcMargin
.top
+= pda
->curdlg
.rtMargin
.top
* scalx
;
3220 rcMargin
.right
-= pda
->curdlg
.rtMargin
.right
* scaly
;
3221 rcMargin
.bottom
-= pda
->curdlg
.rtMargin
.bottom
* scaly
;
3223 /* if the space is too small then we make sure to not draw anything */
3224 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3225 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3227 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3228 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3230 /* fill background */
3231 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3232 FillRect(hdc
, &rcClient
, hbrush
);
3233 holdbrush
= SelectObject(hdc
, hbrush
);
3235 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3236 holdpen
= SelectObject(hdc
, hpen
);
3238 /* paint left edge */
3239 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3240 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3242 /* paint top edge */
3243 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3244 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3246 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3247 DeleteObject(SelectObject(hdc
, hpen
));
3249 /* paint right edge */
3250 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3251 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3253 /* paint bottom edge */
3254 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3255 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3257 DeleteObject(SelectObject(hdc
, holdpen
));
3258 DeleteObject(SelectObject(hdc
, holdbrush
));
3260 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3262 /* give text a bit of a space from the frame */
3265 rcMargin
.right
-= 2;
3266 rcMargin
.bottom
-= 2;
3268 /* if the space is too small then we make sure to not draw anything */
3269 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3270 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3272 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3275 EndPaint(hWnd
, &ps
);
3277 #undef CALLPAINTHOOK
3280 /***********************************************************************
3281 * PRINTDLG_PageDlgProcA
3282 * Message handler for PageSetupDlgA
3284 static INT_PTR CALLBACK
3285 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3288 PageSetupDataA
*pda
;
3289 INT_PTR res
= FALSE
;
3292 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3293 pda
= (PageSetupDataA
*)lParam
;
3294 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3295 pda
->curdlg
= *pda
->dlga
;
3297 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3298 TRACE("set property to %p\n", pda
);
3299 SetPropA(hDlg
, "__WINE_PAGESETUPDLGDATA", pda
);
3300 SetPropA(hDrawWnd
, "__WINE_PAGESETUPDLGDATA", pda
);
3301 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3302 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3303 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3304 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3307 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3309 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3311 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3312 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3313 FIXME("Setup page hook failed?\n");
3316 /* if printer button disabled */
3317 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3318 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3319 /* if margin edit boxes disabled */
3320 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3321 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3322 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3323 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3324 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3326 /* Set orientation radiobutton properly */
3327 if(pda
->dlga
->hDevMode
)
3329 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3330 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3331 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3332 else /* this is default if papersize is not set */
3333 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3334 GlobalUnlock(pda
->dlga
->hDevMode
);
3337 /* if orientation disabled */
3338 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3339 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3340 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3342 /* We fill them out enabled or not */
3343 if (pda
->dlga
->Flags
& PSD_MARGINS
) {
3345 _c_size2strA(pda
,pda
->dlga
->rtMargin
.left
,str
);
3346 SetDlgItemTextA(hDlg
,edt4
,str
);
3347 _c_size2strA(pda
,pda
->dlga
->rtMargin
.top
,str
);
3348 SetDlgItemTextA(hDlg
,edt5
,str
);
3349 _c_size2strA(pda
,pda
->dlga
->rtMargin
.right
,str
);
3350 SetDlgItemTextA(hDlg
,edt6
,str
);
3351 _c_size2strA(pda
,pda
->dlga
->rtMargin
.bottom
,str
);
3352 SetDlgItemTextA(hDlg
,edt7
,str
);
3354 /* default is 1 inch */
3355 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3357 _c_size2strA(pda
,size
,str
);
3358 SetDlgItemTextA(hDlg
,edt4
,str
);
3359 SetDlgItemTextA(hDlg
,edt5
,str
);
3360 SetDlgItemTextA(hDlg
,edt6
,str
);
3361 SetDlgItemTextA(hDlg
,edt7
,str
);
3362 pda
->curdlg
.rtMargin
.left
= size
;
3363 pda
->curdlg
.rtMargin
.top
= size
;
3364 pda
->curdlg
.rtMargin
.right
= size
;
3365 pda
->curdlg
.rtMargin
.bottom
= size
;
3367 /* if paper disabled */
3368 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3369 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3370 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3372 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3373 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3374 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
3376 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3377 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &pda
->curdlg
.ptPaperSize
);
3378 GlobalUnlock(pda
->pdlg
.hDevMode
);
3379 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3380 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3381 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3382 DWORD tmp
= pda
->curdlg
.ptPaperSize
.y
;
3383 pda
->curdlg
.ptPaperSize
.y
= pda
->curdlg
.ptPaperSize
.x
;
3384 pda
->curdlg
.ptPaperSize
.x
= tmp
;
3387 WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda
->pdlg
.hDevMode
);
3388 /* Drawing paper prev */
3389 PRINTDLG_PS_ChangePaperPrev(pda
);
3392 pda
= (PageSetupDataA
*)GetPropA(hDlg
,"__WINE_PAGESETUPDLGDATA");
3394 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3397 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3398 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3399 if (res
) return res
;
3404 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3409 static INT_PTR CALLBACK
3410 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3412 static const WCHAR __WINE_PAGESETUPDLGDATA
[] =
3413 { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
3414 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };
3415 PageSetupDataW
*pdw
;
3418 if (uMsg
==WM_INITDIALOG
) {
3420 pdw
= (PageSetupDataW
*)lParam
;
3421 pdw
->curdlg
= *pdw
->dlgw
;
3422 SetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
, pdw
);
3423 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3424 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3426 FIXME("Setup page hook failed?\n");
3431 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3432 FIXME("PagePaintHook not yet implemented!\n");
3434 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3435 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3436 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3437 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3438 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3439 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3440 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3443 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3445 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3446 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3447 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3449 /* We fill them out enabled or not */
3450 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3452 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3453 SetDlgItemTextW(hDlg
,edt4
,str
);
3454 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3455 SetDlgItemTextW(hDlg
,edt5
,str
);
3456 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3457 SetDlgItemTextW(hDlg
,edt6
,str
);
3458 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3459 SetDlgItemTextW(hDlg
,edt7
,str
);
3461 /* default is 1 inch */
3462 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3464 _c_size2strW(pdw
,size
,str
);
3465 SetDlgItemTextW(hDlg
,edt4
,str
);
3466 SetDlgItemTextW(hDlg
,edt5
,str
);
3467 SetDlgItemTextW(hDlg
,edt6
,str
);
3468 SetDlgItemTextW(hDlg
,edt7
,str
);
3471 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3472 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3473 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3478 pdw
= (PageSetupDataW
*)GetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
);
3480 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3483 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3484 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3485 if (res
) return res
;
3490 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3495 /***********************************************************************
3496 * PageSetupDlgA (COMDLG32.@)
3498 * Displays the PAGE SETUP dialog box, which enables the user to specify
3499 * specific properties of a printed page such as
3500 * size, source, orientation and the width of the page margins.
3503 * setupdlg [IO] PAGESETUPDLGA struct
3506 * TRUE if the user pressed the OK button
3507 * FALSE if the user cancelled the window or an error occurred
3510 * The values of hDevMode and hDevNames are filled on output and can be
3511 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3515 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3519 PageSetupDataA
*pda
;
3522 if (setupdlg
== NULL
) {
3523 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3528 if(TRACE_ON(commdlg
)) {
3529 char flagstr
[1000] = "";
3530 const struct pd_flags
*pflag
= psd_flags
;
3531 for( ; pflag
->name
; pflag
++) {
3532 if(setupdlg
->Flags
& pflag
->flag
) {
3533 strcat(flagstr
, pflag
->name
);
3534 strcat(flagstr
, "|");
3537 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3538 "hinst %p, flags %08x (%s)\n",
3539 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3540 setupdlg
->hDevNames
,
3541 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3544 /* Checking setupdlg structure */
3545 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3546 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3549 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3550 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3551 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3555 /* Initialize default printer struct. If no printer device info is specified
3556 retrieve the default printer data. */
3557 memset(&pdlg
,0,sizeof(pdlg
));
3558 pdlg
.lStructSize
= sizeof(pdlg
);
3559 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3560 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3561 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3563 pdlg
.Flags
= PD_RETURNDEFAULT
;
3564 bRet
= PrintDlgA(&pdlg
);
3566 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3568 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3569 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3575 /* short cut exit, just return default values */
3576 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3579 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3580 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3581 dm
= GlobalLock(pdlg
.hDevMode
);
3582 PRINTDLG_PaperSizeA(&pdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3583 GlobalUnlock(pdlg
.hDevMode
);
3584 setupdlg
->ptPaperSize
.x
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.x
);
3585 setupdlg
->ptPaperSize
.y
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.y
);
3589 /* get dialog template */
3590 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3592 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3595 ptr
= LockResource( hDlgTmpl
);
3597 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3601 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3602 pda
->dlga
= setupdlg
;
3605 bRet
= (0<DialogBoxIndirectParamA(
3606 setupdlg
->hInstance
,
3608 setupdlg
->hwndOwner
,
3609 PRINTDLG_PageDlgProcA
,
3613 HeapFree(GetProcessHeap(),0,pda
);
3616 /***********************************************************************
3617 * PageSetupDlgW (COMDLG32.@)
3619 * See PageSetupDlgA.
3621 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3625 PageSetupDataW
*pdw
;
3628 FIXME("Unicode implementation is not done yet\n");
3630 if (setupdlg
== NULL
) {
3631 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3635 if(TRACE_ON(commdlg
)) {
3636 char flagstr
[1000] = "";
3637 const struct pd_flags
*pflag
= psd_flags
;
3638 for( ; pflag
->name
; pflag
++) {
3639 if(setupdlg
->Flags
& pflag
->flag
) {
3640 strcat(flagstr
, pflag
->name
);
3641 strcat(flagstr
, "|");
3644 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3645 "hinst %p, flags %08x (%s)\n",
3646 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3647 setupdlg
->hDevNames
,
3648 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3651 /* Initialize default printer struct. If no printer device info is specified
3652 retrieve the default printer data. */
3653 memset(&pdlg
,0,sizeof(pdlg
));
3654 pdlg
.lStructSize
= sizeof(pdlg
);
3655 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3656 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3657 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3659 pdlg
.Flags
= PD_RETURNDEFAULT
;
3660 bRet
= PrintDlgW(&pdlg
);
3662 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3664 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3665 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3671 /* short cut exit, just return default values */
3672 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3673 static const WCHAR a4
[] = {'A','4',0};
3674 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3675 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3676 /* FIXME: Just return "A4" for now. */
3677 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3678 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3679 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3682 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3684 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3687 ptr
= LockResource( hDlgTmpl
);
3689 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3692 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3693 pdw
->dlgw
= setupdlg
;
3696 bRet
= (0<DialogBoxIndirectParamW(
3697 setupdlg
->hInstance
,
3699 setupdlg
->hwndOwner
,
3706 /***********************************************************************
3707 * PrintDlgExA (COMDLG32.@)
3715 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3718 FIXME("(%p) stub\n", lppd
);
3719 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3720 return E_INVALIDARG
;
3723 if (!IsWindow(lppd
->hwndOwner
)) {
3730 /***********************************************************************
3731 * PrintDlgExW (COMDLG32.@)
3733 * Display the property sheet style PRINT dialog box
3736 * lppd [IO] ptr to PRINTDLGEX struct
3740 * Failure: One of the following COM error codes:
3741 * E_OUTOFMEMORY Insufficient memory.
3742 * E_INVALIDARG One or more arguments are invalid.
3743 * E_POINTER Invalid pointer.
3744 * E_HANDLE Invalid handle.
3745 * E_FAIL Unspecified error.
3748 * This Dialog enables the user to specify specific properties of the print job.
3749 * The property sheet can also have additional application-specific and
3750 * driver-specific property pages.
3756 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3759 FIXME("(%p) stub\n", lppd
);
3760 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3761 return E_INVALIDARG
;
3764 if (!IsWindow(lppd
->hwndOwner
)) {