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];
78 static const WCHAR pd32_collateW
[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
79 static const WCHAR pd32_nocollateW
[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
80 static const WCHAR pd32_portraitW
[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
81 static const WCHAR pd32_landscapeW
[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
82 static const WCHAR printdlg_prop
[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
83 static const WCHAR pagesetupdlg_prop
[] = { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
84 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };
86 /***********************************************************************
87 * PRINTDLG_OpenDefaultPrinter
89 * Returns a winspool printer handle to the default printer in *hprn
90 * Caller must call ClosePrinter on the handle
92 * Returns TRUE on success else FALSE
94 BOOL
PRINTDLG_OpenDefaultPrinter(HANDLE
*hprn
)
97 DWORD dwBufLen
= sizeof(buf
) / sizeof(buf
[0]);
99 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
101 res
= OpenPrinterW(buf
, hprn
, NULL
);
103 WARN("Could not open printer %s\n", debugstr_w(buf
));
107 /***********************************************************************
108 * PRINTDLG_SetUpPrinterListCombo
110 * Initializes printer list combox.
111 * hDlg: HWND of dialog
112 * id: Control id of combo
113 * name: Name of printer to select
115 * Initializes combo with list of available printers. Selects printer 'name'
116 * If name is NULL or does not exist select the default printer.
118 * Returns number of printers added to list.
120 INT
PRINTDLG_SetUpPrinterListComboA(HWND hDlg
, UINT id
, LPCSTR name
)
124 LPPRINTER_INFO_2A pi
;
125 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
126 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
127 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
130 SendDlgItemMessageA(hDlg
, id
, CB_RESETCONTENT
, 0, 0);
132 for(i
= 0; i
< num
; i
++) {
133 SendDlgItemMessageA(hDlg
, id
, CB_ADDSTRING
, 0,
134 (LPARAM
)pi
[i
].pPrinterName
);
136 HeapFree(GetProcessHeap(), 0, pi
);
138 (i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
139 (LPARAM
)name
)) == CB_ERR
) {
142 DWORD dwBufLen
= sizeof(buf
);
144 WARN("Can't find %s in printer list so trying to find default\n",
146 if(!GetDefaultPrinterA(buf
, &dwBufLen
))
148 i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
150 FIXME("Can't find default printer in printer list\n");
152 SendDlgItemMessageA(hDlg
, id
, CB_SETCURSEL
, i
, 0);
156 static INT
PRINTDLG_SetUpPrinterListComboW(HWND hDlg
, UINT id
, LPCWSTR name
)
160 LPPRINTER_INFO_2W pi
;
161 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
162 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
163 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
166 for(i
= 0; i
< num
; i
++) {
167 SendDlgItemMessageW(hDlg
, id
, CB_ADDSTRING
, 0,
168 (LPARAM
)pi
[i
].pPrinterName
);
170 HeapFree(GetProcessHeap(), 0, pi
);
172 (i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
173 (LPARAM
)name
)) == CB_ERR
) {
175 DWORD dwBufLen
= sizeof(buf
)/sizeof(buf
[0]);
177 WARN("Can't find %s in printer list so trying to find default\n",
179 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
181 i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
183 TRACE("Can't find default printer in printer list\n");
185 SendDlgItemMessageW(hDlg
, id
, CB_SETCURSEL
, i
, 0);
189 /***********************************************************************
190 * PRINTDLG_CreateDevNames [internal]
193 * creates a DevNames structure.
195 * (NB. when we handle unicode the offsets will be in wchars).
197 static BOOL
PRINTDLG_CreateDevNames(HGLOBAL
*hmem
, const char* DeviceDriverName
,
198 const char* DeviceName
, const char* OutputPort
)
201 char* pDevNamesSpace
;
203 LPDEVNAMES lpDevNames
;
205 DWORD dwBufLen
= sizeof(buf
);
207 size
= strlen(DeviceDriverName
) + 1
208 + strlen(DeviceName
) + 1
209 + strlen(OutputPort
) + 1
213 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
215 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
219 pDevNamesSpace
= GlobalLock(*hmem
);
220 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
222 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
223 strcpy(pTempPtr
, DeviceDriverName
);
224 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
226 pTempPtr
+= strlen(DeviceDriverName
) + 1;
227 strcpy(pTempPtr
, DeviceName
);
228 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
230 pTempPtr
+= strlen(DeviceName
) + 1;
231 strcpy(pTempPtr
, OutputPort
);
232 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
234 GetDefaultPrinterA(buf
, &dwBufLen
);
235 lpDevNames
->wDefault
= (strcmp(buf
, DeviceName
) == 0) ? 1 : 0;
240 static BOOL
PRINTDLG_CreateDevNamesW(HGLOBAL
*hmem
, LPCWSTR DeviceDriverName
,
241 LPCWSTR DeviceName
, LPCWSTR OutputPort
)
244 LPWSTR pDevNamesSpace
;
246 LPDEVNAMES lpDevNames
;
248 DWORD dwBufLen
= sizeof(bufW
) / sizeof(WCHAR
);
250 size
= sizeof(WCHAR
)*lstrlenW(DeviceDriverName
) + 2
251 + sizeof(WCHAR
)*lstrlenW(DeviceName
) + 2
252 + sizeof(WCHAR
)*lstrlenW(OutputPort
) + 2
256 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
258 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
262 pDevNamesSpace
= GlobalLock(*hmem
);
263 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
265 pTempPtr
= (LPWSTR
)((LPDEVNAMES
)pDevNamesSpace
+ 1);
266 lstrcpyW(pTempPtr
, DeviceDriverName
);
267 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
269 pTempPtr
+= lstrlenW(DeviceDriverName
) + 1;
270 lstrcpyW(pTempPtr
, DeviceName
);
271 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
273 pTempPtr
+= lstrlenW(DeviceName
) + 1;
274 lstrcpyW(pTempPtr
, OutputPort
);
275 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
277 GetDefaultPrinterW(bufW
, &dwBufLen
);
278 lpDevNames
->wDefault
= (lstrcmpW(bufW
, DeviceName
) == 0) ? 1 : 0;
283 /***********************************************************************
284 * PRINTDLG_UpdatePrintDlg [internal]
287 * updates the PrintDlg structure for return values.
290 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
291 * TRUE if successful.
293 static BOOL
PRINTDLG_UpdatePrintDlgA(HWND hDlg
,
294 PRINT_PTRA
* PrintStructures
)
296 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
297 PDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
298 LPPRINTER_INFO_2A pi
= PrintStructures
->lpPrinterInfo
;
302 FIXME("No lpdm ptr?\n");
307 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
308 /* check whether nFromPage and nToPage are within range defined by
309 * nMinPage and nMaxPage
311 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
315 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
316 nToPage
= GetDlgItemInt(hDlg
, edt2
, &translated
, FALSE
);
318 /* if no ToPage value is entered, use the FromPage value */
319 if(!translated
) nToPage
= nFromPage
;
321 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
322 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
323 WCHAR resourcestr
[256];
324 WCHAR resultstr
[256];
325 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
, resourcestr
, 255);
326 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
327 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
, resourcestr
, 255);
328 MessageBoxW(hDlg
, resultstr
, resourcestr
, MB_OK
| MB_ICONWARNING
);
331 lppd
->nFromPage
= nFromPage
;
332 lppd
->nToPage
= nToPage
;
333 lppd
->Flags
|= PD_PAGENUMS
;
336 lppd
->Flags
&= ~PD_PAGENUMS
;
338 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
339 lppd
->Flags
|= PD_SELECTION
;
341 lppd
->Flags
&= ~PD_SELECTION
;
343 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
344 static char file
[] = "FILE:";
345 lppd
->Flags
|= PD_PRINTTOFILE
;
346 pi
->pPortName
= file
;
349 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
350 FIXME("Collate lppd not yet implemented as output\n");
353 /* set PD_Collate and nCopies */
354 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
355 /* The application doesn't support multiple copies or collate...
357 lppd
->Flags
&= ~PD_COLLATE
;
359 /* if the printer driver supports it... store info there
360 * otherwise no collate & multiple copies !
362 if (lpdm
->dmFields
& DM_COLLATE
)
364 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
365 if (lpdm
->dmFields
& DM_COPIES
)
366 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
368 /* Application is responsible for multiple copies */
369 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
370 lppd
->Flags
|= PD_COLLATE
;
372 lppd
->Flags
&= ~PD_COLLATE
;
373 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
374 /* multiple copies already included in the document. Driver must print only one copy */
375 lpdm
->u1
.s1
.dmCopies
= 1;
378 /* Print quality, PrintDlg16 */
379 if(GetDlgItem(hDlg
, cmb1
))
381 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
382 int Sel
= SendMessageA(hQuality
, CB_GETCURSEL
, 0, 0);
386 LONG dpi
= SendMessageA(hQuality
, CB_GETITEMDATA
, Sel
, 0);
387 lpdm
->dmFields
|= DM_PRINTQUALITY
| DM_YRESOLUTION
;
388 lpdm
->u1
.s1
.dmPrintQuality
= LOWORD(dpi
);
389 lpdm
->dmYResolution
= HIWORD(dpi
);
396 static BOOL
PRINTDLG_UpdatePrintDlgW(HWND hDlg
,
397 PRINT_PTRW
* PrintStructures
)
399 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
400 PDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
401 LPPRINTER_INFO_2W pi
= PrintStructures
->lpPrinterInfo
;
405 FIXME("No lpdm ptr?\n");
410 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
411 /* check whether nFromPage and nToPage are within range defined by
412 * nMinPage and nMaxPage
414 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
418 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
419 nToPage
= GetDlgItemInt(hDlg
, edt2
, &translated
, FALSE
);
421 /* if no ToPage value is entered, use the FromPage value */
422 if(!translated
) nToPage
= nFromPage
;
424 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
425 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
426 WCHAR resourcestr
[256];
427 WCHAR resultstr
[256];
428 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
430 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
431 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
433 MessageBoxW(hDlg
, resultstr
, resourcestr
,
434 MB_OK
| MB_ICONWARNING
);
437 lppd
->nFromPage
= nFromPage
;
438 lppd
->nToPage
= nToPage
;
439 lppd
->Flags
|= PD_PAGENUMS
;
442 lppd
->Flags
&= ~PD_PAGENUMS
;
444 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
445 lppd
->Flags
|= PD_SELECTION
;
447 lppd
->Flags
&= ~PD_SELECTION
;
449 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
450 static WCHAR file
[] = {'F','I','L','E',':',0};
451 lppd
->Flags
|= PD_PRINTTOFILE
;
452 pi
->pPortName
= file
;
455 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
456 FIXME("Collate lppd not yet implemented as output\n");
459 /* set PD_Collate and nCopies */
460 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
461 /* The application doesn't support multiple copies or collate...
463 lppd
->Flags
&= ~PD_COLLATE
;
465 /* if the printer driver supports it... store info there
466 * otherwise no collate & multiple copies !
468 if (lpdm
->dmFields
& DM_COLLATE
)
470 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
471 if (lpdm
->dmFields
& DM_COPIES
)
472 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
474 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
475 lppd
->Flags
|= PD_COLLATE
;
477 lppd
->Flags
&= ~PD_COLLATE
;
478 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
484 static BOOL
PRINTDLG_PaperSizeW(
485 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
489 LPWSTR devname
,portname
;
493 POINT
*points
= NULL
;
496 dn
= GlobalLock(pdlga
->hDevNames
);
497 dm
= GlobalLock(pdlga
->hDevMode
);
498 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
499 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
502 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
504 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
507 if (NrOfEntries
== -1) {
508 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
512 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
513 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
514 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
517 for (i
=0;i
<NrOfEntries
;i
++)
518 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
520 if (i
==NrOfEntries
) {
521 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
524 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
525 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
526 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
529 /* this is _10ths_ of a millimeter */
534 GlobalUnlock(pdlga
->hDevNames
);
535 GlobalUnlock(pdlga
->hDevMode
);
536 HeapFree(GetProcessHeap(),0,Names
);
537 HeapFree(GetProcessHeap(),0,points
);
542 /************************************************************************
543 * PRINTDLG_SetUpPaperComboBox
545 * Initialize either the papersize or inputslot combos of the Printer Setup
546 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
547 * We also try to re-select the old selection.
549 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
562 int fwCapability_Names
;
563 int fwCapability_Words
;
565 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
567 /* query the dialog box for the current selected value */
568 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
570 /* we enter here only if a different printer is selected after
571 * the Print Setup dialog is opened. The current settings are
572 * stored into the newly selected printer.
574 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
577 if (nIDComboBox
== cmb2
)
578 dm
->u1
.s1
.dmPaperSize
= oldWord
;
580 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
584 /* we enter here only when the Print setup dialog is initially
585 * opened. In this case the settings are restored from when
586 * the dialog was last closed.
589 if (nIDComboBox
== cmb2
)
590 oldWord
= dm
->u1
.s1
.dmPaperSize
;
592 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
596 if (nIDComboBox
== cmb2
) {
598 fwCapability_Names
= DC_PAPERNAMES
;
599 fwCapability_Words
= DC_PAPERS
;
603 fwCapability_Names
= DC_BINNAMES
;
604 fwCapability_Words
= DC_BINS
;
607 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
608 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
610 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
611 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
612 fwCapability_Names
, NULL
, dm
);
613 if (NrOfEntries
== 0)
614 WARN("no Name Entries found!\n");
615 else if (NrOfEntries
< 0)
618 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
620 ERR("Number of caps is different\n");
624 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
625 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
626 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
627 fwCapability_Names
, Names
, dm
);
628 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
629 fwCapability_Words
, (LPSTR
)Words
, dm
);
631 /* reset any current content in the combobox */
632 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
634 /* store new content */
635 for (i
= 0; i
< NrOfEntries
; i
++) {
636 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
637 (LPARAM
)(&Names
[i
*NamesSize
]) );
638 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
642 /* Look for old selection - can't do this is previous loop since
643 item order will change as more items are added */
645 for (i
= 0; i
< NrOfEntries
; i
++) {
646 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
652 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
654 HeapFree(GetProcessHeap(),0,Words
);
655 HeapFree(GetProcessHeap(),0,Names
);
659 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
661 const WCHAR
* PrinterName
,
662 const WCHAR
* PortName
,
672 int fwCapability_Names
;
673 int fwCapability_Words
;
675 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
677 /* query the dialog box for the current selected value */
678 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
680 /* we enter here only if a different printer is selected after
681 * the Print Setup dialog is opened. The current settings are
682 * stored into the newly selected printer.
684 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
687 if (nIDComboBox
== cmb2
)
688 dm
->u1
.s1
.dmPaperSize
= oldWord
;
690 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
694 /* we enter here only when the Print setup dialog is initially
695 * opened. In this case the settings are restored from when
696 * the dialog was last closed.
699 if (nIDComboBox
== cmb2
)
700 oldWord
= dm
->u1
.s1
.dmPaperSize
;
702 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
706 if (nIDComboBox
== cmb2
) {
708 fwCapability_Names
= DC_PAPERNAMES
;
709 fwCapability_Words
= DC_PAPERS
;
713 fwCapability_Names
= DC_BINNAMES
;
714 fwCapability_Words
= DC_BINS
;
717 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
718 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
720 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
721 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
722 fwCapability_Names
, NULL
, dm
);
723 if (NrOfEntries
== 0)
724 WARN("no Name Entries found!\n");
725 else if (NrOfEntries
< 0)
728 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
730 ERR("Number of caps is different\n");
734 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
735 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
736 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
737 fwCapability_Names
, Names
, dm
);
738 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
739 fwCapability_Words
, Words
, dm
);
741 /* reset any current content in the combobox */
742 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
744 /* store new content */
745 for (i
= 0; i
< NrOfEntries
; i
++) {
746 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
747 (LPARAM
)(&Names
[i
*NamesSize
]) );
748 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
752 /* Look for old selection - can't do this is previous loop since
753 item order will change as more items are added */
755 for (i
= 0; i
< NrOfEntries
; i
++) {
756 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
762 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
764 HeapFree(GetProcessHeap(),0,Words
);
765 HeapFree(GetProcessHeap(),0,Names
);
770 /***********************************************************************
771 * PRINTDLG_UpdatePrinterInfoTexts [internal]
773 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
776 char ResourceString
[256];
782 /* add all status messages */
783 for (i
= 0; i
< 25; i
++) {
784 if (pi
->Status
& (1<<i
)) {
785 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
786 ResourceString
, 255);
787 strcat(StatusMsg
,ResourceString
);
791 /* FIXME: status==ready must only be appended if really so.
792 but how to detect? */
793 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
794 ResourceString
, 255);
795 strcat(StatusMsg
,ResourceString
);
796 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
798 /* set all other printer info texts */
799 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
801 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
802 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
804 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
805 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
809 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
811 WCHAR StatusMsg
[256];
812 WCHAR ResourceString
[256];
813 static const WCHAR emptyW
[] = {0};
819 /* add all status messages */
820 for (i
= 0; i
< 25; i
++) {
821 if (pi
->Status
& (1<<i
)) {
822 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
823 ResourceString
, 255);
824 lstrcatW(StatusMsg
,ResourceString
);
828 /* FIXME: status==ready must only be appended if really so.
829 but how to detect? */
830 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
831 ResourceString
, 255);
832 lstrcatW(StatusMsg
,ResourceString
);
833 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
835 /* set all other printer info texts */
836 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
837 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
838 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
840 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
841 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
845 /*******************************************************************
847 * PRINTDLG_ChangePrinter
850 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
851 PRINT_PTRA
*PrintStructures
)
853 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
854 LPDEVMODEA lpdm
= NULL
;
859 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
860 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
861 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
862 ERR("Can't open printer %s\n", name
);
865 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
866 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
867 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
869 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
870 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
871 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
873 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
878 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
880 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
881 PrintStructures
->lpDevMode
= NULL
;
883 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
885 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
888 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
889 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
891 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
892 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
893 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
894 /* Supplied devicemode matches current printer so try to use it */
895 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
896 DM_OUT_BUFFER
| DM_IN_BUFFER
);
899 GlobalUnlock(lppd
->hDevMode
);
901 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
903 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
904 /* Print range (All/Range/Selection) */
905 if(lppd
->nFromPage
!= 0xffff)
906 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
907 if(lppd
->nToPage
!= 0xffff)
908 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
910 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
911 if (lppd
->Flags
& PD_NOSELECTION
)
912 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
914 if (lppd
->Flags
& PD_SELECTION
)
915 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
916 if (lppd
->Flags
& PD_NOPAGENUMS
) {
917 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
918 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
919 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
920 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
921 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
923 if (lppd
->Flags
& PD_PAGENUMS
)
924 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
929 * FIXME: The ico3 is not displayed for some reason. I don't know why.
931 if (lppd
->Flags
& PD_COLLATE
) {
932 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
933 (LPARAM
)PrintStructures
->hCollateIcon
);
934 CheckDlgButton(hDlg
, chx2
, 1);
936 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
937 (LPARAM
)PrintStructures
->hNoCollateIcon
);
938 CheckDlgButton(hDlg
, chx2
, 0);
941 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
942 /* if printer doesn't support it: no Collate */
943 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
944 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
945 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
952 if (lppd
->hDevMode
== 0)
953 copies
= lppd
->nCopies
;
955 copies
= lpdm
->u1
.s1
.dmCopies
;
956 if(copies
== 0) copies
= 1;
957 else if(copies
< 0) copies
= MAX_COPIES
;
958 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
961 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
962 /* if printer doesn't support it: no nCopies */
963 if (!(lpdm
->dmFields
& DM_COPIES
)) {
964 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
965 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
970 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
971 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
972 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
973 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
974 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
976 /* Fill print quality combo, PrintDlg16 */
977 if(GetDlgItem(hDlg
, cmb1
))
979 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
980 PrintStructures
->lpPrinterInfo
->pPortName
,
981 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
983 if(numResolutions
!= -1)
985 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
990 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
991 PrintStructures
->lpPrinterInfo
->pPrinterName
,
994 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
995 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
996 PrintStructures
->lpPrinterInfo
->pPortName
,
997 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
999 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1000 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1001 DeleteDC(hPrinterDC
);
1003 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1004 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1006 BOOL IsDefault
= FALSE
;
1009 if(Resolutions
[i
] == Resolutions
[i
+1])
1011 if(dpiX
== Resolutions
[i
])
1013 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1016 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1018 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1021 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1024 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1026 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1028 HeapFree(GetProcessHeap(), 0, Resolutions
);
1031 } else { /* PD_PRINTSETUP */
1032 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1034 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1035 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1036 PrintStructures
->lpPrinterInfo
->pPortName
,
1038 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1039 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1040 PrintStructures
->lpPrinterInfo
->pPortName
,
1042 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1043 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1044 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1045 PrintStructures
->hLandscapeIcon
));
1050 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1051 /* hide if PD_SHOWHELP not specified */
1052 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1057 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1058 PRINT_PTRW
*PrintStructures
)
1060 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1061 LPDEVMODEW lpdm
= NULL
;
1066 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1067 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1068 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1069 ERR("Can't open printer %s\n", debugstr_w(name
));
1072 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1073 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
1074 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1076 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1077 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
1078 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1080 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1085 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1087 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1088 PrintStructures
->lpDevMode
= NULL
;
1090 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1092 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1095 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1096 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1098 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1099 !lstrcmpW(lpdm
->dmDeviceName
,
1100 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1101 /* Supplied devicemode matches current printer so try to use it */
1102 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1103 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1106 GlobalUnlock(lppd
->hDevMode
);
1108 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1110 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1111 /* Print range (All/Range/Selection) */
1112 if(lppd
->nFromPage
!= 0xffff)
1113 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1114 if(lppd
->nToPage
!= 0xffff)
1115 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1117 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1118 if (lppd
->Flags
& PD_NOSELECTION
)
1119 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1121 if (lppd
->Flags
& PD_SELECTION
)
1122 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1123 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1124 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1125 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1126 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1127 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1128 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1130 if (lppd
->Flags
& PD_PAGENUMS
)
1131 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1136 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1138 if (lppd
->Flags
& PD_COLLATE
) {
1139 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1140 (LPARAM
)PrintStructures
->hCollateIcon
);
1141 CheckDlgButton(hDlg
, chx2
, 1);
1143 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1144 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1145 CheckDlgButton(hDlg
, chx2
, 0);
1148 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1149 /* if printer doesn't support it: no Collate */
1150 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1151 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1152 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1159 if (lppd
->hDevMode
== 0)
1160 copies
= lppd
->nCopies
;
1162 copies
= lpdm
->u1
.s1
.dmCopies
;
1163 if(copies
== 0) copies
= 1;
1164 else if(copies
< 0) copies
= MAX_COPIES
;
1165 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1168 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1169 /* if printer doesn't support it: no nCopies */
1170 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1171 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1172 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1177 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1178 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1179 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1180 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1181 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1183 } else { /* PD_PRINTSETUP */
1184 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1186 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1187 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1188 PrintStructures
->lpPrinterInfo
->pPortName
,
1190 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1191 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1192 PrintStructures
->lpPrinterInfo
->pPortName
,
1194 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1195 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1196 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1197 PrintStructures
->hLandscapeIcon
));
1202 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1203 /* hide if PD_SHOWHELP not specified */
1204 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1209 /***********************************************************************
1210 * check_printer_setup [internal]
1212 static LRESULT
check_printer_setup(HWND hDlg
)
1215 WCHAR resourcestr
[256],resultstr
[256];
1217 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1220 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1226 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1227 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1228 MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1233 /***********************************************************************
1234 * PRINTDLG_WMInitDialog [internal]
1236 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1237 PRINT_PTRA
* PrintStructures
)
1239 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1243 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1245 /* load Collate ICONs */
1246 /* We load these with LoadImage because they are not a standard
1247 size and we don't want them rescaled */
1248 PrintStructures
->hCollateIcon
=
1249 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1250 PrintStructures
->hNoCollateIcon
=
1251 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1253 /* These can be done with LoadIcon */
1254 PrintStructures
->hPortraitIcon
=
1255 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1256 PrintStructures
->hLandscapeIcon
=
1257 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1259 /* display the collate/no_collate icon */
1260 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1261 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1263 if(PrintStructures
->hCollateIcon
== 0 ||
1264 PrintStructures
->hNoCollateIcon
== 0 ||
1265 PrintStructures
->hPortraitIcon
== 0 ||
1266 PrintStructures
->hLandscapeIcon
== 0) {
1267 ERR("no icon in resourcefile\n");
1268 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1269 EndDialog(hDlg
, FALSE
);
1273 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1274 * must be registered and the Help button must be shown.
1276 if (lppd
->Flags
& PD_SHOWHELP
) {
1277 if((PrintStructures
->HelpMessageID
=
1278 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1279 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1283 PrintStructures
->HelpMessageID
= 0;
1285 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1286 PrintStructures
->hwndUpDown
=
1287 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1288 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1289 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1290 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1291 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1294 /* FIXME: I allow more freedom than either Win95 or WinNT,
1295 * which do not agree to what errors should be thrown or not
1296 * in case nToPage or nFromPage is out-of-range.
1298 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1299 lppd
->nMaxPage
= lppd
->nMinPage
;
1300 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1301 lppd
->Flags
|= PD_NOPAGENUMS
;
1302 if (lppd
->nToPage
< lppd
->nMinPage
)
1303 lppd
->nToPage
= lppd
->nMinPage
;
1304 if (lppd
->nToPage
> lppd
->nMaxPage
)
1305 lppd
->nToPage
= lppd
->nMaxPage
;
1306 if (lppd
->nFromPage
< lppd
->nMinPage
)
1307 lppd
->nFromPage
= lppd
->nMinPage
;
1308 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1309 lppd
->nFromPage
= lppd
->nMaxPage
;
1311 /* if we have the combo box, fill it */
1312 if (GetDlgItem(hDlg
,comboID
)) {
1315 pdn
= GlobalLock(lppd
->hDevNames
);
1316 pdm
= GlobalLock(lppd
->hDevMode
);
1318 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1320 name
= (char*)pdm
->dmDeviceName
;
1321 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1322 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1323 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1325 /* Now find selected printer and update rest of dlg */
1326 name
= HeapAlloc(GetProcessHeap(),0,256);
1327 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1328 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1329 HeapFree(GetProcessHeap(),0,name
);
1331 /* else use default printer */
1333 DWORD dwBufLen
= sizeof(name
);
1334 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1337 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1339 FIXME("No default printer found, expect problems!\n");
1344 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1345 PRINT_PTRW
* PrintStructures
)
1347 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1351 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1353 /* load Collate ICONs */
1354 /* We load these with LoadImage because they are not a standard
1355 size and we don't want them rescaled */
1356 PrintStructures
->hCollateIcon
=
1357 LoadImageW(COMDLG32_hInstance
, pd32_collateW
, IMAGE_ICON
, 0, 0, 0);
1358 PrintStructures
->hNoCollateIcon
=
1359 LoadImageW(COMDLG32_hInstance
, pd32_nocollateW
, IMAGE_ICON
, 0, 0, 0);
1361 /* These can be done with LoadIcon */
1362 PrintStructures
->hPortraitIcon
=
1363 LoadIconW(COMDLG32_hInstance
, pd32_portraitW
);
1364 PrintStructures
->hLandscapeIcon
=
1365 LoadIconW(COMDLG32_hInstance
, pd32_landscapeW
);
1367 /* display the collate/no_collate icon */
1368 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1369 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1371 if(PrintStructures
->hCollateIcon
== 0 ||
1372 PrintStructures
->hNoCollateIcon
== 0 ||
1373 PrintStructures
->hPortraitIcon
== 0 ||
1374 PrintStructures
->hLandscapeIcon
== 0) {
1375 ERR("no icon in resourcefile\n");
1376 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1377 EndDialog(hDlg
, FALSE
);
1381 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1382 * must be registered and the Help button must be shown.
1384 if (lppd
->Flags
& PD_SHOWHELP
) {
1385 if((PrintStructures
->HelpMessageID
=
1386 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1387 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1391 PrintStructures
->HelpMessageID
= 0;
1393 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1394 PrintStructures
->hwndUpDown
=
1395 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1396 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1397 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1398 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1399 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1402 /* FIXME: I allow more freedom than either Win95 or WinNT,
1403 * which do not agree to what errors should be thrown or not
1404 * in case nToPage or nFromPage is out-of-range.
1406 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1407 lppd
->nMaxPage
= lppd
->nMinPage
;
1408 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1409 lppd
->Flags
|= PD_NOPAGENUMS
;
1410 if (lppd
->nToPage
< lppd
->nMinPage
)
1411 lppd
->nToPage
= lppd
->nMinPage
;
1412 if (lppd
->nToPage
> lppd
->nMaxPage
)
1413 lppd
->nToPage
= lppd
->nMaxPage
;
1414 if (lppd
->nFromPage
< lppd
->nMinPage
)
1415 lppd
->nFromPage
= lppd
->nMinPage
;
1416 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1417 lppd
->nFromPage
= lppd
->nMaxPage
;
1419 /* if we have the combo box, fill it */
1420 if (GetDlgItem(hDlg
,comboID
)) {
1423 pdn
= GlobalLock(lppd
->hDevNames
);
1424 pdm
= GlobalLock(lppd
->hDevMode
);
1426 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1428 name
= pdm
->dmDeviceName
;
1429 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1430 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1431 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1433 /* Now find selected printer and update rest of dlg */
1434 /* ansi is ok here */
1435 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1436 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1437 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1438 HeapFree(GetProcessHeap(),0,name
);
1440 /* else use default printer */
1442 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1443 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1446 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1448 FIXME("No default printer found, expect problems!\n");
1453 /***********************************************************************
1454 * PRINTDLG_WMCommand [internal]
1456 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1457 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1459 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1460 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1461 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1463 switch (LOWORD(wParam
)) {
1465 TRACE(" OK button was hit\n");
1466 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1467 FIXME("Update printdlg was not successful!\n");
1470 EndDialog(hDlg
, TRUE
);
1474 TRACE(" CANCEL button was hit\n");
1475 EndDialog(hDlg
, FALSE
);
1479 TRACE(" HELP button was hit\n");
1480 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1481 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1484 case chx2
: /* collate pages checkbox */
1485 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1486 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1487 (LPARAM
)PrintStructures
->hCollateIcon
);
1489 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1490 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1492 case edt1
: /* from page nr editbox */
1493 case edt2
: /* to page nr editbox */
1494 if (HIWORD(wParam
)==EN_CHANGE
) {
1497 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1498 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1499 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1500 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1505 if(HIWORD(wParam
) == EN_CHANGE
) {
1506 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1508 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1510 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1515 case psh1
: /* Print Setup */
1519 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1520 FIXME("The 32bit print dialog does not have this button!?\n");
1524 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1525 pdlg
.Flags
|= PD_PRINTSETUP
;
1526 pdlg
.hwndOwner
= HWND_16(hDlg
);
1527 if (!PrintDlg16(&pdlg
))
1532 case psh2
: /* Properties button */
1535 char PrinterName
[256];
1537 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1538 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1539 FIXME(" Call to OpenPrinter did not succeed!\n");
1542 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1543 PrintStructures
->lpDevMode
,
1544 PrintStructures
->lpDevMode
,
1545 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1546 ClosePrinter(hPrinter
);
1550 case rad1
: /* Paperorientation */
1551 if (lppd
->Flags
& PD_PRINTSETUP
)
1553 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1554 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1555 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1559 case rad2
: /* Paperorientation */
1560 if (lppd
->Flags
& PD_PRINTSETUP
)
1562 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1563 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1564 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1568 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1569 if (PrinterComboID
!= LOWORD(wParam
)) {
1573 case cmb4
: /* Printer combobox */
1574 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1575 char PrinterName
[256];
1576 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1577 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1581 case cmb2
: /* Papersize */
1583 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1585 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1591 case cmb3
: /* Bin */
1593 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1595 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1596 CB_GETITEMDATA
, Sel
,
1601 if(lppd
->Flags
& PD_PRINTSETUP
) {
1602 switch (LOWORD(wParam
)) {
1603 case rad1
: /* orientation */
1605 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1606 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1607 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1608 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1610 (LPARAM
)PrintStructures
->hPortraitIcon
);
1611 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1613 (LPARAM
)PrintStructures
->hPortraitIcon
);
1616 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1617 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1618 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1620 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1621 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1623 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1632 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1633 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1635 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1636 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1637 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1639 switch (LOWORD(wParam
)) {
1641 TRACE(" OK button was hit\n");
1642 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1643 FIXME("Update printdlg was not successful!\n");
1646 EndDialog(hDlg
, TRUE
);
1650 TRACE(" CANCEL button was hit\n");
1651 EndDialog(hDlg
, FALSE
);
1655 TRACE(" HELP button was hit\n");
1656 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1657 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1660 case chx2
: /* collate pages checkbox */
1661 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1662 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1663 (LPARAM
)PrintStructures
->hCollateIcon
);
1665 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1666 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1668 case edt1
: /* from page nr editbox */
1669 case edt2
: /* to page nr editbox */
1670 if (HIWORD(wParam
)==EN_CHANGE
) {
1673 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1674 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1675 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1676 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1681 if(HIWORD(wParam
) == EN_CHANGE
) {
1682 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1684 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1686 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1690 case psh1
: /* Print Setup */
1692 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1695 case psh2
: /* Properties button */
1698 WCHAR PrinterName
[256];
1700 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1701 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1702 FIXME(" Call to OpenPrinter did not succeed!\n");
1705 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1706 PrintStructures
->lpDevMode
,
1707 PrintStructures
->lpDevMode
,
1708 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1709 ClosePrinter(hPrinter
);
1713 case rad1
: /* Paperorientation */
1714 if (lppd
->Flags
& PD_PRINTSETUP
)
1716 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1717 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1718 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1722 case rad2
: /* Paperorientation */
1723 if (lppd
->Flags
& PD_PRINTSETUP
)
1725 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1726 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1727 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1731 case cmb1
: /* Printer Combobox in PRINT SETUP */
1733 case cmb4
: /* Printer combobox */
1734 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1735 WCHAR PrinterName
[256];
1736 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1737 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1741 case cmb2
: /* Papersize */
1743 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1745 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1751 case cmb3
: /* Bin */
1753 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1755 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1756 CB_GETITEMDATA
, Sel
,
1761 if(lppd
->Flags
& PD_PRINTSETUP
) {
1762 switch (LOWORD(wParam
)) {
1763 case rad1
: /* orientation */
1765 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1766 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1767 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1768 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1770 (LPARAM
)PrintStructures
->hPortraitIcon
);
1771 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1773 (LPARAM
)PrintStructures
->hPortraitIcon
);
1776 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1777 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1778 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1780 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1781 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1783 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1792 /***********************************************************************
1793 * PrintDlgProcA [internal]
1795 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1798 PRINT_PTRA
* PrintStructures
;
1799 INT_PTR res
= FALSE
;
1801 if (uMsg
!=WM_INITDIALOG
) {
1802 PrintStructures
= GetPropW(hDlg
, printdlg_prop
);
1803 if (!PrintStructures
)
1806 PrintStructures
= (PRINT_PTRA
*) lParam
;
1807 SetPropW(hDlg
, printdlg_prop
, PrintStructures
);
1808 if(!check_printer_setup(hDlg
))
1810 EndDialog(hDlg
,FALSE
);
1813 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1815 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1816 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1817 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1822 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1823 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1830 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1833 DestroyIcon(PrintStructures
->hCollateIcon
);
1834 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1835 DestroyIcon(PrintStructures
->hPortraitIcon
);
1836 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1837 if(PrintStructures
->hwndUpDown
)
1838 DestroyWindow(PrintStructures
->hwndUpDown
);
1844 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1847 PRINT_PTRW
* PrintStructures
;
1848 INT_PTR res
= FALSE
;
1850 if (uMsg
!=WM_INITDIALOG
) {
1851 PrintStructures
= GetPropW(hDlg
, printdlg_prop
);
1852 if (!PrintStructures
)
1855 PrintStructures
= (PRINT_PTRW
*) lParam
;
1856 SetPropW(hDlg
, printdlg_prop
, PrintStructures
);
1857 if(!check_printer_setup(hDlg
))
1859 EndDialog(hDlg
,FALSE
);
1862 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1864 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1865 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1869 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1870 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1876 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1879 DestroyIcon(PrintStructures
->hCollateIcon
);
1880 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1881 DestroyIcon(PrintStructures
->hPortraitIcon
);
1882 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1883 if(PrintStructures
->hwndUpDown
)
1884 DestroyWindow(PrintStructures
->hwndUpDown
);
1890 /************************************************************
1892 * PRINTDLG_GetDlgTemplate
1895 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1900 if (lppd
->Flags
& PD_PRINTSETUP
) {
1901 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1902 hDlgTmpl
= lppd
->hSetupTemplate
;
1903 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1904 hResInfo
= FindResourceA(lppd
->hInstance
,
1905 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1906 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1908 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1910 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1913 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1914 hDlgTmpl
= lppd
->hPrintTemplate
;
1915 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1916 hResInfo
= FindResourceA(lppd
->hInstance
,
1917 lppd
->lpPrintTemplateName
,
1919 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1921 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1923 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1929 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1933 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1934 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1936 if (lppd
->Flags
& PD_PRINTSETUP
) {
1937 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1938 hDlgTmpl
= lppd
->hSetupTemplate
;
1939 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1940 hResInfo
= FindResourceW(lppd
->hInstance
,
1941 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1942 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1944 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
1945 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1948 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1949 hDlgTmpl
= lppd
->hPrintTemplate
;
1950 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1951 hResInfo
= FindResourceW(lppd
->hInstance
,
1952 lppd
->lpPrintTemplateName
,
1954 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1956 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
1957 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1963 /***********************************************************************
1968 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
1970 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
1971 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
1973 if(lppd
->Flags
& PD_RETURNDC
) {
1974 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
1975 (char*)pdn
+ pdn
->wDeviceOffset
,
1976 (char*)pdn
+ pdn
->wOutputOffset
,
1978 } else if(lppd
->Flags
& PD_RETURNIC
) {
1979 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
1980 (char*)pdn
+ pdn
->wDeviceOffset
,
1981 (char*)pdn
+ pdn
->wOutputOffset
,
1984 GlobalUnlock(lppd
->hDevNames
);
1985 GlobalUnlock(lppd
->hDevMode
);
1986 return lppd
->hDC
? TRUE
: FALSE
;
1989 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
1991 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
1992 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
1994 if(lppd
->Flags
& PD_RETURNDC
) {
1995 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
1996 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
1997 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
1999 } else if(lppd
->Flags
& PD_RETURNIC
) {
2000 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2001 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2002 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2005 GlobalUnlock(lppd
->hDevNames
);
2006 GlobalUnlock(lppd
->hDevMode
);
2007 return lppd
->hDC
? TRUE
: FALSE
;
2010 /***********************************************************************
2011 * PrintDlgA (COMDLG32.@)
2013 * Displays the PRINT dialog box, which enables the user to specify
2014 * specific properties of the print job.
2017 * lppd [IO] ptr to PRINTDLG32 struct
2020 * nonzero if the user pressed the OK button
2021 * zero if the user cancelled the window or an error occurred
2025 * * The Collate Icons do not display, even though they are in the code.
2026 * * The Properties Button(s) should call DocumentPropertiesA().
2029 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2037 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2041 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2042 if(TRACE_ON(commdlg
)) {
2043 char flagstr
[1000] = "";
2044 const struct pd_flags
*pflag
= pd_flags
;
2045 for( ; pflag
->name
; pflag
++) {
2046 if(lppd
->Flags
& pflag
->flag
)
2047 strcat(flagstr
, pflag
->name
);
2049 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2050 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2051 "flags %08x (%s)\n",
2052 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2053 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2054 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2057 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2058 WARN("structure size failure !!!\n");
2059 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2063 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2064 PRINTER_INFO_2A
*pbuf
;
2065 DRIVER_INFO_3A
*dbuf
;
2069 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2070 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2071 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2074 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2075 WARN("Can't find default printer\n");
2076 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2080 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2081 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2082 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2084 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2085 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2086 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2087 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2088 GetLastError(),pbuf
->pPrinterName
);
2089 HeapFree(GetProcessHeap(), 0, dbuf
);
2090 HeapFree(GetProcessHeap(), 0, pbuf
);
2091 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2096 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2100 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2101 pbuf
->pDevMode
->dmDriverExtra
);
2102 ptr
= GlobalLock(lppd
->hDevMode
);
2103 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2104 pbuf
->pDevMode
->dmDriverExtra
);
2105 GlobalUnlock(lppd
->hDevMode
);
2106 HeapFree(GetProcessHeap(), 0, pbuf
);
2107 HeapFree(GetProcessHeap(), 0, dbuf
);
2111 PRINT_PTRA
*PrintStructures
;
2113 /* load Dialog resources,
2114 * depending on Flags indicates Print32 or Print32_setup dialog
2116 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2118 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2121 ptr
= LockResource( hDlgTmpl
);
2123 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2127 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2128 sizeof(PRINT_PTRA
));
2129 PrintStructures
->lpPrintDlg
= lppd
;
2131 /* and create & process the dialog .
2132 * -1 is failure, 0 is broken hwnd, everything else is ok.
2134 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2136 (LPARAM
)PrintStructures
));
2139 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2140 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2141 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2143 if (lppd
->hDevMode
== 0) {
2144 TRACE(" No hDevMode yet... Need to create my own\n");
2145 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2146 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2148 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2149 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2152 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2153 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2155 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2160 GlobalUnlock(lppd
->hDevMode
);
2162 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2163 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2164 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2165 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2167 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2168 bRet
= PRINTDLG_CreateDCA(lppd
);
2170 TRACE("exit! (%d)\n", bRet
);
2174 /***********************************************************************
2175 * PrintDlgW (COMDLG32.@)
2179 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2187 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2191 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2192 if(TRACE_ON(commdlg
)) {
2193 char flagstr
[1000] = "";
2194 const struct pd_flags
*pflag
= pd_flags
;
2195 for( ; pflag
->name
; pflag
++) {
2196 if(lppd
->Flags
& pflag
->flag
)
2197 strcat(flagstr
, pflag
->name
);
2199 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2200 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2201 "flags %08x (%s)\n",
2202 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2203 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2204 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2207 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2208 WARN("structure size failure !!!\n");
2209 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2213 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2214 PRINTER_INFO_2W
*pbuf
;
2215 DRIVER_INFO_3W
*dbuf
;
2219 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2220 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2221 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2224 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2225 WARN("Can't find default printer\n");
2226 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2230 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2231 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2232 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2234 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2235 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2236 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2237 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2238 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2239 HeapFree(GetProcessHeap(), 0, dbuf
);
2240 HeapFree(GetProcessHeap(), 0, pbuf
);
2241 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2246 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2250 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2251 pbuf
->pDevMode
->dmDriverExtra
);
2252 ptr
= GlobalLock(lppd
->hDevMode
);
2253 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2254 pbuf
->pDevMode
->dmDriverExtra
);
2255 GlobalUnlock(lppd
->hDevMode
);
2256 HeapFree(GetProcessHeap(), 0, pbuf
);
2257 HeapFree(GetProcessHeap(), 0, dbuf
);
2261 PRINT_PTRW
*PrintStructures
;
2263 /* load Dialog resources,
2264 * depending on Flags indicates Print32 or Print32_setup dialog
2266 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2268 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2271 ptr
= LockResource( hDlgTmpl
);
2273 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2277 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2278 sizeof(PRINT_PTRW
));
2279 PrintStructures
->lpPrintDlg
= lppd
;
2281 /* and create & process the dialog .
2282 * -1 is failure, 0 is broken hwnd, everything else is ok.
2284 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2286 (LPARAM
)PrintStructures
));
2289 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2290 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2291 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2293 if (lppd
->hDevMode
== 0) {
2294 TRACE(" No hDevMode yet... Need to create my own\n");
2295 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2296 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2299 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2300 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2302 GlobalUnlock(lppd
->hDevMode
);
2303 TRACE("Now got %d locks\n", locks
);
2306 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2307 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2310 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2311 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2313 if (lppd
->hDevNames
!= 0) {
2315 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2316 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2318 GlobalUnlock(lppd
->hDevNames
);
2321 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2326 GlobalUnlock(lppd
->hDevMode
);
2328 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2329 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2330 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2331 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2333 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2334 bRet
= PRINTDLG_CreateDCW(lppd
);
2336 TRACE("exit! (%d)\n", bRet
);
2340 /***********************************************************************
2345 * cmb1 - printer select (not in standard dialog template)
2347 * cmb3 - source (tray?)
2348 * edt4 - border left
2350 * edt6 - border right
2351 * edt7 - border bottom
2352 * psh3 - "Printer..."
2356 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2357 HWND hDlg
; /* Page Setup dialog handler */
2358 RECT rtDrawRect
; /* Drawing rect for page */
2362 LPPAGESETUPDLGW dlgw
;
2364 PAGESETUPDLGW curdlg
; /* Current dialog state */
2368 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2373 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2374 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2375 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2376 hResInfo
= FindResourceA(lppd
->hInstance
,
2377 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2378 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2380 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2381 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2386 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2391 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2392 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2393 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2394 hResInfo
= FindResourceW(lppd
->hInstance
,
2395 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2396 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2398 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2399 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2405 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2406 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2407 return 10*size
*100/254;
2413 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2414 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2417 return (size
*254)/100;
2420 static void size2str(PageSetupDataA
*pda
, DWORD size
, LPWSTR strout
)
2422 static const WCHAR metric_format
[] = {'%','d',0};
2423 static const WCHAR imperial_format
[] = {'%','d','i','n',0};
2425 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2426 wsprintfW(strout
, metric_format
, size
/ 100);
2428 wsprintfW(strout
, imperial_format
, size
/ 1000);
2432 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2433 static const char mm_fmt
[] = "%.2f mm";
2434 static const char in_fmt
[] = "%.2f in";
2436 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2437 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2438 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2439 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2441 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2442 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2445 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2449 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2454 if (!sscanf(strin
,"%f%s",&val
,rest
))
2457 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2458 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2461 return val
*25.4*100;
2463 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2464 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2466 if (!strcmp(rest
,"mm")) {
2467 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2470 return 1000.0*val
/25.4;
2472 if (rest
[0]=='\0') {
2473 /* use application supplied default */
2474 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2478 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2483 ERR("Did not find a conversion for type '%s'!\n",rest
);
2489 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2492 /* this W -> A transition is OK */
2493 /* we need a unicode version of sscanf to avoid it */
2494 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2495 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2498 static inline BOOL
is_default_metric(void)
2501 GetLocaleInfoW(LOCALE_USER_DEFAULT
, LOCALE_IMEASURE
| LOCALE_RETURN_NUMBER
,
2502 (LPWSTR
)&system
, sizeof(system
));
2506 static BOOL
pagesetup_papersizeA(PAGESETUPDLGA
*dlg
, const WORD paperword
, LPPOINT size
)
2510 LPSTR devname
, portname
;
2513 POINT
*points
= NULL
;
2514 BOOL retval
= FALSE
;
2516 dn
= GlobalLock(dlg
->hDevNames
);
2517 dm
= GlobalLock(dlg
->hDevMode
);
2518 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2519 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2521 num
= DeviceCapabilitiesA(devname
, portname
, DC_PAPERS
, NULL
, dm
);
2524 FIXME("No papernames found for %s/%s\n", devname
, portname
);
2528 words
= HeapAlloc(GetProcessHeap(), 0, num
* sizeof(WORD
));
2529 points
= HeapAlloc(GetProcessHeap(), 0, num
* sizeof(POINT
));
2531 if (num
!= DeviceCapabilitiesA(devname
, portname
, DC_PAPERS
, (LPSTR
)words
, dm
))
2533 FIXME("Number of returned words is not %d\n", num
);
2537 if (num
!= DeviceCapabilitiesA(devname
, portname
, DC_PAPERSIZE
, (LPSTR
)points
, dm
))
2539 FIXME("Number of returned sizes is not %d\n",num
);
2543 for (i
= 0; i
< num
; i
++)
2544 if (words
[i
] == paperword
)
2549 FIXME("Papersize %d not found in list?\n", paperword
);
2553 /* this is _10ths_ of a millimeter */
2554 size
->x
= _c_10mm2size(dlg
, points
[i
].x
);
2555 size
->y
= _c_10mm2size(dlg
, points
[i
].y
);
2559 HeapFree(GetProcessHeap(), 0, words
);
2560 HeapFree(GetProcessHeap(), 0, points
);
2561 GlobalUnlock(dlg
->hDevNames
);
2562 GlobalUnlock(dlg
->hDevMode
);
2567 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2570 LPWSTR devname
,portname
;
2571 WCHAR papername
[64];
2574 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2575 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2576 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2577 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2579 /* Save paper size into device context */
2580 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2581 /* Save paper source into device context */
2582 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2584 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2585 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2586 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2587 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2589 FIXME("could not get dialog text for papersize cmbbox?\n");
2590 #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); }
2591 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2592 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2593 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2594 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2597 /* If we are in landscape, swap x and y of page size */
2598 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2600 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2601 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2602 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2605 /* Save orientation */
2606 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2607 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2609 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2611 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2612 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2616 /**********************************************************************************************
2617 * PRINTDLG_PS_ChangeActivePrinerA
2619 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2622 * name [in] Name of a printer for activation
2623 * pda [in/out] ptr to PageSetupDataA structure
2630 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2633 LPPRINTER_INFO_2A lpPrinterInfo
;
2634 LPDRIVER_INFO_3A lpDriverInfo
;
2635 DEVMODEA
*pDevMode
, *dm
;
2637 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2638 ERR("Can't open printer %s\n", name
);
2641 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2642 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2643 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2644 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2645 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2646 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2647 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2648 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2649 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2654 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2656 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2657 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2658 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2661 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2662 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2664 pda
->dlga
->hDevMode
= GlobalReAlloc(pda
->dlga
->hDevMode
,
2665 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2667 dm
= GlobalLock(pda
->dlga
->hDevMode
);
2668 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2670 PRINTDLG_CreateDevNames(&(pda
->dlga
->hDevNames
),
2671 lpDriverInfo
->pDriverPath
,
2672 lpPrinterInfo
->pPrinterName
,
2673 lpPrinterInfo
->pPortName
);
2675 GlobalUnlock(pda
->dlga
->hDevMode
);
2676 HeapFree(GetProcessHeap(), 0, pDevMode
);
2677 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2678 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2682 /****************************************************************************************
2683 * PRINTDLG_PS_ChangePrinterA
2685 * Fills Printers, Paper and Source combo
2691 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2694 LPSTR devname
,portname
;
2696 dn
= GlobalLock(pda
->dlga
->hDevNames
);
2697 dm
= GlobalLock(pda
->dlga
->hDevMode
);
2698 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2699 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2700 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2701 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2702 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2703 GlobalUnlock(pda
->dlga
->hDevNames
);
2704 GlobalUnlock(pda
->dlga
->hDevMode
);
2708 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2710 WCHAR PaperName
[64];
2712 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2713 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2714 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2715 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2717 if(IsDlgButtonChecked(hDlg
, rad2
))
2719 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2720 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2721 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2725 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2730 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2735 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2736 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2738 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2740 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2743 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2745 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2749 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2752 LPWSTR devname
,portname
;
2754 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2755 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2756 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2757 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2758 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2759 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2761 /* Landscape orientation */
2762 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2763 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2764 else /* this is default if papersize is not set */
2765 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2767 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2768 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2770 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2775 /******************************************************************************************
2776 * PRINTDLG_PS_ChangePaperPrev
2778 * Changes paper preview size / position
2781 * pda [i] Pointer for current PageSetupDataA structure
2787 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2789 LONG width
, height
, x
, y
;
2792 if(pda
->dlga
->ptPaperSize
.x
> pda
->dlga
->ptPaperSize
.y
) {
2793 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2794 height
= pda
->dlga
->ptPaperSize
.y
* width
/ pda
->dlga
->ptPaperSize
.x
;
2796 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2797 width
= pda
->dlga
->ptPaperSize
.x
* height
/ pda
->dlga
->ptPaperSize
.y
;
2799 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2800 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2801 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2802 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2803 x
, y
, width
, height
);
2806 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2807 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2808 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2809 rtTmp
= pda
->rtDrawRect
;
2810 rtTmp
.right
+= SHADOW
;
2811 rtTmp
.bottom
+= SHADOW
;
2814 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2818 #define GETVAL(idc,val) \
2819 if(msg == EN_CHANGE){ \
2820 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2821 val = _c_str2sizeA(pda->dlga,buf); \
2823 FIXME("could not get dlgitemtexta for %x\n",id); \
2826 /********************************************************************************
2827 * PRINTDLG_PS_WMCommandA
2828 * process WM_COMMAND message for PageSetupDlgA
2831 * hDlg [in] Main dialog HANDLE
2832 * wParam [in] WM_COMMAND wParam
2833 * lParam [in] WM_COMMAND lParam
2834 * pda [in/out] ptr to PageSetupDataA
2838 PRINTDLG_PS_WMCommandA(
2839 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2841 WORD msg
= HIWORD(wParam
);
2842 WORD id
= LOWORD(wParam
);
2845 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2846 LOWORD(lParam
),wParam
,lParam
);
2849 EndDialog(hDlg
, TRUE
);
2853 EndDialog(hDlg
, FALSE
);
2859 memset(&prnt
, 0, sizeof(prnt
));
2860 prnt
.lStructSize
= sizeof(prnt
);
2862 prnt
.hwndOwner
= hDlg
;
2863 prnt
.hDevNames
= pda
->dlga
->hDevNames
;
2864 prnt
.hDevMode
= pda
->dlga
->hDevMode
;
2865 if (PrintDlgA(&prnt
))
2867 pda
->dlga
->hDevNames
= prnt
.hDevNames
;
2868 pda
->dlga
->hDevMode
= prnt
.hDevMode
;
2869 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2875 if((id
== rad1
&& pda
->dlga
->ptPaperSize
.x
> pda
->dlga
->ptPaperSize
.y
) ||
2876 (id
== rad2
&& pda
->dlga
->ptPaperSize
.y
> pda
->dlga
->ptPaperSize
.x
))
2880 DWORD tmp
= pda
->dlga
->ptPaperSize
.x
;
2881 DEVMODEA
*dm
= GlobalLock(pda
->dlga
->hDevMode
);
2883 pda
->dlga
->ptPaperSize
.x
= pda
->dlga
->ptPaperSize
.y
;
2884 pda
->dlga
->ptPaperSize
.y
= tmp
;
2886 dm
->u1
.s1
.dmOrientation
= (id
== rad1
) ? DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
2887 GlobalUnlock(pda
->dlga
->hDevMode
);
2889 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2890 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2891 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2892 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2894 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2895 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2896 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2897 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2899 PRINTDLG_PS_ChangePaperPrev(pda
);
2902 case cmb1
: /* Printer combo */
2903 if(msg
== CBN_SELCHANGE
){
2904 char crPrinterName
[256];
2905 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2906 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2907 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2910 case cmb2
: /* Paper combo */
2911 if(msg
== CBN_SELCHANGE
){
2912 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2913 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2914 if (paperword
!= CB_ERR
)
2916 DEVMODEA
*dm
= GlobalLock(pda
->dlga
->hDevMode
);
2917 dm
->u1
.s1
.dmPaperSize
= paperword
;
2918 GlobalUnlock(pda
->dlga
->hDevMode
);
2919 pagesetup_papersizeA(pda
->dlga
, paperword
, &(pda
->dlga
->ptPaperSize
));
2920 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2921 DWORD tmp
= pda
->dlga
->ptPaperSize
.x
;
2922 pda
->dlga
->ptPaperSize
.x
= pda
->dlga
->ptPaperSize
.y
;
2923 pda
->dlga
->ptPaperSize
.y
= tmp
;
2925 PRINTDLG_PS_ChangePaperPrev(pda
);
2927 FIXME("could not get dialog text for papersize cmbbox?\n");
2931 if(msg
== CBN_SELCHANGE
){
2932 DEVMODEA
*dm
= GlobalLock(pda
->dlga
->hDevMode
);
2933 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2934 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2935 GlobalUnlock(pda
->dlga
->hDevMode
);
2938 case psh2
: /* Printer Properties button */
2941 char PrinterName
[256];
2946 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2947 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2948 FIXME("Call to OpenPrinter did not succeed!\n");
2951 dm
= GlobalLock(pda
->dlga
->hDevMode
);
2952 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2953 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2954 ClosePrinter(hPrinter
);
2955 /* Changing paper */
2956 pagesetup_papersizeA(pda
->dlga
, dm
->u1
.s1
.dmPaperSize
, &(pda
->dlga
->ptPaperSize
));
2957 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
2958 DWORD tmp
= pda
->dlga
->ptPaperSize
.x
;
2959 pda
->dlga
->ptPaperSize
.x
= pda
->dlga
->ptPaperSize
.y
;
2960 pda
->dlga
->ptPaperSize
.y
= tmp
;
2961 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2964 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2965 /* Changing paper preview */
2966 PRINTDLG_PS_ChangePaperPrev(pda
);
2967 /* Selecting paper in combo */
2968 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
2969 if(count
!= CB_ERR
){
2970 for(i
=0; i
<count
; ++i
){
2971 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
2972 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
2978 GlobalUnlock(pda
->dlga
->hDevMode
);
2982 GETVAL(id
, pda
->dlga
->rtMargin
.left
);
2985 GETVAL(id
, pda
->dlga
->rtMargin
.top
);
2988 GETVAL(id
, pda
->dlga
->rtMargin
.right
);
2991 GETVAL(id
, pda
->dlga
->rtMargin
.bottom
);
2994 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3000 PRINTDLG_PS_WMCommandW(
3001 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3003 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3004 LOWORD(lParam
),wParam
,lParam
);
3005 switch (LOWORD(wParam
)) {
3007 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3009 EndDialog(hDlg
, TRUE
);
3013 EndDialog(hDlg
, FALSE
);
3018 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3019 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3023 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3025 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3026 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3028 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3029 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3030 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3031 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3033 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3034 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3035 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3036 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3041 pdw
->pdlg
.Flags
= 0;
3042 pdw
->pdlg
.hwndOwner
= hDlg
;
3043 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3044 if (PrintDlgW(&(pdw
->pdlg
)))
3045 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3053 /***********************************************************************
3054 * DefaultPagePaintHook
3055 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3056 * whenever the sample page is redrawn.
3060 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3061 const PageSetupDataA
*pda
)
3063 LPRECT lprc
= (LPRECT
) lParam
;
3064 HDC hdc
= (HDC
) wParam
;
3067 HFONT hfont
, holdfont
;
3069 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3070 /* Call user paint hook if enable */
3071 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3072 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3076 /* LPPAGESETUPDLG in lParam */
3077 case WM_PSD_PAGESETUPDLG
:
3078 /* Inform about the sample page rectangle */
3079 case WM_PSD_FULLPAGERECT
:
3080 /* Inform about the margin rectangle */
3081 case WM_PSD_MINMARGINRECT
:
3084 /* Draw dashed rectangle showing margins */
3085 case WM_PSD_MARGINRECT
:
3086 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3087 holdpen
= SelectObject(hdc
, hpen
);
3088 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3089 DeleteObject(SelectObject(hdc
, holdpen
));
3091 /* Draw the fake document */
3092 case WM_PSD_GREEKTEXTRECT
:
3093 /* select a nice scalable font, because we want the text really small */
3094 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3095 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3096 hfont
= CreateFontIndirectW(&lf
);
3097 holdfont
= SelectObject(hdc
, hfont
);
3099 /* if text not loaded, then do so now */
3100 if (wszFakeDocumentText
[0] == '\0')
3101 LoadStringW(COMDLG32_hInstance
,
3103 wszFakeDocumentText
,
3104 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3106 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3107 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3108 SetBkMode(hdc
, oldbkmode
);
3110 DeleteObject(SelectObject(hdc
, holdfont
));
3113 /* Envelope stamp */
3114 case WM_PSD_ENVSTAMPRECT
:
3115 /* Return address */
3116 case WM_PSD_YAFULLPAGERECT
:
3117 FIXME("envelope/stamp is not implemented\n");
3120 FIXME("Unknown message %x\n",uMsg
);
3126 /***********************************************************************
3128 * The main paint procedure for the PageSetupDlg function.
3129 * The Page Setup dialog box includes an image of a sample page that shows how
3130 * the user's selections affect the appearance of the printed output.
3131 * The image consists of a rectangle that represents the selected paper
3132 * or envelope type, with a dotted-line rectangle representing
3133 * the current margins, and partial (Greek text) characters
3134 * to show how text looks on the printed page.
3136 * The following messages in the order sends to user hook procedure:
3137 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3138 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3139 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3140 * WM_PSD_MARGINRECT Draw the margin rectangle
3141 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3142 * If any of first three messages returns TRUE, painting done.
3145 * hWnd [in] Handle to the Page Setup dialog box
3146 * uMsg [in] Received message
3149 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3150 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3153 * FALSE if all done correctly
3158 static LRESULT CALLBACK
3159 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3162 RECT rcClient
, rcMargin
;
3165 HBRUSH hbrush
, holdbrush
;
3166 PageSetupDataA
*pda
;
3167 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3168 double scalx
, scaly
;
3169 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3171 if (uMsg
!= WM_PAINT
)
3172 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3174 /* Processing WM_PAINT message */
3175 pda
= GetPropW(hWnd
, pagesetupdlg_prop
);
3177 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3180 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3183 hdc
= BeginPaint(hWnd
, &ps
);
3184 GetClientRect(hWnd
, &rcClient
);
3186 scalx
= rcClient
.right
/ (double)pda
->dlga
->ptPaperSize
.x
;
3187 scaly
= rcClient
.bottom
/ (double)pda
->dlga
->ptPaperSize
.y
;
3188 rcMargin
= rcClient
;
3190 rcMargin
.left
+= pda
->dlga
->rtMargin
.left
* scalx
;
3191 rcMargin
.top
+= pda
->dlga
->rtMargin
.top
* scalx
;
3192 rcMargin
.right
-= pda
->dlga
->rtMargin
.right
* scaly
;
3193 rcMargin
.bottom
-= pda
->dlga
->rtMargin
.bottom
* scaly
;
3195 /* if the space is too small then we make sure to not draw anything */
3196 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3197 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3199 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3200 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3202 /* fill background */
3203 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3204 FillRect(hdc
, &rcClient
, hbrush
);
3205 holdbrush
= SelectObject(hdc
, hbrush
);
3207 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3208 holdpen
= SelectObject(hdc
, hpen
);
3210 /* paint left edge */
3211 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3212 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3214 /* paint top edge */
3215 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3216 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3218 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3219 DeleteObject(SelectObject(hdc
, hpen
));
3221 /* paint right edge */
3222 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3223 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3225 /* paint bottom edge */
3226 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3227 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3229 DeleteObject(SelectObject(hdc
, holdpen
));
3230 DeleteObject(SelectObject(hdc
, holdbrush
));
3232 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3234 /* give text a bit of a space from the frame */
3237 rcMargin
.right
-= 2;
3238 rcMargin
.bottom
-= 2;
3240 /* if the space is too small then we make sure to not draw anything */
3241 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3242 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3244 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3247 EndPaint(hWnd
, &ps
);
3249 #undef CALLPAINTHOOK
3252 /***********************************************************************
3253 * PRINTDLG_PageDlgProcA
3254 * Message handler for PageSetupDlgA
3256 static INT_PTR CALLBACK
3257 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3260 PageSetupDataA
*pda
;
3261 INT_PTR res
= FALSE
;
3264 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3267 pda
= (PageSetupDataA
*)lParam
;
3268 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3270 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3271 TRACE("set property to %p\n", pda
);
3272 SetPropW(hDlg
, pagesetupdlg_prop
, pda
);
3273 SetPropW(hDrawWnd
, pagesetupdlg_prop
, pda
);
3274 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3275 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3276 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3277 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3280 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3282 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3284 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3285 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3286 FIXME("Setup page hook failed?\n");
3289 /* if printer button disabled */
3290 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3291 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3292 /* if margin edit boxes disabled */
3293 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3294 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3295 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3296 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3297 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3299 /* Set orientation radiobutton properly */
3300 if(pda
->dlga
->hDevMode
)
3302 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3303 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3304 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3305 else /* this is default if papersize is not set */
3306 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3307 GlobalUnlock(pda
->dlga
->hDevMode
);
3310 /* if orientation disabled */
3311 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3312 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3313 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3316 /* We fill them out enabled or not */
3317 if (!(pda
->dlga
->Flags
& PSD_MARGINS
))
3319 /* default is 1 inch */
3320 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3321 pda
->dlga
->rtMargin
.left
= size
;
3322 pda
->dlga
->rtMargin
.top
= size
;
3323 pda
->dlga
->rtMargin
.right
= size
;
3324 pda
->dlga
->rtMargin
.bottom
= size
;
3326 size2str(pda
, pda
->dlga
->rtMargin
.left
, str
);
3327 SetDlgItemTextW(hDlg
, edt4
, str
);
3328 size2str(pda
, pda
->dlga
->rtMargin
.top
, str
);
3329 SetDlgItemTextW(hDlg
, edt5
, str
);
3330 size2str(pda
, pda
->dlga
->rtMargin
.right
, str
);
3331 SetDlgItemTextW(hDlg
, edt6
, str
);
3332 size2str(pda
, pda
->dlga
->rtMargin
.bottom
, str
);
3333 SetDlgItemTextW(hDlg
, edt7
, str
);
3335 /* if paper disabled */
3336 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3337 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3338 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3340 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3341 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3342 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3344 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3345 pagesetup_papersizeA(pda
->dlga
, dm
->u1
.s1
.dmPaperSize
, &pda
->dlga
->ptPaperSize
);
3346 GlobalUnlock(pda
->dlga
->hDevMode
);
3347 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3348 DWORD tmp
= pda
->dlga
->ptPaperSize
.y
;
3349 pda
->dlga
->ptPaperSize
.y
= pda
->dlga
->ptPaperSize
.x
;
3350 pda
->dlga
->ptPaperSize
.x
= tmp
;
3353 WARN("GlobalLock(pda->dlga->hDevMode) fail? hDevMode=%p\n", pda
->dlga
->hDevMode
);
3354 /* Drawing paper prev */
3355 PRINTDLG_PS_ChangePaperPrev(pda
);
3358 pda
= GetPropW(hDlg
, pagesetupdlg_prop
);
3360 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3363 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3364 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3365 if (res
) return res
;
3370 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3375 static INT_PTR CALLBACK
3376 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3378 PageSetupDataW
*pdw
;
3381 if (uMsg
==WM_INITDIALOG
) {
3383 pdw
= (PageSetupDataW
*)lParam
;
3384 pdw
->curdlg
= *pdw
->dlgw
;
3385 SetPropW(hDlg
, pagesetupdlg_prop
, pdw
);
3386 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3387 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3389 FIXME("Setup page hook failed?\n");
3394 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3395 FIXME("PagePaintHook not yet implemented!\n");
3397 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3398 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3399 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3400 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3401 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3402 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3403 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3406 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3408 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3409 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3410 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3412 /* We fill them out enabled or not */
3413 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3415 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3416 SetDlgItemTextW(hDlg
,edt4
,str
);
3417 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3418 SetDlgItemTextW(hDlg
,edt5
,str
);
3419 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3420 SetDlgItemTextW(hDlg
,edt6
,str
);
3421 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3422 SetDlgItemTextW(hDlg
,edt7
,str
);
3424 /* default is 1 inch */
3425 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3427 _c_size2strW(pdw
,size
,str
);
3428 SetDlgItemTextW(hDlg
,edt4
,str
);
3429 SetDlgItemTextW(hDlg
,edt5
,str
);
3430 SetDlgItemTextW(hDlg
,edt6
,str
);
3431 SetDlgItemTextW(hDlg
,edt7
,str
);
3434 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3435 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3436 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3441 pdw
= GetPropW(hDlg
, pagesetupdlg_prop
);
3443 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3446 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3447 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3448 if (res
) return res
;
3453 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3458 /***********************************************************************
3459 * PageSetupDlgA (COMDLG32.@)
3461 * Displays the PAGE SETUP dialog box, which enables the user to specify
3462 * specific properties of a printed page such as
3463 * size, source, orientation and the width of the page margins.
3466 * setupdlg [IO] PAGESETUPDLGA struct
3469 * TRUE if the user pressed the OK button
3470 * FALSE if the user cancelled the window or an error occurred
3473 * The values of hDevMode and hDevNames are filled on output and can be
3474 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3478 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3482 PageSetupDataA
*pda
;
3484 if (setupdlg
== NULL
) {
3485 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3490 if(TRACE_ON(commdlg
)) {
3491 char flagstr
[1000] = "";
3492 const struct pd_flags
*pflag
= psd_flags
;
3493 for( ; pflag
->name
; pflag
++) {
3494 if(setupdlg
->Flags
& pflag
->flag
) {
3495 strcat(flagstr
, pflag
->name
);
3496 strcat(flagstr
, "|");
3499 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3500 "hinst %p, flags %08x (%s)\n",
3501 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3502 setupdlg
->hDevNames
,
3503 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3506 /* Checking setupdlg structure */
3507 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3508 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3511 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3512 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3513 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3517 if(!(setupdlg
->Flags
& (PSD_INTHOUSANDTHSOFINCHES
| PSD_INHUNDREDTHSOFMILLIMETERS
)))
3518 setupdlg
->Flags
|= is_default_metric() ?
3519 PSD_INHUNDREDTHSOFMILLIMETERS
: PSD_INTHOUSANDTHSOFINCHES
;
3521 /* Initialize default printer struct. If no printer device info is specified
3522 retrieve the default printer data. */
3523 if (!setupdlg
->hDevMode
|| !setupdlg
->hDevNames
)
3526 memset(&pdlg
, 0, sizeof(pdlg
));
3527 pdlg
.lStructSize
= sizeof(pdlg
);
3528 pdlg
.Flags
= PD_RETURNDEFAULT
;
3529 bRet
= PrintDlgA(&pdlg
);
3532 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3534 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3535 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3539 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3540 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3543 /* short cut exit, just return default values */
3544 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3546 dm
= GlobalLock(setupdlg
->hDevMode
);
3547 pagesetup_papersizeA(setupdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3548 GlobalUnlock(setupdlg
->hDevMode
);
3552 /* get dialog template */
3553 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3555 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3558 ptr
= LockResource( hDlgTmpl
);
3560 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3564 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3565 pda
->dlga
= setupdlg
;
3567 bRet
= (0<DialogBoxIndirectParamW(
3568 setupdlg
->hInstance
,
3570 setupdlg
->hwndOwner
,
3571 PRINTDLG_PageDlgProcA
,
3575 HeapFree(GetProcessHeap(),0,pda
);
3578 /***********************************************************************
3579 * PageSetupDlgW (COMDLG32.@)
3581 * See PageSetupDlgA.
3583 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3587 PageSetupDataW
*pdw
;
3590 FIXME("Unicode implementation is not done yet\n");
3592 if (setupdlg
== NULL
) {
3593 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3597 if(TRACE_ON(commdlg
)) {
3598 char flagstr
[1000] = "";
3599 const struct pd_flags
*pflag
= psd_flags
;
3600 for( ; pflag
->name
; pflag
++) {
3601 if(setupdlg
->Flags
& pflag
->flag
) {
3602 strcat(flagstr
, pflag
->name
);
3603 strcat(flagstr
, "|");
3606 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3607 "hinst %p, flags %08x (%s)\n",
3608 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3609 setupdlg
->hDevNames
,
3610 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3613 /* Initialize default printer struct. If no printer device info is specified
3614 retrieve the default printer data. */
3615 memset(&pdlg
,0,sizeof(pdlg
));
3616 pdlg
.lStructSize
= sizeof(pdlg
);
3617 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3618 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3619 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3621 pdlg
.Flags
= PD_RETURNDEFAULT
;
3622 bRet
= PrintDlgW(&pdlg
);
3624 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3626 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3627 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3633 /* short cut exit, just return default values */
3634 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3635 static const WCHAR a4
[] = {'A','4',0};
3636 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3637 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3638 /* FIXME: Just return "A4" for now. */
3639 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3640 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3641 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3644 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3646 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3649 ptr
= LockResource( hDlgTmpl
);
3651 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3654 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3655 pdw
->dlgw
= setupdlg
;
3658 bRet
= (0<DialogBoxIndirectParamW(
3659 setupdlg
->hInstance
,
3661 setupdlg
->hwndOwner
,
3668 /***********************************************************************
3669 * PrintDlgExA (COMDLG32.@)
3677 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3680 FIXME("(%p) stub\n", lppd
);
3681 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3682 return E_INVALIDARG
;
3685 if (!IsWindow(lppd
->hwndOwner
)) {
3692 /***********************************************************************
3693 * PrintDlgExW (COMDLG32.@)
3695 * Display the property sheet style PRINT dialog box
3698 * lppd [IO] ptr to PRINTDLGEX struct
3702 * Failure: One of the following COM error codes:
3703 * E_OUTOFMEMORY Insufficient memory.
3704 * E_INVALIDARG One or more arguments are invalid.
3705 * E_POINTER Invalid pointer.
3706 * E_HANDLE Invalid handle.
3707 * E_FAIL Unspecified error.
3710 * This Dialog enables the user to specify specific properties of the print job.
3711 * The property sheet can also have additional application-specific and
3712 * driver-specific property pages.
3715 * Not fully implemented
3718 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3723 FIXME("(%p) not fully implemented\n", lppd
);
3725 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3726 return E_INVALIDARG
;
3729 if (!IsWindow(lppd
->hwndOwner
)) {
3733 if (lppd
->Flags
& PD_RETURNDEFAULT
) {
3734 PRINTER_INFO_2W
*pbuf
;
3735 DRIVER_INFO_2W
*dbuf
;
3737 DWORD needed
= 1024;
3740 if (lppd
->hDevMode
|| lppd
->hDevNames
) {
3741 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
3742 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3743 return E_INVALIDARG
;
3745 if (!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
3746 WARN("Can't find default printer\n");
3747 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
3751 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3752 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3753 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3754 HeapFree(GetProcessHeap(), 0, pbuf
);
3755 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3756 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3759 HeapFree(GetProcessHeap(), 0, pbuf
);
3765 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3766 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3767 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3768 HeapFree(GetProcessHeap(), 0, dbuf
);
3769 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3770 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3773 ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
3774 GetLastError(), debugstr_w(pbuf
->pPrinterName
));
3775 HeapFree(GetProcessHeap(), 0, dbuf
);
3776 HeapFree(GetProcessHeap(), 0, pbuf
);
3777 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3783 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
3787 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
3788 pbuf
->pDevMode
->dmDriverExtra
);
3789 if (lppd
->hDevMode
) {
3790 ptr
= GlobalLock(lppd
->hDevMode
);
3792 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
3793 pbuf
->pDevMode
->dmDriverExtra
);
3794 GlobalUnlock(lppd
->hDevMode
);
3798 HeapFree(GetProcessHeap(), 0, pbuf
);
3799 HeapFree(GetProcessHeap(), 0, dbuf
);