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_PaperSizeA(
485 PRINTDLGA
*pdlga
,const WORD PaperSize
,LPPOINT size
489 LPSTR devname
,portname
;
493 POINT
*points
= NULL
;
496 dn
= GlobalLock(pdlga
->hDevNames
);
497 dm
= GlobalLock(pdlga
->hDevMode
);
498 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
499 portname
= ((char*)dn
)+dn
->wOutputOffset
;
502 NrOfEntries
= DeviceCapabilitiesA(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
504 FIXME("No papernames found for %s/%s\n",devname
,portname
);
507 if (NrOfEntries
== -1) {
508 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
512 Words
= HeapAlloc(GetProcessHeap(),0,NrOfEntries
*sizeof(WORD
));
513 if (NrOfEntries
!= (ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERS
,(LPSTR
)Words
,dm
))) {
514 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
517 for (i
=0;i
<NrOfEntries
;i
++)
518 if (Words
[i
] == PaperSize
)
520 if (i
== NrOfEntries
) {
521 FIXME("Papersize %d not found in list?\n",PaperSize
);
524 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
525 if (NrOfEntries
!=(ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERSIZE
,(LPSTR
)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,Words
);
537 HeapFree(GetProcessHeap(),0,points
);
541 static BOOL
PRINTDLG_PaperSizeW(
542 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
546 LPWSTR devname
,portname
;
550 POINT
*points
= NULL
;
553 dn
= GlobalLock(pdlga
->hDevNames
);
554 dm
= GlobalLock(pdlga
->hDevMode
);
555 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
556 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
559 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
561 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
564 if (NrOfEntries
== -1) {
565 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
569 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
570 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
571 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
574 for (i
=0;i
<NrOfEntries
;i
++)
575 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
577 if (i
==NrOfEntries
) {
578 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
581 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
582 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
583 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
586 /* this is _10ths_ of a millimeter */
591 GlobalUnlock(pdlga
->hDevNames
);
592 GlobalUnlock(pdlga
->hDevMode
);
593 HeapFree(GetProcessHeap(),0,Names
);
594 HeapFree(GetProcessHeap(),0,points
);
599 /************************************************************************
600 * PRINTDLG_SetUpPaperComboBox
602 * Initialize either the papersize or inputslot combos of the Printer Setup
603 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
604 * We also try to re-select the old selection.
606 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
619 int fwCapability_Names
;
620 int fwCapability_Words
;
622 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
624 /* query the dialog box for the current selected value */
625 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
627 /* we enter here only if a different printer is selected after
628 * the Print Setup dialog is opened. The current settings are
629 * stored into the newly selected printer.
631 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
634 if (nIDComboBox
== cmb2
)
635 dm
->u1
.s1
.dmPaperSize
= oldWord
;
637 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
641 /* we enter here only when the Print setup dialog is initially
642 * opened. In this case the settings are restored from when
643 * the dialog was last closed.
646 if (nIDComboBox
== cmb2
)
647 oldWord
= dm
->u1
.s1
.dmPaperSize
;
649 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
653 if (nIDComboBox
== cmb2
) {
655 fwCapability_Names
= DC_PAPERNAMES
;
656 fwCapability_Words
= DC_PAPERS
;
660 fwCapability_Names
= DC_BINNAMES
;
661 fwCapability_Words
= DC_BINS
;
664 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
665 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
667 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
668 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
669 fwCapability_Names
, NULL
, dm
);
670 if (NrOfEntries
== 0)
671 WARN("no Name Entries found!\n");
672 else if (NrOfEntries
< 0)
675 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
677 ERR("Number of caps is different\n");
681 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
682 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
683 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
684 fwCapability_Names
, Names
, dm
);
685 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
686 fwCapability_Words
, (LPSTR
)Words
, dm
);
688 /* reset any current content in the combobox */
689 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
691 /* store new content */
692 for (i
= 0; i
< NrOfEntries
; i
++) {
693 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
694 (LPARAM
)(&Names
[i
*NamesSize
]) );
695 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
699 /* Look for old selection - can't do this is previous loop since
700 item order will change as more items are added */
702 for (i
= 0; i
< NrOfEntries
; i
++) {
703 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
709 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
711 HeapFree(GetProcessHeap(),0,Words
);
712 HeapFree(GetProcessHeap(),0,Names
);
716 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
718 const WCHAR
* PrinterName
,
719 const WCHAR
* PortName
,
729 int fwCapability_Names
;
730 int fwCapability_Words
;
732 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
734 /* query the dialog box for the current selected value */
735 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
737 /* we enter here only if a different printer is selected after
738 * the Print Setup dialog is opened. The current settings are
739 * stored into the newly selected printer.
741 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
744 if (nIDComboBox
== cmb2
)
745 dm
->u1
.s1
.dmPaperSize
= oldWord
;
747 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
751 /* we enter here only when the Print setup dialog is initially
752 * opened. In this case the settings are restored from when
753 * the dialog was last closed.
756 if (nIDComboBox
== cmb2
)
757 oldWord
= dm
->u1
.s1
.dmPaperSize
;
759 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
763 if (nIDComboBox
== cmb2
) {
765 fwCapability_Names
= DC_PAPERNAMES
;
766 fwCapability_Words
= DC_PAPERS
;
770 fwCapability_Names
= DC_BINNAMES
;
771 fwCapability_Words
= DC_BINS
;
774 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
775 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
777 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
778 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
779 fwCapability_Names
, NULL
, dm
);
780 if (NrOfEntries
== 0)
781 WARN("no Name Entries found!\n");
782 else if (NrOfEntries
< 0)
785 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
787 ERR("Number of caps is different\n");
791 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
792 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
793 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
794 fwCapability_Names
, Names
, dm
);
795 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
796 fwCapability_Words
, (LPWSTR
)Words
, dm
);
798 /* reset any current content in the combobox */
799 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
801 /* store new content */
802 for (i
= 0; i
< NrOfEntries
; i
++) {
803 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
804 (LPARAM
)(&Names
[i
*NamesSize
]) );
805 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
809 /* Look for old selection - can't do this is previous loop since
810 item order will change as more items are added */
812 for (i
= 0; i
< NrOfEntries
; i
++) {
813 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
819 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
821 HeapFree(GetProcessHeap(),0,Words
);
822 HeapFree(GetProcessHeap(),0,Names
);
827 /***********************************************************************
828 * PRINTDLG_UpdatePrinterInfoTexts [internal]
830 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
833 char ResourceString
[256];
839 /* add all status messages */
840 for (i
= 0; i
< 25; i
++) {
841 if (pi
->Status
& (1<<i
)) {
842 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
843 ResourceString
, 255);
844 strcat(StatusMsg
,ResourceString
);
848 /* FIXME: status==ready must only be appended if really so.
849 but how to detect? */
850 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
851 ResourceString
, 255);
852 strcat(StatusMsg
,ResourceString
);
853 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
855 /* set all other printer info texts */
856 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
858 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
859 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
861 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
862 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
866 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
868 WCHAR StatusMsg
[256];
869 WCHAR ResourceString
[256];
870 static const WCHAR emptyW
[] = {0};
876 /* add all status messages */
877 for (i
= 0; i
< 25; i
++) {
878 if (pi
->Status
& (1<<i
)) {
879 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
880 ResourceString
, 255);
881 lstrcatW(StatusMsg
,ResourceString
);
885 /* FIXME: status==ready must only be appended if really so.
886 but how to detect? */
887 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
888 ResourceString
, 255);
889 lstrcatW(StatusMsg
,ResourceString
);
890 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
892 /* set all other printer info texts */
893 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
894 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
895 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
897 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
898 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
902 /*******************************************************************
904 * PRINTDLG_ChangePrinter
907 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
908 PRINT_PTRA
*PrintStructures
)
910 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
911 LPDEVMODEA lpdm
= NULL
;
916 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
917 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
918 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
919 ERR("Can't open printer %s\n", name
);
922 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
923 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
924 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
926 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
927 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
928 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
930 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
935 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
937 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
938 PrintStructures
->lpDevMode
= NULL
;
940 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
942 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
945 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
946 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
948 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
949 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
950 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
951 /* Supplied devicemode matches current printer so try to use it */
952 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
953 DM_OUT_BUFFER
| DM_IN_BUFFER
);
956 GlobalUnlock(lppd
->hDevMode
);
958 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
960 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
961 /* Print range (All/Range/Selection) */
962 if(lppd
->nFromPage
!= 0xffff)
963 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
964 if(lppd
->nToPage
!= 0xffff)
965 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
967 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
968 if (lppd
->Flags
& PD_NOSELECTION
)
969 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
971 if (lppd
->Flags
& PD_SELECTION
)
972 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
973 if (lppd
->Flags
& PD_NOPAGENUMS
) {
974 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
975 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
976 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
977 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
978 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
980 if (lppd
->Flags
& PD_PAGENUMS
)
981 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
986 * FIXME: The ico3 is not displayed for some reason. I don't know why.
988 if (lppd
->Flags
& PD_COLLATE
) {
989 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
990 (LPARAM
)PrintStructures
->hCollateIcon
);
991 CheckDlgButton(hDlg
, chx2
, 1);
993 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
994 (LPARAM
)PrintStructures
->hNoCollateIcon
);
995 CheckDlgButton(hDlg
, chx2
, 0);
998 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
999 /* if printer doesn't support it: no Collate */
1000 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1001 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1002 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1009 if (lppd
->hDevMode
== 0)
1010 copies
= lppd
->nCopies
;
1012 copies
= lpdm
->u1
.s1
.dmCopies
;
1013 if(copies
== 0) copies
= 1;
1014 else if(copies
< 0) copies
= MAX_COPIES
;
1015 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1018 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1019 /* if printer doesn't support it: no nCopies */
1020 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1021 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1022 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1027 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1028 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1029 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1030 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1031 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1033 /* Fill print quality combo, PrintDlg16 */
1034 if(GetDlgItem(hDlg
, cmb1
))
1036 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1037 PrintStructures
->lpPrinterInfo
->pPortName
,
1038 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
1040 if(numResolutions
!= -1)
1042 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
1047 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
1048 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1051 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
1052 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1053 PrintStructures
->lpPrinterInfo
->pPortName
,
1054 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
1056 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1057 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1058 DeleteDC(hPrinterDC
);
1060 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1061 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1063 BOOL IsDefault
= FALSE
;
1066 if(Resolutions
[i
] == Resolutions
[i
+1])
1068 if(dpiX
== Resolutions
[i
])
1070 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1073 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1075 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1078 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1081 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1083 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1085 HeapFree(GetProcessHeap(), 0, Resolutions
);
1088 } else { /* PD_PRINTSETUP */
1089 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1091 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1092 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1093 PrintStructures
->lpPrinterInfo
->pPortName
,
1095 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1096 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1097 PrintStructures
->lpPrinterInfo
->pPortName
,
1099 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1100 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1101 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1102 PrintStructures
->hLandscapeIcon
));
1107 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1108 /* hide if PD_SHOWHELP not specified */
1109 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1114 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1115 PRINT_PTRW
*PrintStructures
)
1117 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1118 LPDEVMODEW lpdm
= NULL
;
1123 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1124 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1125 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1126 ERR("Can't open printer %s\n", debugstr_w(name
));
1129 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1130 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
1131 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1133 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1134 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
1135 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1137 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1142 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1144 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1145 PrintStructures
->lpDevMode
= NULL
;
1147 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1149 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1152 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1153 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1155 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1156 !lstrcmpW(lpdm
->dmDeviceName
,
1157 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1158 /* Supplied devicemode matches current printer so try to use it */
1159 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1160 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1163 GlobalUnlock(lppd
->hDevMode
);
1165 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1167 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1168 /* Print range (All/Range/Selection) */
1169 if(lppd
->nFromPage
!= 0xffff)
1170 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1171 if(lppd
->nToPage
!= 0xffff)
1172 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1174 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1175 if (lppd
->Flags
& PD_NOSELECTION
)
1176 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1178 if (lppd
->Flags
& PD_SELECTION
)
1179 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1180 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1181 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1182 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1183 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1184 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1185 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1187 if (lppd
->Flags
& PD_PAGENUMS
)
1188 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1193 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1195 if (lppd
->Flags
& PD_COLLATE
) {
1196 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1197 (LPARAM
)PrintStructures
->hCollateIcon
);
1198 CheckDlgButton(hDlg
, chx2
, 1);
1200 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1201 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1202 CheckDlgButton(hDlg
, chx2
, 0);
1205 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1206 /* if printer doesn't support it: no Collate */
1207 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1208 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1209 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1216 if (lppd
->hDevMode
== 0)
1217 copies
= lppd
->nCopies
;
1219 copies
= lpdm
->u1
.s1
.dmCopies
;
1220 if(copies
== 0) copies
= 1;
1221 else if(copies
< 0) copies
= MAX_COPIES
;
1222 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1225 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1226 /* if printer doesn't support it: no nCopies */
1227 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1228 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1229 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1234 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1235 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1236 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1237 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1238 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1240 } else { /* PD_PRINTSETUP */
1241 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1243 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1244 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1245 PrintStructures
->lpPrinterInfo
->pPortName
,
1247 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1248 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1249 PrintStructures
->lpPrinterInfo
->pPortName
,
1251 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1252 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1253 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1254 PrintStructures
->hLandscapeIcon
));
1259 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1260 /* hide if PD_SHOWHELP not specified */
1261 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1266 /***********************************************************************
1267 * check_printer_setup [internal]
1269 static LRESULT
check_printer_setup(HWND hDlg
)
1272 WCHAR resourcestr
[256],resultstr
[256];
1274 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1277 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1283 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1284 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1285 MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1290 /***********************************************************************
1291 * PRINTDLG_WMInitDialog [internal]
1293 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1294 PRINT_PTRA
* PrintStructures
)
1296 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1300 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1302 /* load Collate ICONs */
1303 /* We load these with LoadImage because they are not a standard
1304 size and we don't want them rescaled */
1305 PrintStructures
->hCollateIcon
=
1306 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1307 PrintStructures
->hNoCollateIcon
=
1308 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1310 /* These can be done with LoadIcon */
1311 PrintStructures
->hPortraitIcon
=
1312 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1313 PrintStructures
->hLandscapeIcon
=
1314 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1316 /* display the collate/no_collate icon */
1317 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1318 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1320 if(PrintStructures
->hCollateIcon
== 0 ||
1321 PrintStructures
->hNoCollateIcon
== 0 ||
1322 PrintStructures
->hPortraitIcon
== 0 ||
1323 PrintStructures
->hLandscapeIcon
== 0) {
1324 ERR("no icon in resourcefile\n");
1325 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1326 EndDialog(hDlg
, FALSE
);
1330 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1331 * must be registered and the Help button must be shown.
1333 if (lppd
->Flags
& PD_SHOWHELP
) {
1334 if((PrintStructures
->HelpMessageID
=
1335 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1336 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1340 PrintStructures
->HelpMessageID
= 0;
1342 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1343 PrintStructures
->hwndUpDown
=
1344 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1345 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1346 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1347 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1348 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1351 /* FIXME: I allow more freedom than either Win95 or WinNT,
1352 * which do not agree to what errors should be thrown or not
1353 * in case nToPage or nFromPage is out-of-range.
1355 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1356 lppd
->nMaxPage
= lppd
->nMinPage
;
1357 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1358 lppd
->Flags
|= PD_NOPAGENUMS
;
1359 if (lppd
->nToPage
< lppd
->nMinPage
)
1360 lppd
->nToPage
= lppd
->nMinPage
;
1361 if (lppd
->nToPage
> lppd
->nMaxPage
)
1362 lppd
->nToPage
= lppd
->nMaxPage
;
1363 if (lppd
->nFromPage
< lppd
->nMinPage
)
1364 lppd
->nFromPage
= lppd
->nMinPage
;
1365 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1366 lppd
->nFromPage
= lppd
->nMaxPage
;
1368 /* if we have the combo box, fill it */
1369 if (GetDlgItem(hDlg
,comboID
)) {
1372 pdn
= GlobalLock(lppd
->hDevNames
);
1373 pdm
= GlobalLock(lppd
->hDevMode
);
1375 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1377 name
= (char*)pdm
->dmDeviceName
;
1378 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1379 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1380 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1382 /* Now find selected printer and update rest of dlg */
1383 name
= HeapAlloc(GetProcessHeap(),0,256);
1384 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1385 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1386 HeapFree(GetProcessHeap(),0,name
);
1388 /* else use default printer */
1390 DWORD dwBufLen
= sizeof(name
);
1391 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1394 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1396 FIXME("No default printer found, expect problems!\n");
1401 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1402 PRINT_PTRW
* PrintStructures
)
1404 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1408 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1410 /* load Collate ICONs */
1411 /* We load these with LoadImage because they are not a standard
1412 size and we don't want them rescaled */
1413 PrintStructures
->hCollateIcon
=
1414 LoadImageW(COMDLG32_hInstance
, pd32_collateW
, IMAGE_ICON
, 0, 0, 0);
1415 PrintStructures
->hNoCollateIcon
=
1416 LoadImageW(COMDLG32_hInstance
, pd32_nocollateW
, IMAGE_ICON
, 0, 0, 0);
1418 /* These can be done with LoadIcon */
1419 PrintStructures
->hPortraitIcon
=
1420 LoadIconW(COMDLG32_hInstance
, pd32_portraitW
);
1421 PrintStructures
->hLandscapeIcon
=
1422 LoadIconW(COMDLG32_hInstance
, pd32_landscapeW
);
1424 /* display the collate/no_collate icon */
1425 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1426 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1428 if(PrintStructures
->hCollateIcon
== 0 ||
1429 PrintStructures
->hNoCollateIcon
== 0 ||
1430 PrintStructures
->hPortraitIcon
== 0 ||
1431 PrintStructures
->hLandscapeIcon
== 0) {
1432 ERR("no icon in resourcefile\n");
1433 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1434 EndDialog(hDlg
, FALSE
);
1438 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1439 * must be registered and the Help button must be shown.
1441 if (lppd
->Flags
& PD_SHOWHELP
) {
1442 if((PrintStructures
->HelpMessageID
=
1443 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1444 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1448 PrintStructures
->HelpMessageID
= 0;
1450 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1451 PrintStructures
->hwndUpDown
=
1452 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1453 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1454 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1455 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1456 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1459 /* FIXME: I allow more freedom than either Win95 or WinNT,
1460 * which do not agree to what errors should be thrown or not
1461 * in case nToPage or nFromPage is out-of-range.
1463 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1464 lppd
->nMaxPage
= lppd
->nMinPage
;
1465 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1466 lppd
->Flags
|= PD_NOPAGENUMS
;
1467 if (lppd
->nToPage
< lppd
->nMinPage
)
1468 lppd
->nToPage
= lppd
->nMinPage
;
1469 if (lppd
->nToPage
> lppd
->nMaxPage
)
1470 lppd
->nToPage
= lppd
->nMaxPage
;
1471 if (lppd
->nFromPage
< lppd
->nMinPage
)
1472 lppd
->nFromPage
= lppd
->nMinPage
;
1473 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1474 lppd
->nFromPage
= lppd
->nMaxPage
;
1476 /* if we have the combo box, fill it */
1477 if (GetDlgItem(hDlg
,comboID
)) {
1480 pdn
= GlobalLock(lppd
->hDevNames
);
1481 pdm
= GlobalLock(lppd
->hDevMode
);
1483 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1485 name
= pdm
->dmDeviceName
;
1486 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1487 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1488 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1490 /* Now find selected printer and update rest of dlg */
1491 /* ansi is ok here */
1492 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1493 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1494 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1495 HeapFree(GetProcessHeap(),0,name
);
1497 /* else use default printer */
1499 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1500 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1503 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1505 FIXME("No default printer found, expect problems!\n");
1510 /***********************************************************************
1511 * PRINTDLG_WMCommand [internal]
1513 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1514 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1516 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1517 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1518 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1520 switch (LOWORD(wParam
)) {
1522 TRACE(" OK button was hit\n");
1523 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1524 FIXME("Update printdlg was not successful!\n");
1527 EndDialog(hDlg
, TRUE
);
1531 TRACE(" CANCEL button was hit\n");
1532 EndDialog(hDlg
, FALSE
);
1536 TRACE(" HELP button was hit\n");
1537 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1538 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1541 case chx2
: /* collate pages checkbox */
1542 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1543 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1544 (LPARAM
)PrintStructures
->hCollateIcon
);
1546 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1547 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1549 case edt1
: /* from page nr editbox */
1550 case edt2
: /* to page nr editbox */
1551 if (HIWORD(wParam
)==EN_CHANGE
) {
1554 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1555 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1556 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1557 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1562 if(HIWORD(wParam
) == EN_CHANGE
) {
1563 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1565 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1567 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1572 case psh1
: /* Print Setup */
1576 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1577 FIXME("The 32bit print dialog does not have this button!?\n");
1581 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1582 pdlg
.Flags
|= PD_PRINTSETUP
;
1583 pdlg
.hwndOwner
= HWND_16(hDlg
);
1584 if (!PrintDlg16(&pdlg
))
1589 case psh2
: /* Properties button */
1592 char PrinterName
[256];
1594 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1595 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1596 FIXME(" Call to OpenPrinter did not succeed!\n");
1599 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1600 PrintStructures
->lpDevMode
,
1601 PrintStructures
->lpDevMode
,
1602 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1603 ClosePrinter(hPrinter
);
1607 case rad1
: /* Paperorientation */
1608 if (lppd
->Flags
& PD_PRINTSETUP
)
1610 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1611 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1612 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1616 case rad2
: /* Paperorientation */
1617 if (lppd
->Flags
& PD_PRINTSETUP
)
1619 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1620 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1621 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1625 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1626 if (PrinterComboID
!= LOWORD(wParam
)) {
1630 case cmb4
: /* Printer combobox */
1631 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1632 char PrinterName
[256];
1633 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1634 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1638 case cmb2
: /* Papersize */
1640 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1642 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1648 case cmb3
: /* Bin */
1650 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1652 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1653 CB_GETITEMDATA
, Sel
,
1658 if(lppd
->Flags
& PD_PRINTSETUP
) {
1659 switch (LOWORD(wParam
)) {
1660 case rad1
: /* orientation */
1662 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1663 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1664 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1665 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1667 (LPARAM
)PrintStructures
->hPortraitIcon
);
1668 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1670 (LPARAM
)PrintStructures
->hPortraitIcon
);
1673 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1674 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1675 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1677 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1678 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1680 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1689 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1690 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1692 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1693 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1694 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1696 switch (LOWORD(wParam
)) {
1698 TRACE(" OK button was hit\n");
1699 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1700 FIXME("Update printdlg was not successful!\n");
1703 EndDialog(hDlg
, TRUE
);
1707 TRACE(" CANCEL button was hit\n");
1708 EndDialog(hDlg
, FALSE
);
1712 TRACE(" HELP button was hit\n");
1713 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1714 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1717 case chx2
: /* collate pages checkbox */
1718 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1719 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1720 (LPARAM
)PrintStructures
->hCollateIcon
);
1722 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1723 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1725 case edt1
: /* from page nr editbox */
1726 case edt2
: /* to page nr editbox */
1727 if (HIWORD(wParam
)==EN_CHANGE
) {
1730 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1731 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1732 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1733 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1738 if(HIWORD(wParam
) == EN_CHANGE
) {
1739 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1741 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1743 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1747 case psh1
: /* Print Setup */
1749 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1752 case psh2
: /* Properties button */
1755 WCHAR PrinterName
[256];
1757 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1758 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1759 FIXME(" Call to OpenPrinter did not succeed!\n");
1762 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1763 PrintStructures
->lpDevMode
,
1764 PrintStructures
->lpDevMode
,
1765 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1766 ClosePrinter(hPrinter
);
1770 case rad1
: /* Paperorientation */
1771 if (lppd
->Flags
& PD_PRINTSETUP
)
1773 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1774 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1775 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1779 case rad2
: /* Paperorientation */
1780 if (lppd
->Flags
& PD_PRINTSETUP
)
1782 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1783 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1784 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1788 case cmb1
: /* Printer Combobox in PRINT SETUP */
1790 case cmb4
: /* Printer combobox */
1791 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1792 WCHAR PrinterName
[256];
1793 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1794 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1798 case cmb2
: /* Papersize */
1800 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1802 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1808 case cmb3
: /* Bin */
1810 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1812 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1813 CB_GETITEMDATA
, Sel
,
1818 if(lppd
->Flags
& PD_PRINTSETUP
) {
1819 switch (LOWORD(wParam
)) {
1820 case rad1
: /* orientation */
1822 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1823 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1824 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1825 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1827 (LPARAM
)PrintStructures
->hPortraitIcon
);
1828 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1830 (LPARAM
)PrintStructures
->hPortraitIcon
);
1833 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1834 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1835 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1837 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1838 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1840 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1849 /***********************************************************************
1850 * PrintDlgProcA [internal]
1852 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1855 PRINT_PTRA
* PrintStructures
;
1856 INT_PTR res
= FALSE
;
1858 if (uMsg
!=WM_INITDIALOG
) {
1859 PrintStructures
= GetPropW(hDlg
, printdlg_prop
);
1860 if (!PrintStructures
)
1863 PrintStructures
= (PRINT_PTRA
*) lParam
;
1864 SetPropW(hDlg
, printdlg_prop
, PrintStructures
);
1865 if(!check_printer_setup(hDlg
))
1867 EndDialog(hDlg
,FALSE
);
1870 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1872 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1873 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1874 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1879 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1880 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1887 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1890 DestroyIcon(PrintStructures
->hCollateIcon
);
1891 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1892 DestroyIcon(PrintStructures
->hPortraitIcon
);
1893 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1894 if(PrintStructures
->hwndUpDown
)
1895 DestroyWindow(PrintStructures
->hwndUpDown
);
1901 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1904 PRINT_PTRW
* PrintStructures
;
1905 INT_PTR res
= FALSE
;
1907 if (uMsg
!=WM_INITDIALOG
) {
1908 PrintStructures
= GetPropW(hDlg
, printdlg_prop
);
1909 if (!PrintStructures
)
1912 PrintStructures
= (PRINT_PTRW
*) lParam
;
1913 SetPropW(hDlg
, printdlg_prop
, PrintStructures
);
1914 if(!check_printer_setup(hDlg
))
1916 EndDialog(hDlg
,FALSE
);
1919 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1921 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1922 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1926 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1927 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1933 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1936 DestroyIcon(PrintStructures
->hCollateIcon
);
1937 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1938 DestroyIcon(PrintStructures
->hPortraitIcon
);
1939 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1940 if(PrintStructures
->hwndUpDown
)
1941 DestroyWindow(PrintStructures
->hwndUpDown
);
1947 /************************************************************
1949 * PRINTDLG_GetDlgTemplate
1952 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1957 if (lppd
->Flags
& PD_PRINTSETUP
) {
1958 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1959 hDlgTmpl
= lppd
->hSetupTemplate
;
1960 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1961 hResInfo
= FindResourceA(lppd
->hInstance
,
1962 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1963 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1965 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1967 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1970 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1971 hDlgTmpl
= lppd
->hPrintTemplate
;
1972 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1973 hResInfo
= FindResourceA(lppd
->hInstance
,
1974 lppd
->lpPrintTemplateName
,
1976 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1978 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1980 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1986 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1990 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1991 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1993 if (lppd
->Flags
& PD_PRINTSETUP
) {
1994 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1995 hDlgTmpl
= lppd
->hSetupTemplate
;
1996 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1997 hResInfo
= FindResourceW(lppd
->hInstance
,
1998 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1999 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2001 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
2002 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2005 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
2006 hDlgTmpl
= lppd
->hPrintTemplate
;
2007 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
2008 hResInfo
= FindResourceW(lppd
->hInstance
,
2009 lppd
->lpPrintTemplateName
,
2011 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2013 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
2014 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2020 /***********************************************************************
2025 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
2027 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2028 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
2030 if(lppd
->Flags
& PD_RETURNDC
) {
2031 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
2032 (char*)pdn
+ pdn
->wDeviceOffset
,
2033 (char*)pdn
+ pdn
->wOutputOffset
,
2035 } else if(lppd
->Flags
& PD_RETURNIC
) {
2036 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
2037 (char*)pdn
+ pdn
->wDeviceOffset
,
2038 (char*)pdn
+ pdn
->wOutputOffset
,
2041 GlobalUnlock(lppd
->hDevNames
);
2042 GlobalUnlock(lppd
->hDevMode
);
2043 return lppd
->hDC
? TRUE
: FALSE
;
2046 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
2048 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2049 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
2051 if(lppd
->Flags
& PD_RETURNDC
) {
2052 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2053 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2054 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2056 } else if(lppd
->Flags
& PD_RETURNIC
) {
2057 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2058 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2059 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2062 GlobalUnlock(lppd
->hDevNames
);
2063 GlobalUnlock(lppd
->hDevMode
);
2064 return lppd
->hDC
? TRUE
: FALSE
;
2067 /***********************************************************************
2068 * PrintDlgA (COMDLG32.@)
2070 * Displays the PRINT dialog box, which enables the user to specify
2071 * specific properties of the print job.
2074 * lppd [IO] ptr to PRINTDLG32 struct
2077 * nonzero if the user pressed the OK button
2078 * zero if the user cancelled the window or an error occurred
2082 * * The Collate Icons do not display, even though they are in the code.
2083 * * The Properties Button(s) should call DocumentPropertiesA().
2086 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2094 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2098 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2099 if(TRACE_ON(commdlg
)) {
2100 char flagstr
[1000] = "";
2101 const struct pd_flags
*pflag
= pd_flags
;
2102 for( ; pflag
->name
; pflag
++) {
2103 if(lppd
->Flags
& pflag
->flag
)
2104 strcat(flagstr
, pflag
->name
);
2106 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2107 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2108 "flags %08x (%s)\n",
2109 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2110 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2111 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2114 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2115 WARN("structure size failure !!!\n");
2116 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2120 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2121 PRINTER_INFO_2A
*pbuf
;
2122 DRIVER_INFO_3A
*dbuf
;
2126 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2127 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2128 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2131 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2132 WARN("Can't find default printer\n");
2133 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2137 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2138 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2139 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2141 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2142 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2143 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2144 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2145 GetLastError(),pbuf
->pPrinterName
);
2146 HeapFree(GetProcessHeap(), 0, dbuf
);
2147 HeapFree(GetProcessHeap(), 0, pbuf
);
2148 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2153 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2157 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2158 pbuf
->pDevMode
->dmDriverExtra
);
2159 ptr
= GlobalLock(lppd
->hDevMode
);
2160 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2161 pbuf
->pDevMode
->dmDriverExtra
);
2162 GlobalUnlock(lppd
->hDevMode
);
2163 HeapFree(GetProcessHeap(), 0, pbuf
);
2164 HeapFree(GetProcessHeap(), 0, dbuf
);
2168 PRINT_PTRA
*PrintStructures
;
2170 /* load Dialog resources,
2171 * depending on Flags indicates Print32 or Print32_setup dialog
2173 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2175 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2178 ptr
= LockResource( hDlgTmpl
);
2180 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2184 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2185 sizeof(PRINT_PTRA
));
2186 PrintStructures
->lpPrintDlg
= lppd
;
2188 /* and create & process the dialog .
2189 * -1 is failure, 0 is broken hwnd, everything else is ok.
2191 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2193 (LPARAM
)PrintStructures
));
2196 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2197 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2198 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2200 if (lppd
->hDevMode
== 0) {
2201 TRACE(" No hDevMode yet... Need to create my own\n");
2202 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2203 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2205 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2206 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2209 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2210 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2212 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2217 GlobalUnlock(lppd
->hDevMode
);
2219 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2220 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2221 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2222 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2224 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2225 bRet
= PRINTDLG_CreateDCA(lppd
);
2227 TRACE("exit! (%d)\n", bRet
);
2231 /***********************************************************************
2232 * PrintDlgW (COMDLG32.@)
2236 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2244 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2248 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2249 if(TRACE_ON(commdlg
)) {
2250 char flagstr
[1000] = "";
2251 const struct pd_flags
*pflag
= pd_flags
;
2252 for( ; pflag
->name
; pflag
++) {
2253 if(lppd
->Flags
& pflag
->flag
)
2254 strcat(flagstr
, pflag
->name
);
2256 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2257 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2258 "flags %08x (%s)\n",
2259 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2260 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2261 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2264 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2265 WARN("structure size failure !!!\n");
2266 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2270 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2271 PRINTER_INFO_2W
*pbuf
;
2272 DRIVER_INFO_3W
*dbuf
;
2276 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2277 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2278 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2281 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2282 WARN("Can't find default printer\n");
2283 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2287 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2288 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2289 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2291 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2292 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2293 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2294 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2295 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2296 HeapFree(GetProcessHeap(), 0, dbuf
);
2297 HeapFree(GetProcessHeap(), 0, pbuf
);
2298 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2303 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2307 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2308 pbuf
->pDevMode
->dmDriverExtra
);
2309 ptr
= GlobalLock(lppd
->hDevMode
);
2310 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2311 pbuf
->pDevMode
->dmDriverExtra
);
2312 GlobalUnlock(lppd
->hDevMode
);
2313 HeapFree(GetProcessHeap(), 0, pbuf
);
2314 HeapFree(GetProcessHeap(), 0, dbuf
);
2318 PRINT_PTRW
*PrintStructures
;
2320 /* load Dialog resources,
2321 * depending on Flags indicates Print32 or Print32_setup dialog
2323 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2325 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2328 ptr
= LockResource( hDlgTmpl
);
2330 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2334 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2335 sizeof(PRINT_PTRW
));
2336 PrintStructures
->lpPrintDlg
= lppd
;
2338 /* and create & process the dialog .
2339 * -1 is failure, 0 is broken hwnd, everything else is ok.
2341 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2343 (LPARAM
)PrintStructures
));
2346 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2347 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2348 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2350 if (lppd
->hDevMode
== 0) {
2351 TRACE(" No hDevMode yet... Need to create my own\n");
2352 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2353 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2356 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2357 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2359 GlobalUnlock(lppd
->hDevMode
);
2360 TRACE("Now got %d locks\n", locks
);
2363 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2364 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2367 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2368 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2370 if (lppd
->hDevNames
!= 0) {
2372 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2373 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2375 GlobalUnlock(lppd
->hDevNames
);
2378 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2383 GlobalUnlock(lppd
->hDevMode
);
2385 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2386 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2387 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2388 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2390 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2391 bRet
= PRINTDLG_CreateDCW(lppd
);
2393 TRACE("exit! (%d)\n", bRet
);
2397 /***********************************************************************
2402 * cmb1 - printer select (not in standard dialog template)
2404 * cmb3 - source (tray?)
2405 * edt4 - border left
2407 * edt6 - border right
2408 * edt7 - border bottom
2409 * psh3 - "Printer..."
2413 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2415 HWND hDlg
; /* Page Setup dialog handler */
2416 PAGESETUPDLGA curdlg
; /* Stores the current dialog state */
2417 RECT rtDrawRect
; /* Drawing rect for page */
2421 LPPAGESETUPDLGW dlgw
;
2423 PAGESETUPDLGW curdlg
; /* Current dialog state */
2427 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2432 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2433 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2434 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2435 hResInfo
= FindResourceA(lppd
->hInstance
,
2436 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2437 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2439 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2440 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2445 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2450 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2451 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2452 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2453 hResInfo
= FindResourceW(lppd
->hInstance
,
2454 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2455 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2457 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2458 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2464 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2465 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2466 return 10*size
*100/254;
2467 /* If we don't have a flag, we can choose one. Use millimeters
2468 * to avoid confusing me
2470 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2476 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2477 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2479 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2480 return (size
*254)/100;
2481 /* if we don't have a flag, we can choose one. Use millimeters
2482 * to avoid confusing me
2484 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2485 return (size
*254)/100;
2489 _c_size2strA(PageSetupDataA
*pda
,DWORD size
,LPSTR strout
) {
2490 strcpy(strout
,"<undef>");
2491 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2492 sprintf(strout
,"%d",(size
)/100);
2495 if (pda
->dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2496 sprintf(strout
,"%din",(size
)/1000);
2499 pda
->dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2500 sprintf(strout
,"%d",(size
)/100);
2504 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2505 static const char mm_fmt
[] = "%.2f mm";
2506 static const char in_fmt
[] = "%.2f in";
2508 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2509 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2510 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2511 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2513 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2514 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2517 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2521 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2526 if (!sscanf(strin
,"%f%s",&val
,rest
))
2529 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2530 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2533 return val
*25.4*100;
2535 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2536 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2538 if (!strcmp(rest
,"mm")) {
2539 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2542 return 1000.0*val
/25.4;
2544 if (rest
[0]=='\0') {
2545 /* use application supplied default */
2546 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2550 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2555 ERR("Did not find a conversion for type '%s'!\n",rest
);
2561 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2564 /* this W -> A transition is OK */
2565 /* we need a unicode version of sscanf to avoid it */
2566 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2567 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2571 /****************************************************************************
2572 * PRINTDLG_PS_UpdateDlgStructA
2574 * Updates pda->dlga structure
2575 * Function calls when user presses OK button
2578 * hDlg [in] main window dialog HANDLE
2579 * pda [in/out] ptr to PageSetupDataA structure
2585 PRINTDLG_PS_UpdateDlgStructA(HWND hDlg
, PageSetupDataA
*pda
) {
2589 memcpy(pda
->dlga
, &pda
->curdlg
, sizeof(pda
->curdlg
));
2590 pda
->dlga
->hDevMode
= pda
->pdlg
.hDevMode
;
2591 pda
->dlga
->hDevNames
= pda
->pdlg
.hDevNames
;
2593 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2595 /* Save paper orientation into device context */
2596 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
)
2597 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2599 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2601 /* Save paper size into the device context */
2602 paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2603 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2604 if (paperword
!= CB_ERR
)
2605 dm
->u1
.s1
.dmPaperSize
= paperword
;
2607 FIXME("could not get dialog text for papersize cmbbox?\n");
2609 /* Save paper source into the device context */
2610 paperword
= SendDlgItemMessageA(hDlg
,cmb1
,CB_GETITEMDATA
,
2611 SendDlgItemMessageA(hDlg
, cmb1
, CB_GETCURSEL
, 0, 0), 0);
2612 if (paperword
!= CB_ERR
)
2613 dm
->u1
.s1
.dmDefaultSource
= paperword
;
2615 FIXME("could not get dialog text for papersize cmbbox?\n");
2617 GlobalUnlock(pda
->pdlg
.hDevMode
);
2623 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2626 LPWSTR devname
,portname
;
2627 WCHAR papername
[64];
2630 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2631 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2632 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2633 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2635 /* Save paper size into device context */
2636 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2637 /* Save paper source into device context */
2638 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2640 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2641 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2642 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2643 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2645 FIXME("could not get dialog text for papersize cmbbox?\n");
2646 #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); }
2647 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2648 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2649 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2650 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2653 /* If we are in landscape, swap x and y of page size */
2654 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2656 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2657 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2658 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2661 /* Save orientation */
2662 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2663 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2665 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2667 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2668 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2672 /**********************************************************************************************
2673 * PRINTDLG_PS_ChangeActivePrinerA
2675 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2678 * name [in] Name of a printer for activation
2679 * pda [in/out] ptr to PageSetupDataA structure
2686 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2689 LPPRINTER_INFO_2A lpPrinterInfo
;
2690 LPDRIVER_INFO_3A lpDriverInfo
;
2691 DEVMODEA
*pDevMode
, *dm
;
2693 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2694 ERR("Can't open printer %s\n", name
);
2697 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2698 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2699 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2700 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2701 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2702 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2703 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2704 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2705 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2710 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2712 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2713 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2714 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2717 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2718 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2720 pda
->pdlg
.hDevMode
= GlobalReAlloc(pda
->pdlg
.hDevMode
,
2721 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2723 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2724 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2726 PRINTDLG_CreateDevNames(&(pda
->pdlg
.hDevNames
),
2727 lpDriverInfo
->pDriverPath
,
2728 lpPrinterInfo
->pPrinterName
,
2729 lpPrinterInfo
->pPortName
);
2731 GlobalUnlock(pda
->pdlg
.hDevMode
);
2732 HeapFree(GetProcessHeap(), 0, pDevMode
);
2733 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2734 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2738 /****************************************************************************************
2739 * PRINTDLG_PS_ChangePrinterA
2741 * Fills Printers, Paper and Source combo
2747 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2750 LPSTR devname
,portname
;
2752 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2753 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2754 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2755 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2756 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2757 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2758 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2759 GlobalUnlock(pda
->pdlg
.hDevNames
);
2760 GlobalUnlock(pda
->pdlg
.hDevMode
);
2764 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2766 WCHAR PaperName
[64];
2768 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2769 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2770 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2771 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2773 if(IsDlgButtonChecked(hDlg
, rad2
))
2775 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2776 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2777 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2781 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2786 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2791 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2792 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2794 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2796 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2799 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2801 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2805 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2808 LPWSTR devname
,portname
;
2810 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2811 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2812 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2813 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2814 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2815 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2817 /* Landscape orientation */
2818 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2819 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2820 else /* this is default if papersize is not set */
2821 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2823 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2824 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2826 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2831 /******************************************************************************************
2832 * PRINTDLG_PS_ChangePaperPrev
2834 * Changes paper preview size / position
2837 * pda [i] Pointer for current PageSetupDataA structure
2843 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2845 LONG width
, height
, x
, y
;
2848 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) {
2849 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2850 height
= pda
->curdlg
.ptPaperSize
.y
* width
/ pda
->curdlg
.ptPaperSize
.x
;
2852 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2853 width
= pda
->curdlg
.ptPaperSize
.x
* height
/ pda
->curdlg
.ptPaperSize
.y
;
2855 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2856 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2857 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2858 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2859 x
, y
, width
, height
);
2862 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2863 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2864 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2865 rtTmp
= pda
->rtDrawRect
;
2866 rtTmp
.right
+= SHADOW
;
2867 rtTmp
.bottom
+= SHADOW
;
2870 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2874 #define GETVAL(idc,val) \
2875 if(msg == EN_CHANGE){ \
2876 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2877 val = _c_str2sizeA(pda->dlga,buf); \
2879 FIXME("could not get dlgitemtexta for %x\n",id); \
2882 /********************************************************************************
2883 * PRINTDLG_PS_WMCommandA
2884 * process WM_COMMAND message for PageSetupDlgA
2887 * hDlg [in] Main dialog HANDLE
2888 * wParam [in] WM_COMMAND wParam
2889 * lParam [in] WM_COMMAND lParam
2890 * pda [in/out] ptr to PageSetupDataA
2894 PRINTDLG_PS_WMCommandA(
2895 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2897 WORD msg
= HIWORD(wParam
);
2898 WORD id
= LOWORD(wParam
);
2901 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2902 LOWORD(lParam
),wParam
,lParam
);
2905 if (!PRINTDLG_PS_UpdateDlgStructA(hDlg
, pda
))
2907 EndDialog(hDlg
, TRUE
);
2911 EndDialog(hDlg
, FALSE
);
2915 pda
->pdlg
.Flags
= 0;
2916 pda
->pdlg
.hwndOwner
= hDlg
;
2917 if (PrintDlgA(&(pda
->pdlg
)))
2918 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2923 if((id
== rad1
&& pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) ||
2924 (id
== rad2
&& pda
->curdlg
.ptPaperSize
.y
> pda
->curdlg
.ptPaperSize
.x
))
2928 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2930 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2931 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2933 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2934 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2935 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2936 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2938 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2939 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2940 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2941 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2943 PRINTDLG_PS_ChangePaperPrev(pda
);
2946 case cmb1
: /* Printer combo */
2947 if(msg
== CBN_SELCHANGE
){
2948 char crPrinterName
[256];
2949 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2950 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2951 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2954 case cmb2
: /* Paper combo */
2955 if(msg
== CBN_SELCHANGE
){
2956 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2957 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2958 if (paperword
!= CB_ERR
) {
2959 PRINTDLG_PaperSizeA(&(pda
->pdlg
), paperword
,&(pda
->curdlg
.ptPaperSize
));
2960 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.x
);
2961 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.y
);
2963 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2964 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2965 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2966 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2968 PRINTDLG_PS_ChangePaperPrev(pda
);
2970 FIXME("could not get dialog text for papersize cmbbox?\n");
2974 if(msg
== CBN_SELCHANGE
){
2975 DEVMODEA
*dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2976 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2977 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2978 GlobalUnlock(pda
->pdlg
.hDevMode
);
2981 case psh2
: /* Printer Properties button */
2984 char PrinterName
[256];
2989 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2990 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2991 FIXME("Call to OpenPrinter did not succeed!\n");
2994 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2995 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2996 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2997 ClosePrinter(hPrinter
);
2998 /* Changing paper */
2999 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &(pda
->curdlg
.ptPaperSize
));
3000 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3001 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3002 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
3003 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
3004 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
3005 pda
->curdlg
.ptPaperSize
.y
= tmp
;
3006 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3009 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3010 /* Changing paper preview */
3011 PRINTDLG_PS_ChangePaperPrev(pda
);
3012 /* Selecting paper in combo */
3013 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
3014 if(count
!= CB_ERR
){
3015 for(i
=0; i
<count
; ++i
){
3016 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
3017 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
3023 GlobalUnlock(pda
->pdlg
.hDevMode
);
3027 GETVAL(id
, pda
->curdlg
.rtMargin
.left
);
3030 GETVAL(id
, pda
->curdlg
.rtMargin
.top
);
3033 GETVAL(id
, pda
->curdlg
.rtMargin
.right
);
3036 GETVAL(id
, pda
->curdlg
.rtMargin
.bottom
);
3039 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3045 PRINTDLG_PS_WMCommandW(
3046 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3048 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3049 LOWORD(lParam
),wParam
,lParam
);
3050 switch (LOWORD(wParam
)) {
3052 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3054 EndDialog(hDlg
, TRUE
);
3058 EndDialog(hDlg
, FALSE
);
3063 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3064 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3068 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3070 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3071 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3073 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3074 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3075 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3076 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3078 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3079 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3080 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3081 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3086 pdw
->pdlg
.Flags
= 0;
3087 pdw
->pdlg
.hwndOwner
= hDlg
;
3088 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3089 if (PrintDlgW(&(pdw
->pdlg
)))
3090 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3098 /***********************************************************************
3099 * DefaultPagePaintHook
3100 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3101 * whenever the sample page is redrawn.
3105 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3106 const PageSetupDataA
*pda
)
3108 LPRECT lprc
= (LPRECT
) lParam
;
3109 HDC hdc
= (HDC
) wParam
;
3112 HFONT hfont
, holdfont
;
3114 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3115 /* Call user paint hook if enable */
3116 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3117 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3121 /* LPPAGESETUPDLG in lParam */
3122 case WM_PSD_PAGESETUPDLG
:
3123 /* Inform about the sample page rectangle */
3124 case WM_PSD_FULLPAGERECT
:
3125 /* Inform about the margin rectangle */
3126 case WM_PSD_MINMARGINRECT
:
3129 /* Draw dashed rectangle showing margins */
3130 case WM_PSD_MARGINRECT
:
3131 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3132 holdpen
= SelectObject(hdc
, hpen
);
3133 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3134 DeleteObject(SelectObject(hdc
, holdpen
));
3136 /* Draw the fake document */
3137 case WM_PSD_GREEKTEXTRECT
:
3138 /* select a nice scalable font, because we want the text really small */
3139 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3140 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3141 hfont
= CreateFontIndirectW(&lf
);
3142 holdfont
= SelectObject(hdc
, hfont
);
3144 /* if text not loaded, then do so now */
3145 if (wszFakeDocumentText
[0] == '\0')
3146 LoadStringW(COMDLG32_hInstance
,
3148 wszFakeDocumentText
,
3149 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3151 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3152 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3153 SetBkMode(hdc
, oldbkmode
);
3155 DeleteObject(SelectObject(hdc
, holdfont
));
3158 /* Envelope stamp */
3159 case WM_PSD_ENVSTAMPRECT
:
3160 /* Return address */
3161 case WM_PSD_YAFULLPAGERECT
:
3162 FIXME("envelope/stamp is not implemented\n");
3165 FIXME("Unknown message %x\n",uMsg
);
3171 /***********************************************************************
3173 * The main paint procedure for the PageSetupDlg function.
3174 * The Page Setup dialog box includes an image of a sample page that shows how
3175 * the user's selections affect the appearance of the printed output.
3176 * The image consists of a rectangle that represents the selected paper
3177 * or envelope type, with a dotted-line rectangle representing
3178 * the current margins, and partial (Greek text) characters
3179 * to show how text looks on the printed page.
3181 * The following messages in the order sends to user hook procedure:
3182 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3183 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3184 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3185 * WM_PSD_MARGINRECT Draw the margin rectangle
3186 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3187 * If any of first three messages returns TRUE, painting done.
3190 * hWnd [in] Handle to the Page Setup dialog box
3191 * uMsg [in] Received message
3194 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3195 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3198 * FALSE if all done correctly
3203 static LRESULT CALLBACK
3204 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3207 RECT rcClient
, rcMargin
;
3210 HBRUSH hbrush
, holdbrush
;
3211 PageSetupDataA
*pda
;
3212 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3213 double scalx
, scaly
;
3214 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3216 if (uMsg
!= WM_PAINT
)
3217 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3219 /* Processing WM_PAINT message */
3220 pda
= GetPropW(hWnd
, pagesetupdlg_prop
);
3222 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3225 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3228 hdc
= BeginPaint(hWnd
, &ps
);
3229 GetClientRect(hWnd
, &rcClient
);
3231 scalx
= rcClient
.right
/ (double)pda
->curdlg
.ptPaperSize
.x
;
3232 scaly
= rcClient
.bottom
/ (double)pda
->curdlg
.ptPaperSize
.y
;
3233 rcMargin
= rcClient
;
3235 rcMargin
.left
+= pda
->curdlg
.rtMargin
.left
* scalx
;
3236 rcMargin
.top
+= pda
->curdlg
.rtMargin
.top
* scalx
;
3237 rcMargin
.right
-= pda
->curdlg
.rtMargin
.right
* scaly
;
3238 rcMargin
.bottom
-= pda
->curdlg
.rtMargin
.bottom
* scaly
;
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 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3245 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3247 /* fill background */
3248 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3249 FillRect(hdc
, &rcClient
, hbrush
);
3250 holdbrush
= SelectObject(hdc
, hbrush
);
3252 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3253 holdpen
= SelectObject(hdc
, hpen
);
3255 /* paint left edge */
3256 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3257 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3259 /* paint top edge */
3260 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3261 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3263 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3264 DeleteObject(SelectObject(hdc
, hpen
));
3266 /* paint right edge */
3267 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3268 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3270 /* paint bottom edge */
3271 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3272 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3274 DeleteObject(SelectObject(hdc
, holdpen
));
3275 DeleteObject(SelectObject(hdc
, holdbrush
));
3277 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3279 /* give text a bit of a space from the frame */
3282 rcMargin
.right
-= 2;
3283 rcMargin
.bottom
-= 2;
3285 /* if the space is too small then we make sure to not draw anything */
3286 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3287 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3289 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3292 EndPaint(hWnd
, &ps
);
3294 #undef CALLPAINTHOOK
3297 /***********************************************************************
3298 * PRINTDLG_PageDlgProcA
3299 * Message handler for PageSetupDlgA
3301 static INT_PTR CALLBACK
3302 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3305 PageSetupDataA
*pda
;
3306 INT_PTR res
= FALSE
;
3309 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3310 pda
= (PageSetupDataA
*)lParam
;
3311 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3312 pda
->curdlg
= *pda
->dlga
;
3314 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3315 TRACE("set property to %p\n", pda
);
3316 SetPropW(hDlg
, pagesetupdlg_prop
, pda
);
3317 SetPropW(hDrawWnd
, pagesetupdlg_prop
, pda
);
3318 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3319 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3320 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3321 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3324 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3326 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3328 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3329 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3330 FIXME("Setup page hook failed?\n");
3333 /* if printer button disabled */
3334 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3335 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3336 /* if margin edit boxes disabled */
3337 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3338 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3339 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3340 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3341 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3343 /* Set orientation radiobutton properly */
3344 if(pda
->dlga
->hDevMode
)
3346 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3347 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3348 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3349 else /* this is default if papersize is not set */
3350 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3351 GlobalUnlock(pda
->dlga
->hDevMode
);
3354 /* if orientation disabled */
3355 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3356 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3357 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3359 /* We fill them out enabled or not */
3360 if (pda
->dlga
->Flags
& PSD_MARGINS
) {
3362 _c_size2strA(pda
,pda
->dlga
->rtMargin
.left
,str
);
3363 SetDlgItemTextA(hDlg
,edt4
,str
);
3364 _c_size2strA(pda
,pda
->dlga
->rtMargin
.top
,str
);
3365 SetDlgItemTextA(hDlg
,edt5
,str
);
3366 _c_size2strA(pda
,pda
->dlga
->rtMargin
.right
,str
);
3367 SetDlgItemTextA(hDlg
,edt6
,str
);
3368 _c_size2strA(pda
,pda
->dlga
->rtMargin
.bottom
,str
);
3369 SetDlgItemTextA(hDlg
,edt7
,str
);
3371 /* default is 1 inch */
3372 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3374 _c_size2strA(pda
,size
,str
);
3375 SetDlgItemTextA(hDlg
,edt4
,str
);
3376 SetDlgItemTextA(hDlg
,edt5
,str
);
3377 SetDlgItemTextA(hDlg
,edt6
,str
);
3378 SetDlgItemTextA(hDlg
,edt7
,str
);
3379 pda
->curdlg
.rtMargin
.left
= size
;
3380 pda
->curdlg
.rtMargin
.top
= size
;
3381 pda
->curdlg
.rtMargin
.right
= size
;
3382 pda
->curdlg
.rtMargin
.bottom
= size
;
3384 /* if paper disabled */
3385 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3386 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3387 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3389 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3390 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3391 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
3393 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3394 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &pda
->curdlg
.ptPaperSize
);
3395 GlobalUnlock(pda
->pdlg
.hDevMode
);
3396 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3397 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3398 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3399 DWORD tmp
= pda
->curdlg
.ptPaperSize
.y
;
3400 pda
->curdlg
.ptPaperSize
.y
= pda
->curdlg
.ptPaperSize
.x
;
3401 pda
->curdlg
.ptPaperSize
.x
= tmp
;
3404 WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda
->pdlg
.hDevMode
);
3405 /* Drawing paper prev */
3406 PRINTDLG_PS_ChangePaperPrev(pda
);
3409 pda
= GetPropW(hDlg
, pagesetupdlg_prop
);
3411 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3414 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3415 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3416 if (res
) return res
;
3421 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3426 static INT_PTR CALLBACK
3427 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3429 PageSetupDataW
*pdw
;
3432 if (uMsg
==WM_INITDIALOG
) {
3434 pdw
= (PageSetupDataW
*)lParam
;
3435 pdw
->curdlg
= *pdw
->dlgw
;
3436 SetPropW(hDlg
, pagesetupdlg_prop
, pdw
);
3437 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3438 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3440 FIXME("Setup page hook failed?\n");
3445 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3446 FIXME("PagePaintHook not yet implemented!\n");
3448 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3449 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3450 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3451 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3452 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3453 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3454 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3457 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3459 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3460 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3461 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3463 /* We fill them out enabled or not */
3464 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3466 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3467 SetDlgItemTextW(hDlg
,edt4
,str
);
3468 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3469 SetDlgItemTextW(hDlg
,edt5
,str
);
3470 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3471 SetDlgItemTextW(hDlg
,edt6
,str
);
3472 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3473 SetDlgItemTextW(hDlg
,edt7
,str
);
3475 /* default is 1 inch */
3476 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3478 _c_size2strW(pdw
,size
,str
);
3479 SetDlgItemTextW(hDlg
,edt4
,str
);
3480 SetDlgItemTextW(hDlg
,edt5
,str
);
3481 SetDlgItemTextW(hDlg
,edt6
,str
);
3482 SetDlgItemTextW(hDlg
,edt7
,str
);
3485 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3486 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3487 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3492 pdw
= GetPropW(hDlg
, pagesetupdlg_prop
);
3494 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3497 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3498 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3499 if (res
) return res
;
3504 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3509 /***********************************************************************
3510 * PageSetupDlgA (COMDLG32.@)
3512 * Displays the PAGE SETUP dialog box, which enables the user to specify
3513 * specific properties of a printed page such as
3514 * size, source, orientation and the width of the page margins.
3517 * setupdlg [IO] PAGESETUPDLGA struct
3520 * TRUE if the user pressed the OK button
3521 * FALSE if the user cancelled the window or an error occurred
3524 * The values of hDevMode and hDevNames are filled on output and can be
3525 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3529 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3533 PageSetupDataA
*pda
;
3536 if (setupdlg
== NULL
) {
3537 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3542 if(TRACE_ON(commdlg
)) {
3543 char flagstr
[1000] = "";
3544 const struct pd_flags
*pflag
= psd_flags
;
3545 for( ; pflag
->name
; pflag
++) {
3546 if(setupdlg
->Flags
& pflag
->flag
) {
3547 strcat(flagstr
, pflag
->name
);
3548 strcat(flagstr
, "|");
3551 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3552 "hinst %p, flags %08x (%s)\n",
3553 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3554 setupdlg
->hDevNames
,
3555 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3558 /* Checking setupdlg structure */
3559 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3560 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3563 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3564 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3565 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3569 /* Initialize default printer struct. If no printer device info is specified
3570 retrieve the default printer data. */
3571 memset(&pdlg
,0,sizeof(pdlg
));
3572 pdlg
.lStructSize
= sizeof(pdlg
);
3573 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3574 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3575 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3577 pdlg
.Flags
= PD_RETURNDEFAULT
;
3578 bRet
= PrintDlgA(&pdlg
);
3580 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3582 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3583 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3589 /* short cut exit, just return default values */
3590 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3593 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3594 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3595 dm
= GlobalLock(pdlg
.hDevMode
);
3596 PRINTDLG_PaperSizeA(&pdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3597 GlobalUnlock(pdlg
.hDevMode
);
3598 setupdlg
->ptPaperSize
.x
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.x
);
3599 setupdlg
->ptPaperSize
.y
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.y
);
3603 /* get dialog template */
3604 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3606 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3609 ptr
= LockResource( hDlgTmpl
);
3611 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3615 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3616 pda
->dlga
= setupdlg
;
3619 bRet
= (0<DialogBoxIndirectParamA(
3620 setupdlg
->hInstance
,
3622 setupdlg
->hwndOwner
,
3623 PRINTDLG_PageDlgProcA
,
3627 HeapFree(GetProcessHeap(),0,pda
);
3630 /***********************************************************************
3631 * PageSetupDlgW (COMDLG32.@)
3633 * See PageSetupDlgA.
3635 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3639 PageSetupDataW
*pdw
;
3642 FIXME("Unicode implementation is not done yet\n");
3644 if (setupdlg
== NULL
) {
3645 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3649 if(TRACE_ON(commdlg
)) {
3650 char flagstr
[1000] = "";
3651 const struct pd_flags
*pflag
= psd_flags
;
3652 for( ; pflag
->name
; pflag
++) {
3653 if(setupdlg
->Flags
& pflag
->flag
) {
3654 strcat(flagstr
, pflag
->name
);
3655 strcat(flagstr
, "|");
3658 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3659 "hinst %p, flags %08x (%s)\n",
3660 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3661 setupdlg
->hDevNames
,
3662 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3665 /* Initialize default printer struct. If no printer device info is specified
3666 retrieve the default printer data. */
3667 memset(&pdlg
,0,sizeof(pdlg
));
3668 pdlg
.lStructSize
= sizeof(pdlg
);
3669 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3670 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3671 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3673 pdlg
.Flags
= PD_RETURNDEFAULT
;
3674 bRet
= PrintDlgW(&pdlg
);
3676 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3678 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3679 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3685 /* short cut exit, just return default values */
3686 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3687 static const WCHAR a4
[] = {'A','4',0};
3688 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3689 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3690 /* FIXME: Just return "A4" for now. */
3691 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3692 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3693 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3696 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3698 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3701 ptr
= LockResource( hDlgTmpl
);
3703 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3706 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3707 pdw
->dlgw
= setupdlg
;
3710 bRet
= (0<DialogBoxIndirectParamW(
3711 setupdlg
->hInstance
,
3713 setupdlg
->hwndOwner
,
3720 /***********************************************************************
3721 * PrintDlgExA (COMDLG32.@)
3729 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3732 FIXME("(%p) stub\n", lppd
);
3733 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3734 return E_INVALIDARG
;
3737 if (!IsWindow(lppd
->hwndOwner
)) {
3744 /***********************************************************************
3745 * PrintDlgExW (COMDLG32.@)
3747 * Display the property sheet style PRINT dialog box
3750 * lppd [IO] ptr to PRINTDLGEX struct
3754 * Failure: One of the following COM error codes:
3755 * E_OUTOFMEMORY Insufficient memory.
3756 * E_INVALIDARG One or more arguments are invalid.
3757 * E_POINTER Invalid pointer.
3758 * E_HANDLE Invalid handle.
3759 * E_FAIL Unspecified error.
3762 * This Dialog enables the user to specify specific properties of the print job.
3763 * The property sheet can also have additional application-specific and
3764 * driver-specific property pages.
3767 * Not fully implemented
3770 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3775 FIXME("(%p) not fully implemented\n", lppd
);
3777 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3778 return E_INVALIDARG
;
3781 if (!IsWindow(lppd
->hwndOwner
)) {
3785 if (lppd
->Flags
& PD_RETURNDEFAULT
) {
3786 PRINTER_INFO_2W
*pbuf
;
3787 DRIVER_INFO_2W
*dbuf
;
3789 DWORD needed
= 1024;
3792 if (lppd
->hDevMode
|| lppd
->hDevNames
) {
3793 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
3794 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3795 return E_INVALIDARG
;
3797 if (!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
3798 WARN("Can't find default printer\n");
3799 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
3803 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3804 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3805 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3806 HeapFree(GetProcessHeap(), 0, pbuf
);
3807 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3808 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3811 HeapFree(GetProcessHeap(), 0, pbuf
);
3817 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3818 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3819 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3820 HeapFree(GetProcessHeap(), 0, dbuf
);
3821 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3822 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3825 ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
3826 GetLastError(), debugstr_w(pbuf
->pPrinterName
));
3827 HeapFree(GetProcessHeap(), 0, dbuf
);
3828 HeapFree(GetProcessHeap(), 0, pbuf
);
3829 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3835 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
3839 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
3840 pbuf
->pDevMode
->dmDriverExtra
);
3841 if (lppd
->hDevMode
) {
3842 ptr
= GlobalLock(lppd
->hDevMode
);
3844 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
3845 pbuf
->pDevMode
->dmDriverExtra
);
3846 GlobalUnlock(lppd
->hDevMode
);
3850 HeapFree(GetProcessHeap(), 0, pbuf
);
3851 HeapFree(GetProcessHeap(), 0, dbuf
);