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 char resourcestr
[256];
313 LoadStringA(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
315 sprintf(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
316 LoadStringA(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
318 MessageBoxA(hDlg
, resultstr
, resourcestr
,
319 MB_OK
| MB_ICONWARNING
);
322 lppd
->nFromPage
= nFromPage
;
323 lppd
->nToPage
= nToPage
;
324 lppd
->Flags
|= PD_PAGENUMS
;
327 lppd
->Flags
&= ~PD_PAGENUMS
;
329 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
330 lppd
->Flags
|= PD_SELECTION
;
332 lppd
->Flags
&= ~PD_SELECTION
;
334 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
335 static char file
[] = "FILE:";
336 lppd
->Flags
|= PD_PRINTTOFILE
;
337 pi
->pPortName
= file
;
340 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
341 FIXME("Collate lppd not yet implemented as output\n");
344 /* set PD_Collate and nCopies */
345 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
346 /* The application doesn't support multiple copies or collate...
348 lppd
->Flags
&= ~PD_COLLATE
;
350 /* if the printer driver supports it... store info there
351 * otherwise no collate & multiple copies !
353 if (lpdm
->dmFields
& DM_COLLATE
)
355 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
356 if (lpdm
->dmFields
& DM_COPIES
)
357 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
359 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
360 lppd
->Flags
|= PD_COLLATE
;
362 lppd
->Flags
&= ~PD_COLLATE
;
363 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
366 /* Print quality, PrintDlg16 */
367 if(GetDlgItem(hDlg
, cmb1
))
369 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
370 int Sel
= SendMessageA(hQuality
, CB_GETCURSEL
, 0, 0);
374 LONG dpi
= SendMessageA(hQuality
, CB_GETITEMDATA
, Sel
, 0);
375 lpdm
->dmFields
|= DM_PRINTQUALITY
| DM_YRESOLUTION
;
376 lpdm
->u1
.s1
.dmPrintQuality
= LOWORD(dpi
);
377 lpdm
->dmYResolution
= HIWORD(dpi
);
384 static BOOL
PRINTDLG_UpdatePrintDlgW(HWND hDlg
,
385 PRINT_PTRW
* PrintStructures
)
387 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
388 PDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
389 LPPRINTER_INFO_2W pi
= PrintStructures
->lpPrinterInfo
;
393 FIXME("No lpdm ptr?\n");
398 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
399 /* check whether nFromPage and nToPage are within range defined by
400 * nMinPage and nMaxPage
402 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
405 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
406 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
407 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
408 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
409 WCHAR resourcestr
[256];
410 WCHAR resultstr
[256];
411 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
413 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
414 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
416 MessageBoxW(hDlg
, resultstr
, resourcestr
,
417 MB_OK
| MB_ICONWARNING
);
420 lppd
->nFromPage
= nFromPage
;
421 lppd
->nToPage
= nToPage
;
422 lppd
->Flags
|= PD_PAGENUMS
;
425 lppd
->Flags
&= ~PD_PAGENUMS
;
427 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
428 lppd
->Flags
|= PD_SELECTION
;
430 lppd
->Flags
&= ~PD_SELECTION
;
432 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
433 static WCHAR file
[] = {'F','I','L','E',':',0};
434 lppd
->Flags
|= PD_PRINTTOFILE
;
435 pi
->pPortName
= file
;
438 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
439 FIXME("Collate lppd not yet implemented as output\n");
442 /* set PD_Collate and nCopies */
443 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
444 /* The application doesn't support multiple copies or collate...
446 lppd
->Flags
&= ~PD_COLLATE
;
448 /* if the printer driver supports it... store info there
449 * otherwise no collate & multiple copies !
451 if (lpdm
->dmFields
& DM_COLLATE
)
453 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
454 if (lpdm
->dmFields
& DM_COPIES
)
455 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
457 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
458 lppd
->Flags
|= PD_COLLATE
;
460 lppd
->Flags
&= ~PD_COLLATE
;
461 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
467 static BOOL
PRINTDLG_PaperSizeA(
468 PRINTDLGA
*pdlga
,const WORD PaperSize
,LPPOINT size
472 LPSTR devname
,portname
;
476 POINT
*points
= NULL
;
479 dn
= GlobalLock(pdlga
->hDevNames
);
480 dm
= GlobalLock(pdlga
->hDevMode
);
481 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
482 portname
= ((char*)dn
)+dn
->wOutputOffset
;
485 NrOfEntries
= DeviceCapabilitiesA(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
487 FIXME("No papernames found for %s/%s\n",devname
,portname
);
490 if (NrOfEntries
== -1) {
491 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
495 Words
= HeapAlloc(GetProcessHeap(),0,NrOfEntries
*sizeof(WORD
));
496 if (NrOfEntries
!= (ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERS
,(LPSTR
)Words
,dm
))) {
497 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
500 for (i
=0;i
<NrOfEntries
;i
++)
501 if (Words
[i
] == PaperSize
)
503 HeapFree(GetProcessHeap(),0,Words
);
504 if (i
== NrOfEntries
) {
505 FIXME("Papersize %d not found in list?\n",PaperSize
);
508 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
509 if (NrOfEntries
!=(ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERSIZE
,(LPSTR
)points
,dm
))) {
510 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
513 /* this is _10ths_ of a millimeter */
518 GlobalUnlock(pdlga
->hDevNames
);
519 GlobalUnlock(pdlga
->hDevMode
);
520 HeapFree(GetProcessHeap(),0,Words
);
521 HeapFree(GetProcessHeap(),0,points
);
525 static BOOL
PRINTDLG_PaperSizeW(
526 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
530 LPWSTR devname
,portname
;
534 POINT
*points
= NULL
;
537 dn
= GlobalLock(pdlga
->hDevNames
);
538 dm
= GlobalLock(pdlga
->hDevMode
);
539 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
540 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
543 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
545 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
548 if (NrOfEntries
== -1) {
549 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
553 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
554 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
555 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
558 for (i
=0;i
<NrOfEntries
;i
++)
559 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
561 HeapFree(GetProcessHeap(),0,Names
);
562 if (i
==NrOfEntries
) {
563 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
566 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
567 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
568 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
571 /* this is _10ths_ of a millimeter */
576 GlobalUnlock(pdlga
->hDevNames
);
577 GlobalUnlock(pdlga
->hDevMode
);
578 HeapFree(GetProcessHeap(),0,Names
);
579 HeapFree(GetProcessHeap(),0,points
);
584 /************************************************************************
585 * PRINTDLG_SetUpPaperComboBox
587 * Initialize either the papersize or inputslot combos of the Printer Setup
588 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
589 * We also try to re-select the old selection.
591 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
604 int fwCapability_Names
;
605 int fwCapability_Words
;
607 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
609 /* query the dialog box for the current selected value */
610 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
612 /* we enter here only if a different printer is selected after
613 * the Print Setup dialog is opened. The current settings are
614 * stored into the newly selected printer.
616 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
619 if (nIDComboBox
== cmb2
)
620 dm
->u1
.s1
.dmPaperSize
= oldWord
;
622 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
626 /* we enter here only when the Print setup dialog is initially
627 * opened. In this case the settings are restored from when
628 * the dialog was last closed.
631 if (nIDComboBox
== cmb2
)
632 oldWord
= dm
->u1
.s1
.dmPaperSize
;
634 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
638 if (nIDComboBox
== cmb2
) {
640 fwCapability_Names
= DC_PAPERNAMES
;
641 fwCapability_Words
= DC_PAPERS
;
645 fwCapability_Names
= DC_BINNAMES
;
646 fwCapability_Words
= DC_BINS
;
649 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
650 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
652 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
653 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
654 fwCapability_Names
, NULL
, dm
);
655 if (NrOfEntries
== 0)
656 WARN("no Name Entries found!\n");
657 else if (NrOfEntries
< 0)
660 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
662 ERR("Number of caps is different\n");
666 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
667 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
668 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
669 fwCapability_Names
, Names
, dm
);
670 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
671 fwCapability_Words
, (LPSTR
)Words
, dm
);
673 /* reset any current content in the combobox */
674 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
676 /* store new content */
677 for (i
= 0; i
< NrOfEntries
; i
++) {
678 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
679 (LPARAM
)(&Names
[i
*NamesSize
]) );
680 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
684 /* Look for old selection - can't do this is previous loop since
685 item order will change as more items are added */
687 for (i
= 0; i
< NrOfEntries
; i
++) {
688 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
694 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
696 HeapFree(GetProcessHeap(),0,Words
);
697 HeapFree(GetProcessHeap(),0,Names
);
701 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
703 const WCHAR
* PrinterName
,
704 const WCHAR
* PortName
,
714 int fwCapability_Names
;
715 int fwCapability_Words
;
717 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
719 /* query the dialog box for the current selected value */
720 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
722 /* we enter here only if a different printer is selected after
723 * the Print Setup dialog is opened. The current settings are
724 * stored into the newly selected printer.
726 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
729 if (nIDComboBox
== cmb2
)
730 dm
->u1
.s1
.dmPaperSize
= oldWord
;
732 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
736 /* we enter here only when the Print setup dialog is initially
737 * opened. In this case the settings are restored from when
738 * the dialog was last closed.
741 if (nIDComboBox
== cmb2
)
742 oldWord
= dm
->u1
.s1
.dmPaperSize
;
744 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
748 if (nIDComboBox
== cmb2
) {
750 fwCapability_Names
= DC_PAPERNAMES
;
751 fwCapability_Words
= DC_PAPERS
;
755 fwCapability_Names
= DC_BINNAMES
;
756 fwCapability_Words
= DC_BINS
;
759 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
760 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
762 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
763 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
764 fwCapability_Names
, NULL
, dm
);
765 if (NrOfEntries
== 0)
766 WARN("no Name Entries found!\n");
767 else if (NrOfEntries
< 0)
770 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
772 ERR("Number of caps is different\n");
776 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
777 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
778 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
779 fwCapability_Names
, Names
, dm
);
780 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
781 fwCapability_Words
, (LPWSTR
)Words
, dm
);
783 /* reset any current content in the combobox */
784 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
786 /* store new content */
787 for (i
= 0; i
< NrOfEntries
; i
++) {
788 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
789 (LPARAM
)(&Names
[i
*NamesSize
]) );
790 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
794 /* Look for old selection - can't do this is previous loop since
795 item order will change as more items are added */
797 for (i
= 0; i
< NrOfEntries
; i
++) {
798 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
804 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
806 HeapFree(GetProcessHeap(),0,Words
);
807 HeapFree(GetProcessHeap(),0,Names
);
812 /***********************************************************************
813 * PRINTDLG_UpdatePrinterInfoTexts [internal]
815 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
818 char ResourceString
[256];
824 /* add all status messages */
825 for (i
= 0; i
< 25; i
++) {
826 if (pi
->Status
& (1<<i
)) {
827 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
828 ResourceString
, 255);
829 strcat(StatusMsg
,ResourceString
);
833 /* FIXME: status==ready must only be appended if really so.
834 but how to detect? */
835 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
836 ResourceString
, 255);
837 strcat(StatusMsg
,ResourceString
);
838 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
840 /* set all other printer info texts */
841 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
843 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
844 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
846 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
847 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
851 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
853 WCHAR StatusMsg
[256];
854 WCHAR ResourceString
[256];
855 static const WCHAR emptyW
[] = {0};
861 /* add all status messages */
862 for (i
= 0; i
< 25; i
++) {
863 if (pi
->Status
& (1<<i
)) {
864 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
865 ResourceString
, 255);
866 lstrcatW(StatusMsg
,ResourceString
);
870 /* FIXME: status==ready must only be appended if really so.
871 but how to detect? */
872 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
873 ResourceString
, 255);
874 lstrcatW(StatusMsg
,ResourceString
);
875 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
877 /* set all other printer info texts */
878 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
879 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
880 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
882 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
883 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
887 /*******************************************************************
889 * PRINTDLG_ChangePrinter
892 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
893 PRINT_PTRA
*PrintStructures
)
895 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
896 LPDEVMODEA lpdm
= NULL
;
901 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
902 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
903 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
904 ERR("Can't open printer %s\n", name
);
907 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
908 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
909 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
911 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
912 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
913 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
915 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
920 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
922 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
923 PrintStructures
->lpDevMode
= NULL
;
925 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
927 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
930 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
931 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
933 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
934 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
935 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
936 /* Supplied devicemode matches current printer so try to use it */
937 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
938 DM_OUT_BUFFER
| DM_IN_BUFFER
);
941 GlobalUnlock(lppd
->hDevMode
);
943 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
945 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
946 /* Print range (All/Range/Selection) */
947 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
948 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
949 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
950 if (lppd
->Flags
& PD_NOSELECTION
)
951 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
953 if (lppd
->Flags
& PD_SELECTION
)
954 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
955 if (lppd
->Flags
& PD_NOPAGENUMS
) {
956 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
957 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
958 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
959 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
960 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
962 if (lppd
->Flags
& PD_PAGENUMS
)
963 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
968 * FIXME: The ico3 is not displayed for some reason. I don't know why.
970 if (lppd
->Flags
& PD_COLLATE
) {
971 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
972 (LPARAM
)PrintStructures
->hCollateIcon
);
973 CheckDlgButton(hDlg
, chx2
, 1);
975 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
976 (LPARAM
)PrintStructures
->hNoCollateIcon
);
977 CheckDlgButton(hDlg
, chx2
, 0);
980 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
981 /* if printer doesn't support it: no Collate */
982 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
983 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
984 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
991 if (lppd
->hDevMode
== 0)
992 copies
= lppd
->nCopies
;
994 copies
= lpdm
->u1
.s1
.dmCopies
;
995 if(copies
== 0) copies
= 1;
996 else if(copies
< 0) copies
= MAX_COPIES
;
997 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1000 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1001 /* if printer doesn't support it: no nCopies */
1002 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1003 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1004 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1009 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1010 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1011 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1012 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1013 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1015 /* Fill print quality combo, PrintDlg16 */
1016 if(GetDlgItem(hDlg
, cmb1
))
1018 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1019 PrintStructures
->lpPrinterInfo
->pPortName
,
1020 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
1022 if(numResolutions
!= -1)
1024 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
1029 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
1030 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1033 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
1034 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1035 PrintStructures
->lpPrinterInfo
->pPortName
,
1036 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
1038 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1039 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1040 DeleteDC(hPrinterDC
);
1042 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1043 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1045 BOOL IsDefault
= FALSE
;
1048 if(Resolutions
[i
] == Resolutions
[i
+1])
1050 if(dpiX
== Resolutions
[i
])
1052 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1055 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1057 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1060 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1063 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1065 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1067 HeapFree(GetProcessHeap(), 0, Resolutions
);
1070 } else { /* PD_PRINTSETUP */
1071 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1073 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1074 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1075 PrintStructures
->lpPrinterInfo
->pPortName
,
1077 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1078 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1079 PrintStructures
->lpPrinterInfo
->pPortName
,
1081 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1082 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1083 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1084 PrintStructures
->hLandscapeIcon
));
1089 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1090 /* hide if PD_SHOWHELP not specified */
1091 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1096 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1097 PRINT_PTRW
*PrintStructures
)
1099 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1100 LPDEVMODEW lpdm
= NULL
;
1105 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1106 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1107 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1108 ERR("Can't open printer %s\n", debugstr_w(name
));
1111 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1112 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1113 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1115 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1116 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1117 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1119 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1124 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1126 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1127 PrintStructures
->lpDevMode
= NULL
;
1129 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1131 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1134 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1135 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1137 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1138 !lstrcmpW(lpdm
->dmDeviceName
,
1139 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1140 /* Supplied devicemode matches current printer so try to use it */
1141 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1142 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1145 GlobalUnlock(lppd
->hDevMode
);
1147 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1149 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1150 /* Print range (All/Range/Selection) */
1151 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1152 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1153 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1154 if (lppd
->Flags
& PD_NOSELECTION
)
1155 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1157 if (lppd
->Flags
& PD_SELECTION
)
1158 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1159 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1160 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1161 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1162 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1163 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1164 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1166 if (lppd
->Flags
& PD_PAGENUMS
)
1167 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1172 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1174 if (lppd
->Flags
& PD_COLLATE
) {
1175 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1176 (LPARAM
)PrintStructures
->hCollateIcon
);
1177 CheckDlgButton(hDlg
, chx2
, 1);
1179 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1180 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1181 CheckDlgButton(hDlg
, chx2
, 0);
1184 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1185 /* if printer doesn't support it: no Collate */
1186 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1187 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1188 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1195 if (lppd
->hDevMode
== 0)
1196 copies
= lppd
->nCopies
;
1198 copies
= lpdm
->u1
.s1
.dmCopies
;
1199 if(copies
== 0) copies
= 1;
1200 else if(copies
< 0) copies
= MAX_COPIES
;
1201 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1204 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1205 /* if printer doesn't support it: no nCopies */
1206 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1207 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1208 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1213 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1214 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1215 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1216 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1217 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1219 } else { /* PD_PRINTSETUP */
1220 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1222 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1223 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1224 PrintStructures
->lpPrinterInfo
->pPortName
,
1226 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1227 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1228 PrintStructures
->lpPrinterInfo
->pPortName
,
1230 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1231 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1232 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1233 PrintStructures
->hLandscapeIcon
));
1238 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1239 /* hide if PD_SHOWHELP not specified */
1240 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1245 /***********************************************************************
1246 * check_printer_setup [internal]
1248 static LRESULT
check_printer_setup(HWND hDlg
)
1251 WCHAR resourcestr
[256],resultstr
[256];
1254 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1257 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1263 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1264 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1265 res
= MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1270 /***********************************************************************
1271 * PRINTDLG_WMInitDialog [internal]
1273 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1274 PRINT_PTRA
* PrintStructures
)
1276 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1280 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1282 /* load Collate ICONs */
1283 /* We load these with LoadImage because they are not a standard
1284 size and we don't want them rescaled */
1285 PrintStructures
->hCollateIcon
=
1286 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1287 PrintStructures
->hNoCollateIcon
=
1288 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1290 /* These can be done with LoadIcon */
1291 PrintStructures
->hPortraitIcon
=
1292 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1293 PrintStructures
->hLandscapeIcon
=
1294 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1296 /* display the collate/no_collate icon */
1297 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1298 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1300 if(PrintStructures
->hCollateIcon
== 0 ||
1301 PrintStructures
->hNoCollateIcon
== 0 ||
1302 PrintStructures
->hPortraitIcon
== 0 ||
1303 PrintStructures
->hLandscapeIcon
== 0) {
1304 ERR("no icon in resourcefile\n");
1305 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1306 EndDialog(hDlg
, FALSE
);
1310 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1311 * must be registered and the Help button must be shown.
1313 if (lppd
->Flags
& PD_SHOWHELP
) {
1314 if((PrintStructures
->HelpMessageID
=
1315 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1316 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1320 PrintStructures
->HelpMessageID
= 0;
1322 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1323 PrintStructures
->hwndUpDown
=
1324 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1325 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1326 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1327 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1328 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1331 /* FIXME: I allow more freedom than either Win95 or WinNT,
1332 * which do not agree to what errors should be thrown or not
1333 * in case nToPage or nFromPage is out-of-range.
1335 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1336 lppd
->nMaxPage
= lppd
->nMinPage
;
1337 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1338 lppd
->Flags
|= PD_NOPAGENUMS
;
1339 if (lppd
->nToPage
< lppd
->nMinPage
)
1340 lppd
->nToPage
= lppd
->nMinPage
;
1341 if (lppd
->nToPage
> lppd
->nMaxPage
)
1342 lppd
->nToPage
= lppd
->nMaxPage
;
1343 if (lppd
->nFromPage
< lppd
->nMinPage
)
1344 lppd
->nFromPage
= lppd
->nMinPage
;
1345 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1346 lppd
->nFromPage
= lppd
->nMaxPage
;
1348 /* if we have the combo box, fill it */
1349 if (GetDlgItem(hDlg
,comboID
)) {
1352 pdn
= GlobalLock(lppd
->hDevNames
);
1353 pdm
= GlobalLock(lppd
->hDevMode
);
1355 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1357 name
= (char*)pdm
->dmDeviceName
;
1358 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1359 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1360 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1362 /* Now find selected printer and update rest of dlg */
1363 name
= HeapAlloc(GetProcessHeap(),0,256);
1364 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1365 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1366 HeapFree(GetProcessHeap(),0,name
);
1368 /* else use default printer */
1370 DWORD dwBufLen
= sizeof(name
);
1371 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1374 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1376 FIXME("No default printer found, expect problems!\n");
1381 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1382 PRINT_PTRW
* PrintStructures
)
1384 static const WCHAR PD32_COLLATE
[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
1385 static const WCHAR PD32_NOCOLLATE
[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
1386 static const WCHAR PD32_PORTRAIT
[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
1387 static const WCHAR PD32_LANDSCAPE
[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
1388 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1392 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1394 /* load Collate ICONs */
1395 /* We load these with LoadImage because they are not a standard
1396 size and we don't want them rescaled */
1397 PrintStructures
->hCollateIcon
=
1398 LoadImageW(COMDLG32_hInstance
, PD32_COLLATE
, IMAGE_ICON
, 0, 0, 0);
1399 PrintStructures
->hNoCollateIcon
=
1400 LoadImageW(COMDLG32_hInstance
, PD32_NOCOLLATE
, IMAGE_ICON
, 0, 0, 0);
1402 /* These can be done with LoadIcon */
1403 PrintStructures
->hPortraitIcon
=
1404 LoadIconW(COMDLG32_hInstance
, PD32_PORTRAIT
);
1405 PrintStructures
->hLandscapeIcon
=
1406 LoadIconW(COMDLG32_hInstance
, PD32_LANDSCAPE
);
1408 /* display the collate/no_collate icon */
1409 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1410 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1412 if(PrintStructures
->hCollateIcon
== 0 ||
1413 PrintStructures
->hNoCollateIcon
== 0 ||
1414 PrintStructures
->hPortraitIcon
== 0 ||
1415 PrintStructures
->hLandscapeIcon
== 0) {
1416 ERR("no icon in resourcefile\n");
1417 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1418 EndDialog(hDlg
, FALSE
);
1422 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1423 * must be registered and the Help button must be shown.
1425 if (lppd
->Flags
& PD_SHOWHELP
) {
1426 if((PrintStructures
->HelpMessageID
=
1427 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1428 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1432 PrintStructures
->HelpMessageID
= 0;
1434 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1435 PrintStructures
->hwndUpDown
=
1436 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1437 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1438 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1439 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1440 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1443 /* FIXME: I allow more freedom than either Win95 or WinNT,
1444 * which do not agree to what errors should be thrown or not
1445 * in case nToPage or nFromPage is out-of-range.
1447 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1448 lppd
->nMaxPage
= lppd
->nMinPage
;
1449 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1450 lppd
->Flags
|= PD_NOPAGENUMS
;
1451 if (lppd
->nToPage
< lppd
->nMinPage
)
1452 lppd
->nToPage
= lppd
->nMinPage
;
1453 if (lppd
->nToPage
> lppd
->nMaxPage
)
1454 lppd
->nToPage
= lppd
->nMaxPage
;
1455 if (lppd
->nFromPage
< lppd
->nMinPage
)
1456 lppd
->nFromPage
= lppd
->nMinPage
;
1457 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1458 lppd
->nFromPage
= lppd
->nMaxPage
;
1460 /* if we have the combo box, fill it */
1461 if (GetDlgItem(hDlg
,comboID
)) {
1464 pdn
= GlobalLock(lppd
->hDevNames
);
1465 pdm
= GlobalLock(lppd
->hDevMode
);
1467 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1469 name
= pdm
->dmDeviceName
;
1470 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1471 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1472 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1474 /* Now find selected printer and update rest of dlg */
1475 /* ansi is ok here */
1476 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1477 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1478 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1479 HeapFree(GetProcessHeap(),0,name
);
1481 /* else use default printer */
1483 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1484 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1487 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1489 FIXME("No default printer found, expect problems!\n");
1494 /***********************************************************************
1495 * PRINTDLG_WMCommand [internal]
1497 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1498 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1500 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1501 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1502 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1504 switch (LOWORD(wParam
)) {
1506 TRACE(" OK button was hit\n");
1507 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1508 FIXME("Update printdlg was not successful!\n");
1511 EndDialog(hDlg
, TRUE
);
1515 TRACE(" CANCEL button was hit\n");
1516 EndDialog(hDlg
, FALSE
);
1520 TRACE(" HELP button was hit\n");
1521 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1522 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1525 case chx2
: /* collate pages checkbox */
1526 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1527 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1528 (LPARAM
)PrintStructures
->hCollateIcon
);
1530 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1531 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1533 case edt1
: /* from page nr editbox */
1534 case edt2
: /* to page nr editbox */
1535 if (HIWORD(wParam
)==EN_CHANGE
) {
1538 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1539 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1540 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1541 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1546 if(HIWORD(wParam
) == EN_CHANGE
) {
1547 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1549 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1551 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1556 case psh1
: /* Print Setup */
1560 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1561 FIXME("The 32bit print dialog does not have this button!?\n");
1565 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1566 pdlg
.Flags
|= PD_PRINTSETUP
;
1567 pdlg
.hwndOwner
= HWND_16(hDlg
);
1568 if (!PrintDlg16(&pdlg
))
1573 case psh2
: /* Properties button */
1576 char PrinterName
[256];
1578 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1579 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1580 FIXME(" Call to OpenPrinter did not succeed!\n");
1583 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1584 PrintStructures
->lpDevMode
,
1585 PrintStructures
->lpDevMode
,
1586 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1587 ClosePrinter(hPrinter
);
1591 case rad1
: /* Paperorientation */
1592 if (lppd
->Flags
& PD_PRINTSETUP
)
1594 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1595 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1596 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1600 case rad2
: /* Paperorientation */
1601 if (lppd
->Flags
& PD_PRINTSETUP
)
1603 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1604 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1605 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1609 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1610 if (PrinterComboID
!= LOWORD(wParam
)) {
1614 case cmb4
: /* Printer combobox */
1615 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1616 char PrinterName
[256];
1617 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1618 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1622 case cmb2
: /* Papersize */
1624 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1626 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1632 case cmb3
: /* Bin */
1634 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1636 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1637 CB_GETITEMDATA
, Sel
,
1642 if(lppd
->Flags
& PD_PRINTSETUP
) {
1643 switch (LOWORD(wParam
)) {
1644 case rad1
: /* orientation */
1646 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1647 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1648 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1649 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1651 (LPARAM
)PrintStructures
->hPortraitIcon
);
1652 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1654 (LPARAM
)PrintStructures
->hPortraitIcon
);
1657 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1658 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1659 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1661 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1662 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1664 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1673 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1674 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1676 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1677 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1678 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1680 switch (LOWORD(wParam
)) {
1682 TRACE(" OK button was hit\n");
1683 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1684 FIXME("Update printdlg was not successful!\n");
1687 EndDialog(hDlg
, TRUE
);
1691 TRACE(" CANCEL button was hit\n");
1692 EndDialog(hDlg
, FALSE
);
1696 TRACE(" HELP button was hit\n");
1697 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1698 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1701 case chx2
: /* collate pages checkbox */
1702 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1703 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1704 (LPARAM
)PrintStructures
->hCollateIcon
);
1706 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1707 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1709 case edt1
: /* from page nr editbox */
1710 case edt2
: /* to page nr editbox */
1711 if (HIWORD(wParam
)==EN_CHANGE
) {
1714 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1715 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1716 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1717 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1722 if(HIWORD(wParam
) == EN_CHANGE
) {
1723 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1725 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1727 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1731 case psh1
: /* Print Setup */
1733 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1736 case psh2
: /* Properties button */
1739 WCHAR PrinterName
[256];
1741 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1742 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1743 FIXME(" Call to OpenPrinter did not succeed!\n");
1746 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1747 PrintStructures
->lpDevMode
,
1748 PrintStructures
->lpDevMode
,
1749 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1750 ClosePrinter(hPrinter
);
1754 case rad1
: /* Paperorientation */
1755 if (lppd
->Flags
& PD_PRINTSETUP
)
1757 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1758 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1759 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1763 case rad2
: /* Paperorientation */
1764 if (lppd
->Flags
& PD_PRINTSETUP
)
1766 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1767 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1768 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1772 case cmb1
: /* Printer Combobox in PRINT SETUP */
1774 case cmb4
: /* Printer combobox */
1775 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1776 WCHAR PrinterName
[256];
1777 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1778 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1782 case cmb2
: /* Papersize */
1784 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1786 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1792 case cmb3
: /* Bin */
1794 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1796 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1797 CB_GETITEMDATA
, Sel
,
1802 if(lppd
->Flags
& PD_PRINTSETUP
) {
1803 switch (LOWORD(wParam
)) {
1804 case rad1
: /* orientation */
1806 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1807 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1808 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1809 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1811 (LPARAM
)PrintStructures
->hPortraitIcon
);
1812 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1814 (LPARAM
)PrintStructures
->hPortraitIcon
);
1817 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1818 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1819 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1821 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1822 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1824 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1833 /***********************************************************************
1834 * PrintDlgProcA [internal]
1836 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1839 PRINT_PTRA
* PrintStructures
;
1840 INT_PTR res
= FALSE
;
1842 if (uMsg
!=WM_INITDIALOG
) {
1843 PrintStructures
= (PRINT_PTRA
*)GetPropA(hDlg
,"__WINE_PRINTDLGDATA");
1844 if (!PrintStructures
)
1847 PrintStructures
= (PRINT_PTRA
*) lParam
;
1848 SetPropA(hDlg
,"__WINE_PRINTDLGDATA",PrintStructures
);
1849 if(!check_printer_setup(hDlg
))
1851 EndDialog(hDlg
,FALSE
);
1854 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1856 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1857 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1858 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1863 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1864 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1871 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1874 DestroyIcon(PrintStructures
->hCollateIcon
);
1875 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1876 DestroyIcon(PrintStructures
->hPortraitIcon
);
1877 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1878 if(PrintStructures
->hwndUpDown
)
1879 DestroyWindow(PrintStructures
->hwndUpDown
);
1885 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1888 static const WCHAR propW
[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
1889 PRINT_PTRW
* PrintStructures
;
1890 INT_PTR res
= FALSE
;
1892 if (uMsg
!=WM_INITDIALOG
) {
1893 PrintStructures
= (PRINT_PTRW
*) GetPropW(hDlg
, propW
);
1894 if (!PrintStructures
)
1897 PrintStructures
= (PRINT_PTRW
*) lParam
;
1898 SetPropW(hDlg
, propW
, PrintStructures
);
1899 if(!check_printer_setup(hDlg
))
1901 EndDialog(hDlg
,FALSE
);
1904 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1906 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1907 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1911 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1912 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1918 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1921 DestroyIcon(PrintStructures
->hCollateIcon
);
1922 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1923 DestroyIcon(PrintStructures
->hPortraitIcon
);
1924 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1925 if(PrintStructures
->hwndUpDown
)
1926 DestroyWindow(PrintStructures
->hwndUpDown
);
1932 /************************************************************
1934 * PRINTDLG_GetDlgTemplate
1937 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1942 if (lppd
->Flags
& PD_PRINTSETUP
) {
1943 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1944 hDlgTmpl
= lppd
->hSetupTemplate
;
1945 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1946 hResInfo
= FindResourceA(lppd
->hInstance
,
1947 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1948 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1950 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1952 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1955 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1956 hDlgTmpl
= lppd
->hPrintTemplate
;
1957 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1958 hResInfo
= FindResourceA(lppd
->hInstance
,
1959 lppd
->lpPrintTemplateName
,
1961 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1963 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1965 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1971 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1975 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1976 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1978 if (lppd
->Flags
& PD_PRINTSETUP
) {
1979 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1980 hDlgTmpl
= lppd
->hSetupTemplate
;
1981 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1982 hResInfo
= FindResourceW(lppd
->hInstance
,
1983 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1984 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1986 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
1987 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1990 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1991 hDlgTmpl
= lppd
->hPrintTemplate
;
1992 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1993 hResInfo
= FindResourceW(lppd
->hInstance
,
1994 lppd
->lpPrintTemplateName
,
1996 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1998 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
1999 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2005 /***********************************************************************
2010 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
2012 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2013 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
2015 if(lppd
->Flags
& PD_RETURNDC
) {
2016 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
2017 (char*)pdn
+ pdn
->wDeviceOffset
,
2018 (char*)pdn
+ pdn
->wOutputOffset
,
2020 } else if(lppd
->Flags
& PD_RETURNIC
) {
2021 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
2022 (char*)pdn
+ pdn
->wDeviceOffset
,
2023 (char*)pdn
+ pdn
->wOutputOffset
,
2026 GlobalUnlock(lppd
->hDevNames
);
2027 GlobalUnlock(lppd
->hDevMode
);
2028 return lppd
->hDC
? TRUE
: FALSE
;
2031 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
2033 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2034 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
2036 if(lppd
->Flags
& PD_RETURNDC
) {
2037 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2038 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2039 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2041 } else if(lppd
->Flags
& PD_RETURNIC
) {
2042 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2043 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2044 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2047 GlobalUnlock(lppd
->hDevNames
);
2048 GlobalUnlock(lppd
->hDevMode
);
2049 return lppd
->hDC
? TRUE
: FALSE
;
2052 /***********************************************************************
2053 * PrintDlgA (COMDLG32.@)
2055 * Displays the PRINT dialog box, which enables the user to specify
2056 * specific properties of the print job.
2059 * lppd [IO] ptr to PRINTDLG32 struct
2062 * nonzero if the user pressed the OK button
2063 * zero if the user cancelled the window or an error occurred
2067 * * The Collate Icons do not display, even though they are in the code.
2068 * * The Properties Button(s) should call DocumentPropertiesA().
2071 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2079 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2083 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2084 if(TRACE_ON(commdlg
)) {
2085 char flagstr
[1000] = "";
2086 const struct pd_flags
*pflag
= pd_flags
;
2087 for( ; pflag
->name
; pflag
++) {
2088 if(lppd
->Flags
& pflag
->flag
)
2089 strcat(flagstr
, pflag
->name
);
2091 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2092 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2093 "flags %08x (%s)\n",
2094 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2095 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2096 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2099 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2100 WARN("structure size failure !!!\n");
2101 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2105 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2106 PRINTER_INFO_2A
*pbuf
;
2107 DRIVER_INFO_3A
*dbuf
;
2111 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2112 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2113 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2116 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2117 WARN("Can't find default printer\n");
2118 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2122 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2123 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2124 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2126 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2127 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2128 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2129 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2130 GetLastError(),pbuf
->pPrinterName
);
2131 HeapFree(GetProcessHeap(), 0, dbuf
);
2132 HeapFree(GetProcessHeap(), 0, pbuf
);
2133 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2138 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2142 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2143 pbuf
->pDevMode
->dmDriverExtra
);
2144 ptr
= GlobalLock(lppd
->hDevMode
);
2145 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2146 pbuf
->pDevMode
->dmDriverExtra
);
2147 GlobalUnlock(lppd
->hDevMode
);
2148 HeapFree(GetProcessHeap(), 0, pbuf
);
2149 HeapFree(GetProcessHeap(), 0, dbuf
);
2153 PRINT_PTRA
*PrintStructures
;
2155 /* load Dialog resources,
2156 * depending on Flags indicates Print32 or Print32_setup dialog
2158 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2160 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2163 ptr
= LockResource( hDlgTmpl
);
2165 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2169 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2170 sizeof(PRINT_PTRA
));
2171 PrintStructures
->lpPrintDlg
= lppd
;
2173 /* and create & process the dialog .
2174 * -1 is failure, 0 is broken hwnd, everything else is ok.
2176 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2178 (LPARAM
)PrintStructures
));
2181 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2182 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2183 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2185 if (lppd
->hDevMode
== 0) {
2186 TRACE(" No hDevMode yet... Need to create my own\n");
2187 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2188 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2190 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2191 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2194 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2195 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2197 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2202 GlobalUnlock(lppd
->hDevMode
);
2204 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2205 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2206 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2207 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2209 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2210 bRet
= PRINTDLG_CreateDCA(lppd
);
2212 TRACE("exit! (%d)\n", bRet
);
2216 /***********************************************************************
2217 * PrintDlgW (COMDLG32.@)
2221 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2229 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2233 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2234 if(TRACE_ON(commdlg
)) {
2235 char flagstr
[1000] = "";
2236 const struct pd_flags
*pflag
= pd_flags
;
2237 for( ; pflag
->name
; pflag
++) {
2238 if(lppd
->Flags
& pflag
->flag
)
2239 strcat(flagstr
, pflag
->name
);
2241 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2242 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2243 "flags %08x (%s)\n",
2244 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2245 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2246 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2249 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2250 WARN("structure size failure !!!\n");
2251 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2255 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2256 PRINTER_INFO_2W
*pbuf
;
2257 DRIVER_INFO_3W
*dbuf
;
2261 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2262 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2263 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2266 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2267 WARN("Can't find default printer\n");
2268 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2272 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2273 pbuf
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*needed
);
2274 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2276 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2277 dbuf
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
2278 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2279 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2280 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2281 HeapFree(GetProcessHeap(), 0, dbuf
);
2282 HeapFree(GetProcessHeap(), 0, pbuf
);
2283 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2288 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2292 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2293 pbuf
->pDevMode
->dmDriverExtra
);
2294 ptr
= GlobalLock(lppd
->hDevMode
);
2295 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2296 pbuf
->pDevMode
->dmDriverExtra
);
2297 GlobalUnlock(lppd
->hDevMode
);
2298 HeapFree(GetProcessHeap(), 0, pbuf
);
2299 HeapFree(GetProcessHeap(), 0, dbuf
);
2303 PRINT_PTRW
*PrintStructures
;
2305 /* load Dialog resources,
2306 * depending on Flags indicates Print32 or Print32_setup dialog
2308 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2310 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2313 ptr
= LockResource( hDlgTmpl
);
2315 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2319 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2320 sizeof(PRINT_PTRW
));
2321 PrintStructures
->lpPrintDlg
= lppd
;
2323 /* and create & process the dialog .
2324 * -1 is failure, 0 is broken hwnd, everything else is ok.
2326 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2328 (LPARAM
)PrintStructures
));
2331 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2332 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2333 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2335 if (lppd
->hDevMode
== 0) {
2336 TRACE(" No hDevMode yet... Need to create my own\n");
2337 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2338 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2341 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2342 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2344 GlobalUnlock(lppd
->hDevMode
);
2345 TRACE("Now got %d locks\n", locks
);
2348 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2349 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2352 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2353 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2355 if (lppd
->hDevNames
!= 0) {
2357 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2358 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2360 GlobalUnlock(lppd
->hDevNames
);
2363 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2368 GlobalUnlock(lppd
->hDevMode
);
2370 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2371 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2372 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2373 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2375 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2376 bRet
= PRINTDLG_CreateDCW(lppd
);
2378 TRACE("exit! (%d)\n", bRet
);
2382 /***********************************************************************
2387 * cmb1 - printer select (not in standard dialog template)
2389 * cmb3 - source (tray?)
2390 * edt4 - border left
2392 * edt6 - border right
2393 * edt7 - border bottom
2394 * psh3 - "Printer..."
2398 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2400 HWND hDlg
; /* Page Setup dialog handler */
2401 PAGESETUPDLGA curdlg
; /* Stores the current dialog state */
2402 RECT rtDrawRect
; /* Drawing rect for page */
2406 LPPAGESETUPDLGW dlgw
;
2408 PAGESETUPDLGW curdlg
; /* Current dialog state */
2412 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2417 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2418 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2419 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2420 hResInfo
= FindResourceA(lppd
->hInstance
,
2421 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2422 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2424 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2425 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2430 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2435 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2436 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2437 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2438 hResInfo
= FindResourceW(lppd
->hInstance
,
2439 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2440 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2442 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2443 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2449 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2450 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2451 return 10*size
*100/254;
2452 /* If we don't have a flag, we can choose one. Use millimeters
2453 * to avoid confusing me
2455 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2461 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2462 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2464 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2465 return (size
*254)/100;
2466 /* if we don't have a flag, we can choose one. Use millimeters
2467 * to avoid confusing me
2469 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2470 return (size
*254)/100;
2474 _c_size2strA(PageSetupDataA
*pda
,DWORD size
,LPSTR strout
) {
2475 strcpy(strout
,"<undef>");
2476 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2477 sprintf(strout
,"%d",(size
)/100);
2480 if (pda
->dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2481 sprintf(strout
,"%din",(size
)/1000);
2484 pda
->dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2485 sprintf(strout
,"%d",(size
)/100);
2489 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2490 static const char mm_fmt
[] = "%.2f mm";
2491 static const char in_fmt
[] = "%.2f in";
2493 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2494 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2495 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2496 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2498 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2499 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2502 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2506 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2511 if (!sscanf(strin
,"%f%s",&val
,rest
))
2514 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2515 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2518 return val
*25.4*100;
2520 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2521 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2523 if (!strcmp(rest
,"mm")) {
2524 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2527 return 1000.0*val
/25.4;
2529 if (rest
[0]=='\0') {
2530 /* use application supplied default */
2531 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2535 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2540 ERR("Did not find a conversion for type '%s'!\n",rest
);
2546 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2549 /* this W -> A transition is OK */
2550 /* we need a unicode version of sscanf to avoid it */
2551 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2552 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2556 /****************************************************************************
2557 * PRINTDLG_PS_UpdateDlgStructA
2559 * Updates pda->dlga structure
2560 * Function calls when user presses OK button
2563 * hDlg [in] main window dialog HANDLE
2564 * pda [in/out] ptr to PageSetupDataA structure
2570 PRINTDLG_PS_UpdateDlgStructA(HWND hDlg
, PageSetupDataA
*pda
) {
2575 memcpy(pda
->dlga
, &pda
->curdlg
, sizeof(pda
->curdlg
));
2576 pda
->dlga
->hDevMode
= pda
->pdlg
.hDevMode
;
2577 pda
->dlga
->hDevNames
= pda
->pdlg
.hDevNames
;
2579 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2580 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2582 /* Save paper orientation into device context */
2583 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
)
2584 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2586 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2588 /* Save paper size into the device context */
2589 paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2590 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2591 if (paperword
!= CB_ERR
)
2592 dm
->u1
.s1
.dmPaperSize
= paperword
;
2594 FIXME("could not get dialog text for papersize cmbbox?\n");
2596 /* Save paper source into the device context */
2597 paperword
= SendDlgItemMessageA(hDlg
,cmb1
,CB_GETITEMDATA
,
2598 SendDlgItemMessageA(hDlg
, cmb1
, CB_GETCURSEL
, 0, 0), 0);
2599 if (paperword
!= CB_ERR
)
2600 dm
->u1
.s1
.dmDefaultSource
= paperword
;
2602 FIXME("could not get dialog text for papersize cmbbox?\n");
2604 GlobalUnlock(pda
->pdlg
.hDevNames
);
2605 GlobalUnlock(pda
->pdlg
.hDevMode
);
2611 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2614 LPWSTR devname
,portname
;
2615 WCHAR papername
[64];
2618 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2619 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2620 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2621 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2623 /* Save paper size into device context */
2624 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2625 /* Save paper source into device context */
2626 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2628 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2629 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2630 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2631 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2633 FIXME("could not get dialog text for papersize cmbbox?\n");
2634 #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); }
2635 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2636 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2637 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2638 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2641 /* If we are in landscape, swap x and y of page size */
2642 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2644 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2645 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2646 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2649 /* Save orientation */
2650 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2651 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2653 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2655 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2656 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2660 /**********************************************************************************************
2661 * PRINTDLG_PS_ChangeActivePrinerA
2663 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2666 * name [in] Name of a printer for activation
2667 * pda [in/out] ptr to PageSetupDataA structure
2674 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2677 LPPRINTER_INFO_2A lpPrinterInfo
;
2678 LPDRIVER_INFO_3A lpDriverInfo
;
2679 DEVMODEA
*pDevMode
, *dm
;
2681 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2682 ERR("Can't open printer %s\n", name
);
2685 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2686 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2687 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2688 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2689 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2690 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2691 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2692 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2693 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2698 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2700 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2701 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2702 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2705 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2706 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2708 pda
->pdlg
.hDevMode
= GlobalReAlloc(pda
->pdlg
.hDevMode
,
2709 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2711 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2712 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2714 PRINTDLG_CreateDevNames(&(pda
->pdlg
.hDevNames
),
2715 lpDriverInfo
->pDriverPath
,
2716 lpPrinterInfo
->pPrinterName
,
2717 lpPrinterInfo
->pPortName
);
2719 GlobalUnlock(pda
->pdlg
.hDevMode
);
2720 HeapFree(GetProcessHeap(), 0, pDevMode
);
2721 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2722 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2726 /****************************************************************************************
2727 * PRINTDLG_PS_ChangePrinterA
2729 * Fills Printers, Paper and Source combo
2735 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2738 LPSTR devname
,portname
;
2740 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2741 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2742 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2743 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2744 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2745 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2746 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2747 GlobalUnlock(pda
->pdlg
.hDevNames
);
2748 GlobalUnlock(pda
->pdlg
.hDevMode
);
2752 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2754 WCHAR PaperName
[64];
2756 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2757 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2758 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2759 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2761 if(IsDlgButtonChecked(hDlg
, rad2
))
2763 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2764 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2765 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2769 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2774 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2779 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2780 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2782 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2784 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2787 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2789 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2793 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2796 LPWSTR devname
,portname
;
2798 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2799 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2800 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2801 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2802 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2803 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2805 /* Landscape orientation */
2806 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2807 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2808 else /* this is default if papersize is not set */
2809 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2811 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2812 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2814 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2819 /******************************************************************************************
2820 * PRINTDLG_PS_ChangePaperPrev
2822 * Changes paper preview size / position
2825 * pda [i] Pointer for current PageSetupDataA structure
2831 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2833 LONG width
, height
, x
, y
;
2836 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) {
2837 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2838 height
= pda
->curdlg
.ptPaperSize
.y
* width
/ pda
->curdlg
.ptPaperSize
.x
;
2840 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2841 width
= pda
->curdlg
.ptPaperSize
.x
* height
/ pda
->curdlg
.ptPaperSize
.y
;
2843 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2844 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2845 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2846 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2847 x
, y
, width
, height
);
2850 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2851 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2852 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2853 rtTmp
= pda
->rtDrawRect
;
2854 rtTmp
.right
+= SHADOW
;
2855 rtTmp
.bottom
+= SHADOW
;
2858 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2862 #define GETVAL(idc,val) \
2863 if(msg == EN_CHANGE){ \
2864 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2865 val = _c_str2sizeA(pda->dlga,buf); \
2867 FIXME("could not get dlgitemtexta for %x\n",id); \
2870 /********************************************************************************
2871 * PRINTDLG_PS_WMCommandA
2872 * process WM_COMMAND message for PageSetupDlgA
2875 * hDlg [in] Main dialog HANDLE
2876 * wParam [in] WM_COMMAND wParam
2877 * lParam [in] WM_COMMAND lParam
2878 * pda [in/out] ptr to PageSetupDataA
2882 PRINTDLG_PS_WMCommandA(
2883 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2885 WORD msg
= HIWORD(wParam
);
2886 WORD id
= LOWORD(wParam
);
2889 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2890 LOWORD(lParam
),wParam
,lParam
);
2893 if (!PRINTDLG_PS_UpdateDlgStructA(hDlg
, pda
))
2895 EndDialog(hDlg
, TRUE
);
2899 EndDialog(hDlg
, FALSE
);
2903 pda
->pdlg
.Flags
= 0;
2904 pda
->pdlg
.hwndOwner
= hDlg
;
2905 if (PrintDlgA(&(pda
->pdlg
)))
2906 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2911 if((id
== rad1
&& pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) ||
2912 (id
== rad2
&& pda
->curdlg
.ptPaperSize
.y
> pda
->curdlg
.ptPaperSize
.x
))
2916 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2918 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2919 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2921 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2922 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2923 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2924 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2926 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2927 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2928 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2929 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2931 PRINTDLG_PS_ChangePaperPrev(pda
);
2934 case cmb1
: /* Printer combo */
2935 if(msg
== CBN_SELCHANGE
){
2936 char crPrinterName
[256];
2937 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2938 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2939 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2942 case cmb2
: /* Paper combo */
2943 if(msg
== CBN_SELCHANGE
){
2944 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2945 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2946 if (paperword
!= CB_ERR
) {
2947 PRINTDLG_PaperSizeA(&(pda
->pdlg
), paperword
,&(pda
->curdlg
.ptPaperSize
));
2948 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.x
);
2949 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.y
);
2951 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2952 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2953 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2954 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2956 PRINTDLG_PS_ChangePaperPrev(pda
);
2958 FIXME("could not get dialog text for papersize cmbbox?\n");
2962 if(msg
== CBN_SELCHANGE
){
2963 DEVMODEA
*dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2964 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2965 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2966 GlobalUnlock(pda
->pdlg
.hDevMode
);
2969 case psh2
: /* Printer Properties button */
2972 char PrinterName
[256];
2977 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2978 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2979 FIXME("Call to OpenPrinter did not succeed!\n");
2982 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2983 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2984 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2985 ClosePrinter(hPrinter
);
2986 /* Changing paper */
2987 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &(pda
->curdlg
.ptPaperSize
));
2988 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
2989 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
2990 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
2991 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2992 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2993 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2994 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2997 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2998 /* Changing paper preview */
2999 PRINTDLG_PS_ChangePaperPrev(pda
);
3000 /* Selecting paper in combo */
3001 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
3002 if(count
!= CB_ERR
){
3003 for(i
=0; i
<count
; ++i
){
3004 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
3005 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
3011 GlobalUnlock(pda
->pdlg
.hDevMode
);
3015 GETVAL(id
, pda
->curdlg
.rtMargin
.left
);
3018 GETVAL(id
, pda
->curdlg
.rtMargin
.top
);
3021 GETVAL(id
, pda
->curdlg
.rtMargin
.right
);
3024 GETVAL(id
, pda
->curdlg
.rtMargin
.bottom
);
3027 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3033 PRINTDLG_PS_WMCommandW(
3034 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3036 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3037 LOWORD(lParam
),wParam
,lParam
);
3038 switch (LOWORD(wParam
)) {
3040 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3042 EndDialog(hDlg
, TRUE
);
3046 EndDialog(hDlg
, FALSE
);
3051 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3052 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3056 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3058 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3059 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3061 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3062 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3063 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3064 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3066 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3067 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3068 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3069 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3074 pdw
->pdlg
.Flags
= 0;
3075 pdw
->pdlg
.hwndOwner
= hDlg
;
3076 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3077 if (PrintDlgW(&(pdw
->pdlg
)))
3078 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3086 /***********************************************************************
3087 * DefaultPagePaintHook
3088 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3089 * whenever the sample page is redrawn.
3093 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3094 const PageSetupDataA
*pda
)
3096 LPRECT lprc
= (LPRECT
) lParam
;
3097 HDC hdc
= (HDC
) wParam
;
3100 HFONT hfont
, holdfont
;
3102 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3103 /* Call user paint hook if enable */
3104 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3105 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3109 /* LPPAGESETUPDLG in lParam */
3110 case WM_PSD_PAGESETUPDLG
:
3111 /* Inform about the sample page rectangle */
3112 case WM_PSD_FULLPAGERECT
:
3113 /* Inform about the margin rectangle */
3114 case WM_PSD_MINMARGINRECT
:
3117 /* Draw dashed rectangle showing margins */
3118 case WM_PSD_MARGINRECT
:
3119 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3120 holdpen
= SelectObject(hdc
, hpen
);
3121 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3122 DeleteObject(SelectObject(hdc
, holdpen
));
3124 /* Draw the fake document */
3125 case WM_PSD_GREEKTEXTRECT
:
3126 /* select a nice scalable font, because we want the text really small */
3127 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3128 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3129 hfont
= CreateFontIndirectW(&lf
);
3130 holdfont
= SelectObject(hdc
, hfont
);
3132 /* if text not loaded, then do so now */
3133 if (wszFakeDocumentText
[0] == '\0')
3134 LoadStringW(COMDLG32_hInstance
,
3136 wszFakeDocumentText
,
3137 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3139 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3140 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3141 SetBkMode(hdc
, oldbkmode
);
3143 DeleteObject(SelectObject(hdc
, holdfont
));
3146 /* Envelope stamp */
3147 case WM_PSD_ENVSTAMPRECT
:
3148 /* Return address */
3149 case WM_PSD_YAFULLPAGERECT
:
3150 FIXME("envelope/stamp is not implemented\n");
3153 FIXME("Unknown message %x\n",uMsg
);
3159 /***********************************************************************
3161 * The main paint procedure for the PageSetupDlg function.
3162 * The Page Setup dialog box includes an image of a sample page that shows how
3163 * the user's selections affect the appearance of the printed output.
3164 * The image consists of a rectangle that represents the selected paper
3165 * or envelope type, with a dotted-line rectangle representing
3166 * the current margins, and partial (Greek text) characters
3167 * to show how text looks on the printed page.
3169 * The following messages in the order sends to user hook procedure:
3170 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3171 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3172 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3173 * WM_PSD_MARGINRECT Draw the margin rectangle
3174 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3175 * If any of first three messages returns TRUE, painting done.
3178 * hWnd [in] Handle to the Page Setup dialog box
3179 * uMsg [in] Received message
3182 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3183 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3186 * FALSE if all done correctly
3191 static LRESULT CALLBACK
3192 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3195 RECT rcClient
, rcMargin
;
3198 HBRUSH hbrush
, holdbrush
;
3199 PageSetupDataA
*pda
;
3200 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3201 double scalx
, scaly
;
3202 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3204 if (uMsg
!= WM_PAINT
)
3205 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3207 /* Processing WM_PAINT message */
3208 pda
= (PageSetupDataA
*)GetPropA(hWnd
, "__WINE_PAGESETUPDLGDATA");
3210 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3213 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3216 hdc
= BeginPaint(hWnd
, &ps
);
3217 GetClientRect(hWnd
, &rcClient
);
3219 scalx
= rcClient
.right
/ (double)pda
->curdlg
.ptPaperSize
.x
;
3220 scaly
= rcClient
.bottom
/ (double)pda
->curdlg
.ptPaperSize
.y
;
3221 rcMargin
= rcClient
;
3223 rcMargin
.left
+= pda
->curdlg
.rtMargin
.left
* scalx
;
3224 rcMargin
.top
+= pda
->curdlg
.rtMargin
.top
* scalx
;
3225 rcMargin
.right
-= pda
->curdlg
.rtMargin
.right
* scaly
;
3226 rcMargin
.bottom
-= pda
->curdlg
.rtMargin
.bottom
* scaly
;
3228 /* if the space is too small then we make sure to not draw anything */
3229 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3230 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3232 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3233 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3235 /* fill background */
3236 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3237 FillRect(hdc
, &rcClient
, hbrush
);
3238 holdbrush
= SelectObject(hdc
, hbrush
);
3240 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3241 holdpen
= SelectObject(hdc
, hpen
);
3243 /* paint left edge */
3244 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3245 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3247 /* paint top edge */
3248 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3249 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3251 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3252 DeleteObject(SelectObject(hdc
, hpen
));
3254 /* paint right edge */
3255 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3256 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3258 /* paint bottom edge */
3259 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3260 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3262 DeleteObject(SelectObject(hdc
, holdpen
));
3263 DeleteObject(SelectObject(hdc
, holdbrush
));
3265 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3267 /* give text a bit of a space from the frame */
3270 rcMargin
.right
-= 2;
3271 rcMargin
.bottom
-= 2;
3273 /* if the space is too small then we make sure to not draw anything */
3274 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3275 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3277 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3280 EndPaint(hWnd
, &ps
);
3282 #undef CALLPAINTHOOK
3285 /***********************************************************************
3286 * PRINTDLG_PageDlgProcA
3287 * Message handler for PageSetupDlgA
3289 static INT_PTR CALLBACK
3290 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3293 PageSetupDataA
*pda
;
3294 INT_PTR res
= FALSE
;
3297 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3298 pda
= (PageSetupDataA
*)lParam
;
3299 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3300 pda
->curdlg
= *pda
->dlga
;
3302 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3303 TRACE("set property to %p\n", pda
);
3304 SetPropA(hDlg
, "__WINE_PAGESETUPDLGDATA", pda
);
3305 SetPropA(hDrawWnd
, "__WINE_PAGESETUPDLGDATA", pda
);
3306 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3307 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3308 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3309 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3312 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3314 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3316 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3317 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3318 FIXME("Setup page hook failed?\n");
3321 /* if printer button disabled */
3322 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3323 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3324 /* if margin edit boxes disabled */
3325 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3326 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3327 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3328 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3329 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3331 /* Set orientation radiobutton properly */
3332 if(pda
->dlga
->hDevMode
)
3334 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3335 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3336 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3337 else /* this is default if papersize is not set */
3338 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3339 GlobalUnlock(pda
->dlga
->hDevMode
);
3342 /* if orientation disabled */
3343 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3344 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3345 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3347 /* We fill them out enabled or not */
3348 if (pda
->dlga
->Flags
& PSD_MARGINS
) {
3350 _c_size2strA(pda
,pda
->dlga
->rtMargin
.left
,str
);
3351 SetDlgItemTextA(hDlg
,edt4
,str
);
3352 _c_size2strA(pda
,pda
->dlga
->rtMargin
.top
,str
);
3353 SetDlgItemTextA(hDlg
,edt5
,str
);
3354 _c_size2strA(pda
,pda
->dlga
->rtMargin
.right
,str
);
3355 SetDlgItemTextA(hDlg
,edt6
,str
);
3356 _c_size2strA(pda
,pda
->dlga
->rtMargin
.bottom
,str
);
3357 SetDlgItemTextA(hDlg
,edt7
,str
);
3359 /* default is 1 inch */
3360 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3362 _c_size2strA(pda
,size
,str
);
3363 SetDlgItemTextA(hDlg
,edt4
,str
);
3364 SetDlgItemTextA(hDlg
,edt5
,str
);
3365 SetDlgItemTextA(hDlg
,edt6
,str
);
3366 SetDlgItemTextA(hDlg
,edt7
,str
);
3367 pda
->curdlg
.rtMargin
.left
= size
;
3368 pda
->curdlg
.rtMargin
.top
= size
;
3369 pda
->curdlg
.rtMargin
.right
= size
;
3370 pda
->curdlg
.rtMargin
.bottom
= size
;
3372 /* if paper disabled */
3373 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3374 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3375 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3377 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3378 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3379 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
3381 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3382 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &pda
->curdlg
.ptPaperSize
);
3383 GlobalUnlock(pda
->pdlg
.hDevMode
);
3384 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3385 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3386 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3387 DWORD tmp
= pda
->curdlg
.ptPaperSize
.y
;
3388 pda
->curdlg
.ptPaperSize
.y
= pda
->curdlg
.ptPaperSize
.x
;
3389 pda
->curdlg
.ptPaperSize
.x
= tmp
;
3392 WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda
->pdlg
.hDevMode
);
3393 /* Drawing paper prev */
3394 PRINTDLG_PS_ChangePaperPrev(pda
);
3397 pda
= (PageSetupDataA
*)GetPropA(hDlg
,"__WINE_PAGESETUPDLGDATA");
3399 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3402 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3403 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3404 if (res
) return res
;
3409 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3414 static INT_PTR CALLBACK
3415 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3417 static const WCHAR __WINE_PAGESETUPDLGDATA
[] =
3418 { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
3419 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };
3420 PageSetupDataW
*pdw
;
3423 if (uMsg
==WM_INITDIALOG
) {
3425 pdw
= (PageSetupDataW
*)lParam
;
3426 pdw
->curdlg
= *pdw
->dlgw
;
3427 SetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
, pdw
);
3428 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3429 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3431 FIXME("Setup page hook failed?\n");
3436 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3437 FIXME("PagePaintHook not yet implemented!\n");
3439 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3440 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3441 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3442 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3443 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3444 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3445 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3448 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3450 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3451 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3452 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3454 /* We fill them out enabled or not */
3455 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3457 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3458 SetDlgItemTextW(hDlg
,edt4
,str
);
3459 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3460 SetDlgItemTextW(hDlg
,edt5
,str
);
3461 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3462 SetDlgItemTextW(hDlg
,edt6
,str
);
3463 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3464 SetDlgItemTextW(hDlg
,edt7
,str
);
3466 /* default is 1 inch */
3467 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3469 _c_size2strW(pdw
,size
,str
);
3470 SetDlgItemTextW(hDlg
,edt4
,str
);
3471 SetDlgItemTextW(hDlg
,edt5
,str
);
3472 SetDlgItemTextW(hDlg
,edt6
,str
);
3473 SetDlgItemTextW(hDlg
,edt7
,str
);
3476 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3477 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3478 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3483 pdw
= (PageSetupDataW
*)GetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
);
3485 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3488 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3489 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3490 if (res
) return res
;
3495 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3500 /***********************************************************************
3501 * PageSetupDlgA (COMDLG32.@)
3503 * Displays the PAGE SETUP dialog box, which enables the user to specify
3504 * specific properties of a printed page such as
3505 * size, source, orientation and the width of the page margins.
3508 * setupdlg [IO] PAGESETUPDLGA struct
3511 * TRUE if the user pressed the OK button
3512 * FALSE if the user cancelled the window or an error occurred
3515 * The values of hDevMode and hDevNames are filled on output and can be
3516 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3520 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3524 PageSetupDataA
*pda
;
3527 if (setupdlg
== NULL
) {
3528 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3533 if(TRACE_ON(commdlg
)) {
3534 char flagstr
[1000] = "";
3535 const struct pd_flags
*pflag
= psd_flags
;
3536 for( ; pflag
->name
; pflag
++) {
3537 if(setupdlg
->Flags
& pflag
->flag
) {
3538 strcat(flagstr
, pflag
->name
);
3539 strcat(flagstr
, "|");
3542 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3543 "hinst %p, flags %08x (%s)\n",
3544 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3545 setupdlg
->hDevNames
,
3546 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3549 /* Checking setupdlg structure */
3550 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3551 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3554 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3555 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3556 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3560 /* Initialize default printer struct. If no printer device info is specified
3561 retrieve the default printer data. */
3562 memset(&pdlg
,0,sizeof(pdlg
));
3563 pdlg
.lStructSize
= sizeof(pdlg
);
3564 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3565 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3566 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3568 pdlg
.Flags
= PD_RETURNDEFAULT
;
3569 bRet
= PrintDlgA(&pdlg
);
3571 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3573 LoadStringA(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3574 MessageBoxA(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3580 /* short cut exit, just return default values */
3581 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3584 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3585 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3586 dm
= GlobalLock(pdlg
.hDevMode
);
3587 PRINTDLG_PaperSizeA(&pdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3588 GlobalUnlock(pdlg
.hDevMode
);
3589 setupdlg
->ptPaperSize
.x
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.x
);
3590 setupdlg
->ptPaperSize
.y
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.y
);
3594 /* get dialog template */
3595 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3597 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3600 ptr
= LockResource( hDlgTmpl
);
3602 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3606 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3607 pda
->dlga
= setupdlg
;
3610 bRet
= (0<DialogBoxIndirectParamA(
3611 setupdlg
->hInstance
,
3613 setupdlg
->hwndOwner
,
3614 PRINTDLG_PageDlgProcA
,
3618 HeapFree(GetProcessHeap(),0,pda
);
3621 /***********************************************************************
3622 * PageSetupDlgW (COMDLG32.@)
3624 * See PageSetupDlgA.
3626 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3630 PageSetupDataW
*pdw
;
3633 FIXME("Unicode implementation is not done yet\n");
3635 if (setupdlg
== NULL
) {
3636 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3640 if(TRACE_ON(commdlg
)) {
3641 char flagstr
[1000] = "";
3642 const struct pd_flags
*pflag
= psd_flags
;
3643 for( ; pflag
->name
; pflag
++) {
3644 if(setupdlg
->Flags
& pflag
->flag
) {
3645 strcat(flagstr
, pflag
->name
);
3646 strcat(flagstr
, "|");
3649 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3650 "hinst %p, flags %08x (%s)\n",
3651 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3652 setupdlg
->hDevNames
,
3653 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3656 /* Initialize default printer struct. If no printer device info is specified
3657 retrieve the default printer data. */
3658 memset(&pdlg
,0,sizeof(pdlg
));
3659 pdlg
.lStructSize
= sizeof(pdlg
);
3660 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3661 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3662 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3664 pdlg
.Flags
= PD_RETURNDEFAULT
;
3665 bRet
= PrintDlgW(&pdlg
);
3667 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3669 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3670 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3676 /* short cut exit, just return default values */
3677 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3678 static const WCHAR a4
[] = {'A','4',0};
3679 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3680 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3681 /* FIXME: Just return "A4" for now. */
3682 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3683 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3684 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3687 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3689 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3692 ptr
= LockResource( hDlgTmpl
);
3694 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3697 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3698 pdw
->dlgw
= setupdlg
;
3701 bRet
= (0<DialogBoxIndirectParamW(
3702 setupdlg
->hInstance
,
3704 setupdlg
->hwndOwner
,
3711 /***********************************************************************
3712 * PrintDlgExA (COMDLG32.@)
3720 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3723 FIXME("(%p) stub\n", lppd
);
3724 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3725 return E_INVALIDARG
;
3728 if (!IsWindow(lppd
->hwndOwner
)) {
3735 /***********************************************************************
3736 * PrintDlgExW (COMDLG32.@)
3738 * Display the property sheet style PRINT dialog box
3741 * lppd [IO] ptr to PRINTDLGEX struct
3745 * Failure: One of the following COM error codes:
3746 * E_OUTOFMEMORY Insufficient memory.
3747 * E_INVALIDARG One or more arguments are invalid.
3748 * E_POINTER Invalid pointer.
3749 * E_HANDLE Invalid handle.
3750 * E_FAIL Unspecified error.
3753 * This Dialog enables the user to specify specific properties of the print job.
3754 * The property sheet can also have additional application-specific and
3755 * driver-specific property pages.
3761 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3764 FIXME("(%p) stub\n", lppd
);
3765 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3766 return E_INVALIDARG
;
3769 if (!IsWindow(lppd
->hwndOwner
)) {