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 propW
[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
84 /***********************************************************************
85 * PRINTDLG_OpenDefaultPrinter
87 * Returns a winspool printer handle to the default printer in *hprn
88 * Caller must call ClosePrinter on the handle
90 * Returns TRUE on success else FALSE
92 BOOL
PRINTDLG_OpenDefaultPrinter(HANDLE
*hprn
)
95 DWORD dwBufLen
= sizeof(buf
) / sizeof(buf
[0]);
97 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
99 res
= OpenPrinterW(buf
, hprn
, NULL
);
101 WARN("Could not open printer %s\n", debugstr_w(buf
));
105 /***********************************************************************
106 * PRINTDLG_SetUpPrinterListCombo
108 * Initializes printer list combox.
109 * hDlg: HWND of dialog
110 * id: Control id of combo
111 * name: Name of printer to select
113 * Initializes combo with list of available printers. Selects printer 'name'
114 * If name is NULL or does not exist select the default printer.
116 * Returns number of printers added to list.
118 INT
PRINTDLG_SetUpPrinterListComboA(HWND hDlg
, UINT id
, LPCSTR name
)
122 LPPRINTER_INFO_2A pi
;
123 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
124 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
125 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
128 SendDlgItemMessageA(hDlg
, id
, CB_RESETCONTENT
, 0, 0);
130 for(i
= 0; i
< num
; i
++) {
131 SendDlgItemMessageA(hDlg
, id
, CB_ADDSTRING
, 0,
132 (LPARAM
)pi
[i
].pPrinterName
);
134 HeapFree(GetProcessHeap(), 0, pi
);
136 (i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
137 (LPARAM
)name
)) == CB_ERR
) {
140 DWORD dwBufLen
= sizeof(buf
);
142 WARN("Can't find %s in printer list so trying to find default\n",
144 if(!GetDefaultPrinterA(buf
, &dwBufLen
))
146 i
= SendDlgItemMessageA(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
148 FIXME("Can't find default printer in printer list\n");
150 SendDlgItemMessageA(hDlg
, id
, CB_SETCURSEL
, i
, 0);
154 static INT
PRINTDLG_SetUpPrinterListComboW(HWND hDlg
, UINT id
, LPCWSTR name
)
158 LPPRINTER_INFO_2W pi
;
159 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
160 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
161 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, (LPBYTE
)pi
, needed
, &needed
,
164 for(i
= 0; i
< num
; i
++) {
165 SendDlgItemMessageW(hDlg
, id
, CB_ADDSTRING
, 0,
166 (LPARAM
)pi
[i
].pPrinterName
);
168 HeapFree(GetProcessHeap(), 0, pi
);
170 (i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1,
171 (LPARAM
)name
)) == CB_ERR
) {
173 DWORD dwBufLen
= sizeof(buf
)/sizeof(buf
[0]);
175 WARN("Can't find %s in printer list so trying to find default\n",
177 if(!GetDefaultPrinterW(buf
, &dwBufLen
))
179 i
= SendDlgItemMessageW(hDlg
, id
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)buf
);
181 TRACE("Can't find default printer in printer list\n");
183 SendDlgItemMessageW(hDlg
, id
, CB_SETCURSEL
, i
, 0);
187 /***********************************************************************
188 * PRINTDLG_CreateDevNames [internal]
191 * creates a DevNames structure.
193 * (NB. when we handle unicode the offsets will be in wchars).
195 static BOOL
PRINTDLG_CreateDevNames(HGLOBAL
*hmem
, const char* DeviceDriverName
,
196 const char* DeviceName
, const char* OutputPort
)
199 char* pDevNamesSpace
;
201 LPDEVNAMES lpDevNames
;
203 DWORD dwBufLen
= sizeof(buf
);
205 size
= strlen(DeviceDriverName
) + 1
206 + strlen(DeviceName
) + 1
207 + strlen(OutputPort
) + 1
211 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
213 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
217 pDevNamesSpace
= GlobalLock(*hmem
);
218 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
220 pTempPtr
= pDevNamesSpace
+ sizeof(DEVNAMES
);
221 strcpy(pTempPtr
, DeviceDriverName
);
222 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
224 pTempPtr
+= strlen(DeviceDriverName
) + 1;
225 strcpy(pTempPtr
, DeviceName
);
226 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
228 pTempPtr
+= strlen(DeviceName
) + 1;
229 strcpy(pTempPtr
, OutputPort
);
230 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
232 GetDefaultPrinterA(buf
, &dwBufLen
);
233 lpDevNames
->wDefault
= (strcmp(buf
, DeviceName
) == 0) ? 1 : 0;
238 static BOOL
PRINTDLG_CreateDevNamesW(HGLOBAL
*hmem
, LPCWSTR DeviceDriverName
,
239 LPCWSTR DeviceName
, LPCWSTR OutputPort
)
242 LPWSTR pDevNamesSpace
;
244 LPDEVNAMES lpDevNames
;
246 DWORD dwBufLen
= sizeof(bufW
) / sizeof(WCHAR
);
248 size
= sizeof(WCHAR
)*lstrlenW(DeviceDriverName
) + 2
249 + sizeof(WCHAR
)*lstrlenW(DeviceName
) + 2
250 + sizeof(WCHAR
)*lstrlenW(OutputPort
) + 2
254 *hmem
= GlobalReAlloc(*hmem
, size
, GMEM_MOVEABLE
);
256 *hmem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
260 pDevNamesSpace
= GlobalLock(*hmem
);
261 lpDevNames
= (LPDEVNAMES
) pDevNamesSpace
;
263 pTempPtr
= (LPWSTR
)((LPDEVNAMES
)pDevNamesSpace
+ 1);
264 lstrcpyW(pTempPtr
, DeviceDriverName
);
265 lpDevNames
->wDriverOffset
= pTempPtr
- pDevNamesSpace
;
267 pTempPtr
+= lstrlenW(DeviceDriverName
) + 1;
268 lstrcpyW(pTempPtr
, DeviceName
);
269 lpDevNames
->wDeviceOffset
= pTempPtr
- pDevNamesSpace
;
271 pTempPtr
+= lstrlenW(DeviceName
) + 1;
272 lstrcpyW(pTempPtr
, OutputPort
);
273 lpDevNames
->wOutputOffset
= pTempPtr
- pDevNamesSpace
;
275 GetDefaultPrinterW(bufW
, &dwBufLen
);
276 lpDevNames
->wDefault
= (lstrcmpW(bufW
, DeviceName
) == 0) ? 1 : 0;
281 /***********************************************************************
282 * PRINTDLG_UpdatePrintDlg [internal]
285 * updates the PrintDlg structure for return values.
288 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
289 * TRUE if successful.
291 static BOOL
PRINTDLG_UpdatePrintDlgA(HWND hDlg
,
292 PRINT_PTRA
* PrintStructures
)
294 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
295 PDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
296 LPPRINTER_INFO_2A pi
= PrintStructures
->lpPrinterInfo
;
300 FIXME("No lpdm ptr?\n");
305 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
306 /* check whether nFromPage and nToPage are within range defined by
307 * nMinPage and nMaxPage
309 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
312 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
313 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
314 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
315 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
316 WCHAR resourcestr
[256];
317 WCHAR resultstr
[256];
318 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
, resourcestr
, 255);
319 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
320 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
, resourcestr
, 255);
321 MessageBoxW(hDlg
, resultstr
, resourcestr
, MB_OK
| MB_ICONWARNING
);
324 lppd
->nFromPage
= nFromPage
;
325 lppd
->nToPage
= nToPage
;
326 lppd
->Flags
|= PD_PAGENUMS
;
329 lppd
->Flags
&= ~PD_PAGENUMS
;
331 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
332 lppd
->Flags
|= PD_SELECTION
;
334 lppd
->Flags
&= ~PD_SELECTION
;
336 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
337 static char file
[] = "FILE:";
338 lppd
->Flags
|= PD_PRINTTOFILE
;
339 pi
->pPortName
= file
;
342 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
343 FIXME("Collate lppd not yet implemented as output\n");
346 /* set PD_Collate and nCopies */
347 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
348 /* The application doesn't support multiple copies or collate...
350 lppd
->Flags
&= ~PD_COLLATE
;
352 /* if the printer driver supports it... store info there
353 * otherwise no collate & multiple copies !
355 if (lpdm
->dmFields
& DM_COLLATE
)
357 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
358 if (lpdm
->dmFields
& DM_COPIES
)
359 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
361 /* Application is responsible for multiple copies */
362 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
363 lppd
->Flags
|= PD_COLLATE
;
365 lppd
->Flags
&= ~PD_COLLATE
;
366 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
367 /* multiple copies already included in the document. Driver must print only one copy */
368 lpdm
->u1
.s1
.dmCopies
= 1;
371 /* Print quality, PrintDlg16 */
372 if(GetDlgItem(hDlg
, cmb1
))
374 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
375 int Sel
= SendMessageA(hQuality
, CB_GETCURSEL
, 0, 0);
379 LONG dpi
= SendMessageA(hQuality
, CB_GETITEMDATA
, Sel
, 0);
380 lpdm
->dmFields
|= DM_PRINTQUALITY
| DM_YRESOLUTION
;
381 lpdm
->u1
.s1
.dmPrintQuality
= LOWORD(dpi
);
382 lpdm
->dmYResolution
= HIWORD(dpi
);
389 static BOOL
PRINTDLG_UpdatePrintDlgW(HWND hDlg
,
390 PRINT_PTRW
* PrintStructures
)
392 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
393 PDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
394 LPPRINTER_INFO_2W pi
= PrintStructures
->lpPrinterInfo
;
398 FIXME("No lpdm ptr?\n");
403 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
404 /* check whether nFromPage and nToPage are within range defined by
405 * nMinPage and nMaxPage
407 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
410 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
411 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
412 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
413 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
414 WCHAR resourcestr
[256];
415 WCHAR resultstr
[256];
416 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
418 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
419 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
421 MessageBoxW(hDlg
, resultstr
, resourcestr
,
422 MB_OK
| MB_ICONWARNING
);
425 lppd
->nFromPage
= nFromPage
;
426 lppd
->nToPage
= nToPage
;
427 lppd
->Flags
|= PD_PAGENUMS
;
430 lppd
->Flags
&= ~PD_PAGENUMS
;
432 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
433 lppd
->Flags
|= PD_SELECTION
;
435 lppd
->Flags
&= ~PD_SELECTION
;
437 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
438 static WCHAR file
[] = {'F','I','L','E',':',0};
439 lppd
->Flags
|= PD_PRINTTOFILE
;
440 pi
->pPortName
= file
;
443 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
444 FIXME("Collate lppd not yet implemented as output\n");
447 /* set PD_Collate and nCopies */
448 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
449 /* The application doesn't support multiple copies or collate...
451 lppd
->Flags
&= ~PD_COLLATE
;
453 /* if the printer driver supports it... store info there
454 * otherwise no collate & multiple copies !
456 if (lpdm
->dmFields
& DM_COLLATE
)
458 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
459 if (lpdm
->dmFields
& DM_COPIES
)
460 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
462 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
463 lppd
->Flags
|= PD_COLLATE
;
465 lppd
->Flags
&= ~PD_COLLATE
;
466 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
472 static BOOL
PRINTDLG_PaperSizeA(
473 PRINTDLGA
*pdlga
,const WORD PaperSize
,LPPOINT size
477 LPSTR devname
,portname
;
481 POINT
*points
= NULL
;
484 dn
= GlobalLock(pdlga
->hDevNames
);
485 dm
= GlobalLock(pdlga
->hDevMode
);
486 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
487 portname
= ((char*)dn
)+dn
->wOutputOffset
;
490 NrOfEntries
= DeviceCapabilitiesA(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
492 FIXME("No papernames found for %s/%s\n",devname
,portname
);
495 if (NrOfEntries
== -1) {
496 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
500 Words
= HeapAlloc(GetProcessHeap(),0,NrOfEntries
*sizeof(WORD
));
501 if (NrOfEntries
!= (ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERS
,(LPSTR
)Words
,dm
))) {
502 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
505 for (i
=0;i
<NrOfEntries
;i
++)
506 if (Words
[i
] == PaperSize
)
508 if (i
== NrOfEntries
) {
509 FIXME("Papersize %d not found in list?\n",PaperSize
);
512 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
513 if (NrOfEntries
!=(ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERSIZE
,(LPSTR
)points
,dm
))) {
514 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
517 /* this is _10ths_ of a millimeter */
522 GlobalUnlock(pdlga
->hDevNames
);
523 GlobalUnlock(pdlga
->hDevMode
);
524 HeapFree(GetProcessHeap(),0,Words
);
525 HeapFree(GetProcessHeap(),0,points
);
529 static BOOL
PRINTDLG_PaperSizeW(
530 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
534 LPWSTR devname
,portname
;
538 POINT
*points
= NULL
;
541 dn
= GlobalLock(pdlga
->hDevNames
);
542 dm
= GlobalLock(pdlga
->hDevMode
);
543 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
544 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
547 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
549 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
552 if (NrOfEntries
== -1) {
553 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
557 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
558 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
559 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
562 for (i
=0;i
<NrOfEntries
;i
++)
563 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
565 if (i
==NrOfEntries
) {
566 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
569 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
570 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
571 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
574 /* this is _10ths_ of a millimeter */
579 GlobalUnlock(pdlga
->hDevNames
);
580 GlobalUnlock(pdlga
->hDevMode
);
581 HeapFree(GetProcessHeap(),0,Names
);
582 HeapFree(GetProcessHeap(),0,points
);
587 /************************************************************************
588 * PRINTDLG_SetUpPaperComboBox
590 * Initialize either the papersize or inputslot combos of the Printer Setup
591 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
592 * We also try to re-select the old selection.
594 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
607 int fwCapability_Names
;
608 int fwCapability_Words
;
610 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
612 /* query the dialog box for the current selected value */
613 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
615 /* we enter here only if a different printer is selected after
616 * the Print Setup dialog is opened. The current settings are
617 * stored into the newly selected printer.
619 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
622 if (nIDComboBox
== cmb2
)
623 dm
->u1
.s1
.dmPaperSize
= oldWord
;
625 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
629 /* we enter here only when the Print setup dialog is initially
630 * opened. In this case the settings are restored from when
631 * the dialog was last closed.
634 if (nIDComboBox
== cmb2
)
635 oldWord
= dm
->u1
.s1
.dmPaperSize
;
637 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
641 if (nIDComboBox
== cmb2
) {
643 fwCapability_Names
= DC_PAPERNAMES
;
644 fwCapability_Words
= DC_PAPERS
;
648 fwCapability_Names
= DC_BINNAMES
;
649 fwCapability_Words
= DC_BINS
;
652 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
653 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
655 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
656 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
657 fwCapability_Names
, NULL
, dm
);
658 if (NrOfEntries
== 0)
659 WARN("no Name Entries found!\n");
660 else if (NrOfEntries
< 0)
663 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
665 ERR("Number of caps is different\n");
669 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
670 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
671 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
672 fwCapability_Names
, Names
, dm
);
673 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
674 fwCapability_Words
, (LPSTR
)Words
, dm
);
676 /* reset any current content in the combobox */
677 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
679 /* store new content */
680 for (i
= 0; i
< NrOfEntries
; i
++) {
681 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
682 (LPARAM
)(&Names
[i
*NamesSize
]) );
683 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
687 /* Look for old selection - can't do this is previous loop since
688 item order will change as more items are added */
690 for (i
= 0; i
< NrOfEntries
; i
++) {
691 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
697 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
699 HeapFree(GetProcessHeap(),0,Words
);
700 HeapFree(GetProcessHeap(),0,Names
);
704 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
706 const WCHAR
* PrinterName
,
707 const WCHAR
* PortName
,
717 int fwCapability_Names
;
718 int fwCapability_Words
;
720 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
722 /* query the dialog box for the current selected value */
723 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
725 /* we enter here only if a different printer is selected after
726 * the Print Setup dialog is opened. The current settings are
727 * stored into the newly selected printer.
729 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
732 if (nIDComboBox
== cmb2
)
733 dm
->u1
.s1
.dmPaperSize
= oldWord
;
735 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
739 /* we enter here only when the Print setup dialog is initially
740 * opened. In this case the settings are restored from when
741 * the dialog was last closed.
744 if (nIDComboBox
== cmb2
)
745 oldWord
= dm
->u1
.s1
.dmPaperSize
;
747 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
751 if (nIDComboBox
== cmb2
) {
753 fwCapability_Names
= DC_PAPERNAMES
;
754 fwCapability_Words
= DC_PAPERS
;
758 fwCapability_Names
= DC_BINNAMES
;
759 fwCapability_Words
= DC_BINS
;
762 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
763 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
765 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
766 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
767 fwCapability_Names
, NULL
, dm
);
768 if (NrOfEntries
== 0)
769 WARN("no Name Entries found!\n");
770 else if (NrOfEntries
< 0)
773 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
775 ERR("Number of caps is different\n");
779 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
780 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
781 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
782 fwCapability_Names
, Names
, dm
);
783 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
784 fwCapability_Words
, (LPWSTR
)Words
, dm
);
786 /* reset any current content in the combobox */
787 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
789 /* store new content */
790 for (i
= 0; i
< NrOfEntries
; i
++) {
791 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
792 (LPARAM
)(&Names
[i
*NamesSize
]) );
793 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
797 /* Look for old selection - can't do this is previous loop since
798 item order will change as more items are added */
800 for (i
= 0; i
< NrOfEntries
; i
++) {
801 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
807 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
809 HeapFree(GetProcessHeap(),0,Words
);
810 HeapFree(GetProcessHeap(),0,Names
);
815 /***********************************************************************
816 * PRINTDLG_UpdatePrinterInfoTexts [internal]
818 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
821 char ResourceString
[256];
827 /* add all status messages */
828 for (i
= 0; i
< 25; i
++) {
829 if (pi
->Status
& (1<<i
)) {
830 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
831 ResourceString
, 255);
832 strcat(StatusMsg
,ResourceString
);
836 /* FIXME: status==ready must only be appended if really so.
837 but how to detect? */
838 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
839 ResourceString
, 255);
840 strcat(StatusMsg
,ResourceString
);
841 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
843 /* set all other printer info texts */
844 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
846 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
847 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
849 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
850 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
854 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
856 WCHAR StatusMsg
[256];
857 WCHAR ResourceString
[256];
858 static const WCHAR emptyW
[] = {0};
864 /* add all status messages */
865 for (i
= 0; i
< 25; i
++) {
866 if (pi
->Status
& (1<<i
)) {
867 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
868 ResourceString
, 255);
869 lstrcatW(StatusMsg
,ResourceString
);
873 /* FIXME: status==ready must only be appended if really so.
874 but how to detect? */
875 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
876 ResourceString
, 255);
877 lstrcatW(StatusMsg
,ResourceString
);
878 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
880 /* set all other printer info texts */
881 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
882 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
883 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
885 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
886 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
890 /*******************************************************************
892 * PRINTDLG_ChangePrinter
895 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
896 PRINT_PTRA
*PrintStructures
)
898 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
899 LPDEVMODEA lpdm
= NULL
;
904 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
905 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
906 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
907 ERR("Can't open printer %s\n", name
);
910 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
911 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
912 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
914 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
915 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
916 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
918 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
923 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
925 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
926 PrintStructures
->lpDevMode
= NULL
;
928 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
930 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
933 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
934 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
936 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
937 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
938 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
939 /* Supplied devicemode matches current printer so try to use it */
940 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
941 DM_OUT_BUFFER
| DM_IN_BUFFER
);
944 GlobalUnlock(lppd
->hDevMode
);
946 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
948 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
949 /* Print range (All/Range/Selection) */
950 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
951 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
952 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
953 if (lppd
->Flags
& PD_NOSELECTION
)
954 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
956 if (lppd
->Flags
& PD_SELECTION
)
957 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
958 if (lppd
->Flags
& PD_NOPAGENUMS
) {
959 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
960 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
961 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
962 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
963 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
965 if (lppd
->Flags
& PD_PAGENUMS
)
966 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
971 * FIXME: The ico3 is not displayed for some reason. I don't know why.
973 if (lppd
->Flags
& PD_COLLATE
) {
974 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
975 (LPARAM
)PrintStructures
->hCollateIcon
);
976 CheckDlgButton(hDlg
, chx2
, 1);
978 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
979 (LPARAM
)PrintStructures
->hNoCollateIcon
);
980 CheckDlgButton(hDlg
, chx2
, 0);
983 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
984 /* if printer doesn't support it: no Collate */
985 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
986 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
987 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
994 if (lppd
->hDevMode
== 0)
995 copies
= lppd
->nCopies
;
997 copies
= lpdm
->u1
.s1
.dmCopies
;
998 if(copies
== 0) copies
= 1;
999 else if(copies
< 0) copies
= MAX_COPIES
;
1000 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1003 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1004 /* if printer doesn't support it: no nCopies */
1005 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1006 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1007 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1012 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1013 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1014 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1015 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1016 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1018 /* Fill print quality combo, PrintDlg16 */
1019 if(GetDlgItem(hDlg
, cmb1
))
1021 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1022 PrintStructures
->lpPrinterInfo
->pPortName
,
1023 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
1025 if(numResolutions
!= -1)
1027 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
1032 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
1033 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1036 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
1037 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1038 PrintStructures
->lpPrinterInfo
->pPortName
,
1039 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
1041 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1042 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1043 DeleteDC(hPrinterDC
);
1045 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1046 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1048 BOOL IsDefault
= FALSE
;
1051 if(Resolutions
[i
] == Resolutions
[i
+1])
1053 if(dpiX
== Resolutions
[i
])
1055 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1058 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1060 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1063 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1066 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1068 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1070 HeapFree(GetProcessHeap(), 0, Resolutions
);
1073 } else { /* PD_PRINTSETUP */
1074 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1076 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1077 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1078 PrintStructures
->lpPrinterInfo
->pPortName
,
1080 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1081 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1082 PrintStructures
->lpPrinterInfo
->pPortName
,
1084 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1085 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1086 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1087 PrintStructures
->hLandscapeIcon
));
1092 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1093 /* hide if PD_SHOWHELP not specified */
1094 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1099 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1100 PRINT_PTRW
*PrintStructures
)
1102 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1103 LPDEVMODEW lpdm
= NULL
;
1108 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1109 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1110 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1111 ERR("Can't open printer %s\n", debugstr_w(name
));
1114 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1115 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1116 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1118 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1119 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1120 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1122 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1127 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1129 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1130 PrintStructures
->lpDevMode
= NULL
;
1132 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1134 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1137 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1138 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1140 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1141 !lstrcmpW(lpdm
->dmDeviceName
,
1142 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1143 /* Supplied devicemode matches current printer so try to use it */
1144 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1145 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1148 GlobalUnlock(lppd
->hDevMode
);
1150 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1152 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1153 /* Print range (All/Range/Selection) */
1154 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1155 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1156 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1157 if (lppd
->Flags
& PD_NOSELECTION
)
1158 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1160 if (lppd
->Flags
& PD_SELECTION
)
1161 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1162 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1163 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1164 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1165 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1166 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1167 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1169 if (lppd
->Flags
& PD_PAGENUMS
)
1170 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1175 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1177 if (lppd
->Flags
& PD_COLLATE
) {
1178 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1179 (LPARAM
)PrintStructures
->hCollateIcon
);
1180 CheckDlgButton(hDlg
, chx2
, 1);
1182 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1183 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1184 CheckDlgButton(hDlg
, chx2
, 0);
1187 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1188 /* if printer doesn't support it: no Collate */
1189 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1190 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1191 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1198 if (lppd
->hDevMode
== 0)
1199 copies
= lppd
->nCopies
;
1201 copies
= lpdm
->u1
.s1
.dmCopies
;
1202 if(copies
== 0) copies
= 1;
1203 else if(copies
< 0) copies
= MAX_COPIES
;
1204 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1207 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1208 /* if printer doesn't support it: no nCopies */
1209 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1210 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1211 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1216 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1217 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1218 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1219 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1220 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1222 } else { /* PD_PRINTSETUP */
1223 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1225 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1226 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1227 PrintStructures
->lpPrinterInfo
->pPortName
,
1229 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1230 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1231 PrintStructures
->lpPrinterInfo
->pPortName
,
1233 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1234 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1235 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1236 PrintStructures
->hLandscapeIcon
));
1241 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1242 /* hide if PD_SHOWHELP not specified */
1243 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1248 /***********************************************************************
1249 * check_printer_setup [internal]
1251 static LRESULT
check_printer_setup(HWND hDlg
)
1254 WCHAR resourcestr
[256],resultstr
[256];
1256 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1259 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1265 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1266 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1267 MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1272 /***********************************************************************
1273 * PRINTDLG_WMInitDialog [internal]
1275 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1276 PRINT_PTRA
* PrintStructures
)
1278 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1282 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1284 /* load Collate ICONs */
1285 /* We load these with LoadImage because they are not a standard
1286 size and we don't want them rescaled */
1287 PrintStructures
->hCollateIcon
=
1288 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1289 PrintStructures
->hNoCollateIcon
=
1290 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1292 /* These can be done with LoadIcon */
1293 PrintStructures
->hPortraitIcon
=
1294 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1295 PrintStructures
->hLandscapeIcon
=
1296 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1298 /* display the collate/no_collate icon */
1299 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1300 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1302 if(PrintStructures
->hCollateIcon
== 0 ||
1303 PrintStructures
->hNoCollateIcon
== 0 ||
1304 PrintStructures
->hPortraitIcon
== 0 ||
1305 PrintStructures
->hLandscapeIcon
== 0) {
1306 ERR("no icon in resourcefile\n");
1307 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1308 EndDialog(hDlg
, FALSE
);
1312 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1313 * must be registered and the Help button must be shown.
1315 if (lppd
->Flags
& PD_SHOWHELP
) {
1316 if((PrintStructures
->HelpMessageID
=
1317 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1318 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1322 PrintStructures
->HelpMessageID
= 0;
1324 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1325 PrintStructures
->hwndUpDown
=
1326 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1327 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1328 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1329 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1330 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1333 /* FIXME: I allow more freedom than either Win95 or WinNT,
1334 * which do not agree to what errors should be thrown or not
1335 * in case nToPage or nFromPage is out-of-range.
1337 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1338 lppd
->nMaxPage
= lppd
->nMinPage
;
1339 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1340 lppd
->Flags
|= PD_NOPAGENUMS
;
1341 if (lppd
->nToPage
< lppd
->nMinPage
)
1342 lppd
->nToPage
= lppd
->nMinPage
;
1343 if (lppd
->nToPage
> lppd
->nMaxPage
)
1344 lppd
->nToPage
= lppd
->nMaxPage
;
1345 if (lppd
->nFromPage
< lppd
->nMinPage
)
1346 lppd
->nFromPage
= lppd
->nMinPage
;
1347 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1348 lppd
->nFromPage
= lppd
->nMaxPage
;
1350 /* if we have the combo box, fill it */
1351 if (GetDlgItem(hDlg
,comboID
)) {
1354 pdn
= GlobalLock(lppd
->hDevNames
);
1355 pdm
= GlobalLock(lppd
->hDevMode
);
1357 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1359 name
= (char*)pdm
->dmDeviceName
;
1360 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1361 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1362 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1364 /* Now find selected printer and update rest of dlg */
1365 name
= HeapAlloc(GetProcessHeap(),0,256);
1366 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1367 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1368 HeapFree(GetProcessHeap(),0,name
);
1370 /* else use default printer */
1372 DWORD dwBufLen
= sizeof(name
);
1373 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1376 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1378 FIXME("No default printer found, expect problems!\n");
1383 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1384 PRINT_PTRW
* PrintStructures
)
1386 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1390 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1392 /* load Collate ICONs */
1393 /* We load these with LoadImage because they are not a standard
1394 size and we don't want them rescaled */
1395 PrintStructures
->hCollateIcon
=
1396 LoadImageW(COMDLG32_hInstance
, pd32_collateW
, IMAGE_ICON
, 0, 0, 0);
1397 PrintStructures
->hNoCollateIcon
=
1398 LoadImageW(COMDLG32_hInstance
, pd32_nocollateW
, IMAGE_ICON
, 0, 0, 0);
1400 /* These can be done with LoadIcon */
1401 PrintStructures
->hPortraitIcon
=
1402 LoadIconW(COMDLG32_hInstance
, pd32_portraitW
);
1403 PrintStructures
->hLandscapeIcon
=
1404 LoadIconW(COMDLG32_hInstance
, pd32_landscapeW
);
1406 /* display the collate/no_collate icon */
1407 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1408 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1410 if(PrintStructures
->hCollateIcon
== 0 ||
1411 PrintStructures
->hNoCollateIcon
== 0 ||
1412 PrintStructures
->hPortraitIcon
== 0 ||
1413 PrintStructures
->hLandscapeIcon
== 0) {
1414 ERR("no icon in resourcefile\n");
1415 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1416 EndDialog(hDlg
, FALSE
);
1420 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1421 * must be registered and the Help button must be shown.
1423 if (lppd
->Flags
& PD_SHOWHELP
) {
1424 if((PrintStructures
->HelpMessageID
=
1425 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1426 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1430 PrintStructures
->HelpMessageID
= 0;
1432 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1433 PrintStructures
->hwndUpDown
=
1434 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1435 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1436 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1437 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1438 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1441 /* FIXME: I allow more freedom than either Win95 or WinNT,
1442 * which do not agree to what errors should be thrown or not
1443 * in case nToPage or nFromPage is out-of-range.
1445 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1446 lppd
->nMaxPage
= lppd
->nMinPage
;
1447 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1448 lppd
->Flags
|= PD_NOPAGENUMS
;
1449 if (lppd
->nToPage
< lppd
->nMinPage
)
1450 lppd
->nToPage
= lppd
->nMinPage
;
1451 if (lppd
->nToPage
> lppd
->nMaxPage
)
1452 lppd
->nToPage
= lppd
->nMaxPage
;
1453 if (lppd
->nFromPage
< lppd
->nMinPage
)
1454 lppd
->nFromPage
= lppd
->nMinPage
;
1455 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1456 lppd
->nFromPage
= lppd
->nMaxPage
;
1458 /* if we have the combo box, fill it */
1459 if (GetDlgItem(hDlg
,comboID
)) {
1462 pdn
= GlobalLock(lppd
->hDevNames
);
1463 pdm
= GlobalLock(lppd
->hDevMode
);
1465 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1467 name
= pdm
->dmDeviceName
;
1468 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1469 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1470 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1472 /* Now find selected printer and update rest of dlg */
1473 /* ansi is ok here */
1474 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1475 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1476 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1477 HeapFree(GetProcessHeap(),0,name
);
1479 /* else use default printer */
1481 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1482 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1485 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1487 FIXME("No default printer found, expect problems!\n");
1492 /***********************************************************************
1493 * PRINTDLG_WMCommand [internal]
1495 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1496 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1498 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1499 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1500 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1502 switch (LOWORD(wParam
)) {
1504 TRACE(" OK button was hit\n");
1505 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1506 FIXME("Update printdlg was not successful!\n");
1509 EndDialog(hDlg
, TRUE
);
1513 TRACE(" CANCEL button was hit\n");
1514 EndDialog(hDlg
, FALSE
);
1518 TRACE(" HELP button was hit\n");
1519 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1520 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1523 case chx2
: /* collate pages checkbox */
1524 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1525 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1526 (LPARAM
)PrintStructures
->hCollateIcon
);
1528 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1529 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1531 case edt1
: /* from page nr editbox */
1532 case edt2
: /* to page nr editbox */
1533 if (HIWORD(wParam
)==EN_CHANGE
) {
1536 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1537 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1538 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1539 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1544 if(HIWORD(wParam
) == EN_CHANGE
) {
1545 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1547 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1549 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1554 case psh1
: /* Print Setup */
1558 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1559 FIXME("The 32bit print dialog does not have this button!?\n");
1563 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1564 pdlg
.Flags
|= PD_PRINTSETUP
;
1565 pdlg
.hwndOwner
= HWND_16(hDlg
);
1566 if (!PrintDlg16(&pdlg
))
1571 case psh2
: /* Properties button */
1574 char PrinterName
[256];
1576 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1577 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1578 FIXME(" Call to OpenPrinter did not succeed!\n");
1581 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1582 PrintStructures
->lpDevMode
,
1583 PrintStructures
->lpDevMode
,
1584 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1585 ClosePrinter(hPrinter
);
1589 case rad1
: /* Paperorientation */
1590 if (lppd
->Flags
& PD_PRINTSETUP
)
1592 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1593 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1594 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1598 case rad2
: /* Paperorientation */
1599 if (lppd
->Flags
& PD_PRINTSETUP
)
1601 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1602 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1603 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1607 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1608 if (PrinterComboID
!= LOWORD(wParam
)) {
1612 case cmb4
: /* Printer combobox */
1613 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1614 char PrinterName
[256];
1615 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1616 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1620 case cmb2
: /* Papersize */
1622 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1624 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1630 case cmb3
: /* Bin */
1632 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1634 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1635 CB_GETITEMDATA
, Sel
,
1640 if(lppd
->Flags
& PD_PRINTSETUP
) {
1641 switch (LOWORD(wParam
)) {
1642 case rad1
: /* orientation */
1644 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1645 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1646 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1647 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1649 (LPARAM
)PrintStructures
->hPortraitIcon
);
1650 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1652 (LPARAM
)PrintStructures
->hPortraitIcon
);
1655 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1656 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1657 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1659 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1660 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1662 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1671 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1672 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1674 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1675 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1676 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1678 switch (LOWORD(wParam
)) {
1680 TRACE(" OK button was hit\n");
1681 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1682 FIXME("Update printdlg was not successful!\n");
1685 EndDialog(hDlg
, TRUE
);
1689 TRACE(" CANCEL button was hit\n");
1690 EndDialog(hDlg
, FALSE
);
1694 TRACE(" HELP button was hit\n");
1695 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1696 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1699 case chx2
: /* collate pages checkbox */
1700 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1701 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1702 (LPARAM
)PrintStructures
->hCollateIcon
);
1704 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1705 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1707 case edt1
: /* from page nr editbox */
1708 case edt2
: /* to page nr editbox */
1709 if (HIWORD(wParam
)==EN_CHANGE
) {
1712 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1713 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1714 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1715 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1720 if(HIWORD(wParam
) == EN_CHANGE
) {
1721 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1723 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1725 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1729 case psh1
: /* Print Setup */
1731 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1734 case psh2
: /* Properties button */
1737 WCHAR PrinterName
[256];
1739 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1740 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1741 FIXME(" Call to OpenPrinter did not succeed!\n");
1744 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1745 PrintStructures
->lpDevMode
,
1746 PrintStructures
->lpDevMode
,
1747 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1748 ClosePrinter(hPrinter
);
1752 case rad1
: /* Paperorientation */
1753 if (lppd
->Flags
& PD_PRINTSETUP
)
1755 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1756 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1757 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1761 case rad2
: /* Paperorientation */
1762 if (lppd
->Flags
& PD_PRINTSETUP
)
1764 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1765 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1766 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1770 case cmb1
: /* Printer Combobox in PRINT SETUP */
1772 case cmb4
: /* Printer combobox */
1773 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1774 WCHAR PrinterName
[256];
1775 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1776 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1780 case cmb2
: /* Papersize */
1782 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1784 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1790 case cmb3
: /* Bin */
1792 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1794 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1795 CB_GETITEMDATA
, Sel
,
1800 if(lppd
->Flags
& PD_PRINTSETUP
) {
1801 switch (LOWORD(wParam
)) {
1802 case rad1
: /* orientation */
1804 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1805 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1806 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1807 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1809 (LPARAM
)PrintStructures
->hPortraitIcon
);
1810 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1812 (LPARAM
)PrintStructures
->hPortraitIcon
);
1815 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1816 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1817 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1819 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1820 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1822 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1831 /***********************************************************************
1832 * PrintDlgProcA [internal]
1834 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1837 PRINT_PTRA
* PrintStructures
;
1838 INT_PTR res
= FALSE
;
1840 if (uMsg
!=WM_INITDIALOG
) {
1841 PrintStructures
= (PRINT_PTRA
*)GetPropA(hDlg
,"__WINE_PRINTDLGDATA");
1842 if (!PrintStructures
)
1845 PrintStructures
= (PRINT_PTRA
*) lParam
;
1846 SetPropA(hDlg
,"__WINE_PRINTDLGDATA",PrintStructures
);
1847 if(!check_printer_setup(hDlg
))
1849 EndDialog(hDlg
,FALSE
);
1852 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1854 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1855 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1856 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1861 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1862 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1869 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1872 DestroyIcon(PrintStructures
->hCollateIcon
);
1873 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1874 DestroyIcon(PrintStructures
->hPortraitIcon
);
1875 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1876 if(PrintStructures
->hwndUpDown
)
1877 DestroyWindow(PrintStructures
->hwndUpDown
);
1883 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1886 PRINT_PTRW
* PrintStructures
;
1887 INT_PTR res
= FALSE
;
1889 if (uMsg
!=WM_INITDIALOG
) {
1890 PrintStructures
= (PRINT_PTRW
*) GetPropW(hDlg
, propW
);
1891 if (!PrintStructures
)
1894 PrintStructures
= (PRINT_PTRW
*) lParam
;
1895 SetPropW(hDlg
, propW
, PrintStructures
);
1896 if(!check_printer_setup(hDlg
))
1898 EndDialog(hDlg
,FALSE
);
1901 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1903 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1904 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1908 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1909 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1915 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1918 DestroyIcon(PrintStructures
->hCollateIcon
);
1919 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1920 DestroyIcon(PrintStructures
->hPortraitIcon
);
1921 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1922 if(PrintStructures
->hwndUpDown
)
1923 DestroyWindow(PrintStructures
->hwndUpDown
);
1929 /************************************************************
1931 * PRINTDLG_GetDlgTemplate
1934 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1939 if (lppd
->Flags
& PD_PRINTSETUP
) {
1940 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1941 hDlgTmpl
= lppd
->hSetupTemplate
;
1942 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1943 hResInfo
= FindResourceA(lppd
->hInstance
,
1944 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1945 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1947 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1949 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1952 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1953 hDlgTmpl
= lppd
->hPrintTemplate
;
1954 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1955 hResInfo
= FindResourceA(lppd
->hInstance
,
1956 lppd
->lpPrintTemplateName
,
1958 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1960 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1962 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1968 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1972 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1973 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1975 if (lppd
->Flags
& PD_PRINTSETUP
) {
1976 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1977 hDlgTmpl
= lppd
->hSetupTemplate
;
1978 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1979 hResInfo
= FindResourceW(lppd
->hInstance
,
1980 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1981 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1983 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
1984 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1987 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1988 hDlgTmpl
= lppd
->hPrintTemplate
;
1989 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1990 hResInfo
= FindResourceW(lppd
->hInstance
,
1991 lppd
->lpPrintTemplateName
,
1993 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1995 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
1996 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2002 /***********************************************************************
2007 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
2009 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2010 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
2012 if(lppd
->Flags
& PD_RETURNDC
) {
2013 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
2014 (char*)pdn
+ pdn
->wDeviceOffset
,
2015 (char*)pdn
+ pdn
->wOutputOffset
,
2017 } else if(lppd
->Flags
& PD_RETURNIC
) {
2018 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
2019 (char*)pdn
+ pdn
->wDeviceOffset
,
2020 (char*)pdn
+ pdn
->wOutputOffset
,
2023 GlobalUnlock(lppd
->hDevNames
);
2024 GlobalUnlock(lppd
->hDevMode
);
2025 return lppd
->hDC
? TRUE
: FALSE
;
2028 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
2030 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2031 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
2033 if(lppd
->Flags
& PD_RETURNDC
) {
2034 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2035 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2036 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2038 } else if(lppd
->Flags
& PD_RETURNIC
) {
2039 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2040 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2041 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2044 GlobalUnlock(lppd
->hDevNames
);
2045 GlobalUnlock(lppd
->hDevMode
);
2046 return lppd
->hDC
? TRUE
: FALSE
;
2049 /***********************************************************************
2050 * PrintDlgA (COMDLG32.@)
2052 * Displays the PRINT dialog box, which enables the user to specify
2053 * specific properties of the print job.
2056 * lppd [IO] ptr to PRINTDLG32 struct
2059 * nonzero if the user pressed the OK button
2060 * zero if the user cancelled the window or an error occurred
2064 * * The Collate Icons do not display, even though they are in the code.
2065 * * The Properties Button(s) should call DocumentPropertiesA().
2068 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2076 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2080 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2081 if(TRACE_ON(commdlg
)) {
2082 char flagstr
[1000] = "";
2083 const struct pd_flags
*pflag
= pd_flags
;
2084 for( ; pflag
->name
; pflag
++) {
2085 if(lppd
->Flags
& pflag
->flag
)
2086 strcat(flagstr
, pflag
->name
);
2088 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2089 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2090 "flags %08x (%s)\n",
2091 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2092 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2093 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2096 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2097 WARN("structure size failure !!!\n");
2098 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2102 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2103 PRINTER_INFO_2A
*pbuf
;
2104 DRIVER_INFO_3A
*dbuf
;
2108 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2109 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2110 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2113 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2114 WARN("Can't find default printer\n");
2115 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2119 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2120 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2121 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2123 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2124 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2125 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2126 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2127 GetLastError(),pbuf
->pPrinterName
);
2128 HeapFree(GetProcessHeap(), 0, dbuf
);
2129 HeapFree(GetProcessHeap(), 0, pbuf
);
2130 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2135 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2139 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2140 pbuf
->pDevMode
->dmDriverExtra
);
2141 ptr
= GlobalLock(lppd
->hDevMode
);
2142 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2143 pbuf
->pDevMode
->dmDriverExtra
);
2144 GlobalUnlock(lppd
->hDevMode
);
2145 HeapFree(GetProcessHeap(), 0, pbuf
);
2146 HeapFree(GetProcessHeap(), 0, dbuf
);
2150 PRINT_PTRA
*PrintStructures
;
2152 /* load Dialog resources,
2153 * depending on Flags indicates Print32 or Print32_setup dialog
2155 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2157 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2160 ptr
= LockResource( hDlgTmpl
);
2162 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2166 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2167 sizeof(PRINT_PTRA
));
2168 PrintStructures
->lpPrintDlg
= lppd
;
2170 /* and create & process the dialog .
2171 * -1 is failure, 0 is broken hwnd, everything else is ok.
2173 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2175 (LPARAM
)PrintStructures
));
2178 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2179 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2180 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2182 if (lppd
->hDevMode
== 0) {
2183 TRACE(" No hDevMode yet... Need to create my own\n");
2184 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2185 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2187 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2188 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2191 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2192 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2194 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2199 GlobalUnlock(lppd
->hDevMode
);
2201 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2202 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2203 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2204 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2206 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2207 bRet
= PRINTDLG_CreateDCA(lppd
);
2209 TRACE("exit! (%d)\n", bRet
);
2213 /***********************************************************************
2214 * PrintDlgW (COMDLG32.@)
2218 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2226 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2230 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2231 if(TRACE_ON(commdlg
)) {
2232 char flagstr
[1000] = "";
2233 const struct pd_flags
*pflag
= pd_flags
;
2234 for( ; pflag
->name
; pflag
++) {
2235 if(lppd
->Flags
& pflag
->flag
)
2236 strcat(flagstr
, pflag
->name
);
2238 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2239 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2240 "flags %08x (%s)\n",
2241 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2242 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2243 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2246 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2247 WARN("structure size failure !!!\n");
2248 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2252 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2253 PRINTER_INFO_2W
*pbuf
;
2254 DRIVER_INFO_3W
*dbuf
;
2258 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2259 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2260 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2263 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2264 WARN("Can't find default printer\n");
2265 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2269 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2270 pbuf
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*needed
);
2271 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2273 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2274 dbuf
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
2275 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2276 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2277 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2278 HeapFree(GetProcessHeap(), 0, dbuf
);
2279 HeapFree(GetProcessHeap(), 0, pbuf
);
2280 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2285 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2289 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2290 pbuf
->pDevMode
->dmDriverExtra
);
2291 ptr
= GlobalLock(lppd
->hDevMode
);
2292 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2293 pbuf
->pDevMode
->dmDriverExtra
);
2294 GlobalUnlock(lppd
->hDevMode
);
2295 HeapFree(GetProcessHeap(), 0, pbuf
);
2296 HeapFree(GetProcessHeap(), 0, dbuf
);
2300 PRINT_PTRW
*PrintStructures
;
2302 /* load Dialog resources,
2303 * depending on Flags indicates Print32 or Print32_setup dialog
2305 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2307 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2310 ptr
= LockResource( hDlgTmpl
);
2312 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2316 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2317 sizeof(PRINT_PTRW
));
2318 PrintStructures
->lpPrintDlg
= lppd
;
2320 /* and create & process the dialog .
2321 * -1 is failure, 0 is broken hwnd, everything else is ok.
2323 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2325 (LPARAM
)PrintStructures
));
2328 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2329 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2330 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2332 if (lppd
->hDevMode
== 0) {
2333 TRACE(" No hDevMode yet... Need to create my own\n");
2334 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2335 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2338 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2339 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2341 GlobalUnlock(lppd
->hDevMode
);
2342 TRACE("Now got %d locks\n", locks
);
2345 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2346 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2349 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2350 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2352 if (lppd
->hDevNames
!= 0) {
2354 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2355 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2357 GlobalUnlock(lppd
->hDevNames
);
2360 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2365 GlobalUnlock(lppd
->hDevMode
);
2367 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2368 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2369 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2370 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2372 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2373 bRet
= PRINTDLG_CreateDCW(lppd
);
2375 TRACE("exit! (%d)\n", bRet
);
2379 /***********************************************************************
2384 * cmb1 - printer select (not in standard dialog template)
2386 * cmb3 - source (tray?)
2387 * edt4 - border left
2389 * edt6 - border right
2390 * edt7 - border bottom
2391 * psh3 - "Printer..."
2395 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2397 HWND hDlg
; /* Page Setup dialog handler */
2398 PAGESETUPDLGA curdlg
; /* Stores the current dialog state */
2399 RECT rtDrawRect
; /* Drawing rect for page */
2403 LPPAGESETUPDLGW dlgw
;
2405 PAGESETUPDLGW curdlg
; /* Current dialog state */
2409 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2414 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2415 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2416 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2417 hResInfo
= FindResourceA(lppd
->hInstance
,
2418 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2419 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2421 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2422 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2427 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2432 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2433 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2434 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2435 hResInfo
= FindResourceW(lppd
->hInstance
,
2436 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2437 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2439 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2440 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2446 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2447 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2448 return 10*size
*100/254;
2449 /* If we don't have a flag, we can choose one. Use millimeters
2450 * to avoid confusing me
2452 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2458 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2459 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2461 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2462 return (size
*254)/100;
2463 /* if we don't have a flag, we can choose one. Use millimeters
2464 * to avoid confusing me
2466 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2467 return (size
*254)/100;
2471 _c_size2strA(PageSetupDataA
*pda
,DWORD size
,LPSTR strout
) {
2472 strcpy(strout
,"<undef>");
2473 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2474 sprintf(strout
,"%d",(size
)/100);
2477 if (pda
->dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2478 sprintf(strout
,"%din",(size
)/1000);
2481 pda
->dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2482 sprintf(strout
,"%d",(size
)/100);
2486 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2487 static const char mm_fmt
[] = "%.2f mm";
2488 static const char in_fmt
[] = "%.2f in";
2490 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2491 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2492 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2493 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2495 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2496 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2499 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2503 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2508 if (!sscanf(strin
,"%f%s",&val
,rest
))
2511 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2512 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2515 return val
*25.4*100;
2517 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2518 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2520 if (!strcmp(rest
,"mm")) {
2521 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2524 return 1000.0*val
/25.4;
2526 if (rest
[0]=='\0') {
2527 /* use application supplied default */
2528 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2532 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2537 ERR("Did not find a conversion for type '%s'!\n",rest
);
2543 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2546 /* this W -> A transition is OK */
2547 /* we need a unicode version of sscanf to avoid it */
2548 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2549 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2553 /****************************************************************************
2554 * PRINTDLG_PS_UpdateDlgStructA
2556 * Updates pda->dlga structure
2557 * Function calls when user presses OK button
2560 * hDlg [in] main window dialog HANDLE
2561 * pda [in/out] ptr to PageSetupDataA structure
2567 PRINTDLG_PS_UpdateDlgStructA(HWND hDlg
, PageSetupDataA
*pda
) {
2571 memcpy(pda
->dlga
, &pda
->curdlg
, sizeof(pda
->curdlg
));
2572 pda
->dlga
->hDevMode
= pda
->pdlg
.hDevMode
;
2573 pda
->dlga
->hDevNames
= pda
->pdlg
.hDevNames
;
2575 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2577 /* Save paper orientation into device context */
2578 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
)
2579 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2581 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2583 /* Save paper size into the device context */
2584 paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2585 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2586 if (paperword
!= CB_ERR
)
2587 dm
->u1
.s1
.dmPaperSize
= paperword
;
2589 FIXME("could not get dialog text for papersize cmbbox?\n");
2591 /* Save paper source into the device context */
2592 paperword
= SendDlgItemMessageA(hDlg
,cmb1
,CB_GETITEMDATA
,
2593 SendDlgItemMessageA(hDlg
, cmb1
, CB_GETCURSEL
, 0, 0), 0);
2594 if (paperword
!= CB_ERR
)
2595 dm
->u1
.s1
.dmDefaultSource
= paperword
;
2597 FIXME("could not get dialog text for papersize cmbbox?\n");
2599 GlobalUnlock(pda
->pdlg
.hDevMode
);
2605 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2608 LPWSTR devname
,portname
;
2609 WCHAR papername
[64];
2612 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2613 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2614 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2615 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2617 /* Save paper size into device context */
2618 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2619 /* Save paper source into device context */
2620 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2622 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2623 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2624 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2625 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2627 FIXME("could not get dialog text for papersize cmbbox?\n");
2628 #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); }
2629 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2630 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2631 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2632 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2635 /* If we are in landscape, swap x and y of page size */
2636 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2638 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2639 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2640 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2643 /* Save orientation */
2644 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2645 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2647 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2649 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2650 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2654 /**********************************************************************************************
2655 * PRINTDLG_PS_ChangeActivePrinerA
2657 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2660 * name [in] Name of a printer for activation
2661 * pda [in/out] ptr to PageSetupDataA structure
2668 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2671 LPPRINTER_INFO_2A lpPrinterInfo
;
2672 LPDRIVER_INFO_3A lpDriverInfo
;
2673 DEVMODEA
*pDevMode
, *dm
;
2675 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2676 ERR("Can't open printer %s\n", name
);
2679 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2680 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2681 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2682 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2683 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2684 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2685 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2686 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2687 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2692 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2694 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2695 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2696 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2699 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2700 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2702 pda
->pdlg
.hDevMode
= GlobalReAlloc(pda
->pdlg
.hDevMode
,
2703 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2705 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2706 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2708 PRINTDLG_CreateDevNames(&(pda
->pdlg
.hDevNames
),
2709 lpDriverInfo
->pDriverPath
,
2710 lpPrinterInfo
->pPrinterName
,
2711 lpPrinterInfo
->pPortName
);
2713 GlobalUnlock(pda
->pdlg
.hDevMode
);
2714 HeapFree(GetProcessHeap(), 0, pDevMode
);
2715 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2716 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2720 /****************************************************************************************
2721 * PRINTDLG_PS_ChangePrinterA
2723 * Fills Printers, Paper and Source combo
2729 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2732 LPSTR devname
,portname
;
2734 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2735 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2736 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2737 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2738 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2739 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2740 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2741 GlobalUnlock(pda
->pdlg
.hDevNames
);
2742 GlobalUnlock(pda
->pdlg
.hDevMode
);
2746 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2748 WCHAR PaperName
[64];
2750 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2751 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2752 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2753 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2755 if(IsDlgButtonChecked(hDlg
, rad2
))
2757 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2758 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2759 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2763 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2768 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2773 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2774 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2776 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2778 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2781 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2783 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2787 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2790 LPWSTR devname
,portname
;
2792 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2793 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2794 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2795 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2796 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2797 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2799 /* Landscape orientation */
2800 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2801 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2802 else /* this is default if papersize is not set */
2803 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2805 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2806 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2808 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2813 /******************************************************************************************
2814 * PRINTDLG_PS_ChangePaperPrev
2816 * Changes paper preview size / position
2819 * pda [i] Pointer for current PageSetupDataA structure
2825 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2827 LONG width
, height
, x
, y
;
2830 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) {
2831 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2832 height
= pda
->curdlg
.ptPaperSize
.y
* width
/ pda
->curdlg
.ptPaperSize
.x
;
2834 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2835 width
= pda
->curdlg
.ptPaperSize
.x
* height
/ pda
->curdlg
.ptPaperSize
.y
;
2837 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2838 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2839 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2840 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2841 x
, y
, width
, height
);
2844 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2845 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2846 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2847 rtTmp
= pda
->rtDrawRect
;
2848 rtTmp
.right
+= SHADOW
;
2849 rtTmp
.bottom
+= SHADOW
;
2852 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2856 #define GETVAL(idc,val) \
2857 if(msg == EN_CHANGE){ \
2858 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2859 val = _c_str2sizeA(pda->dlga,buf); \
2861 FIXME("could not get dlgitemtexta for %x\n",id); \
2864 /********************************************************************************
2865 * PRINTDLG_PS_WMCommandA
2866 * process WM_COMMAND message for PageSetupDlgA
2869 * hDlg [in] Main dialog HANDLE
2870 * wParam [in] WM_COMMAND wParam
2871 * lParam [in] WM_COMMAND lParam
2872 * pda [in/out] ptr to PageSetupDataA
2876 PRINTDLG_PS_WMCommandA(
2877 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2879 WORD msg
= HIWORD(wParam
);
2880 WORD id
= LOWORD(wParam
);
2883 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2884 LOWORD(lParam
),wParam
,lParam
);
2887 if (!PRINTDLG_PS_UpdateDlgStructA(hDlg
, pda
))
2889 EndDialog(hDlg
, TRUE
);
2893 EndDialog(hDlg
, FALSE
);
2897 pda
->pdlg
.Flags
= 0;
2898 pda
->pdlg
.hwndOwner
= hDlg
;
2899 if (PrintDlgA(&(pda
->pdlg
)))
2900 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2905 if((id
== rad1
&& pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) ||
2906 (id
== rad2
&& pda
->curdlg
.ptPaperSize
.y
> pda
->curdlg
.ptPaperSize
.x
))
2910 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2912 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2913 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2915 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2916 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2917 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2918 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2920 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2921 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2922 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2923 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2925 PRINTDLG_PS_ChangePaperPrev(pda
);
2928 case cmb1
: /* Printer combo */
2929 if(msg
== CBN_SELCHANGE
){
2930 char crPrinterName
[256];
2931 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2932 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2933 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2936 case cmb2
: /* Paper combo */
2937 if(msg
== CBN_SELCHANGE
){
2938 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2939 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2940 if (paperword
!= CB_ERR
) {
2941 PRINTDLG_PaperSizeA(&(pda
->pdlg
), paperword
,&(pda
->curdlg
.ptPaperSize
));
2942 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.x
);
2943 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.y
);
2945 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2946 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2947 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2948 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2950 PRINTDLG_PS_ChangePaperPrev(pda
);
2952 FIXME("could not get dialog text for papersize cmbbox?\n");
2956 if(msg
== CBN_SELCHANGE
){
2957 DEVMODEA
*dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2958 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2959 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2960 GlobalUnlock(pda
->pdlg
.hDevMode
);
2963 case psh2
: /* Printer Properties button */
2966 char PrinterName
[256];
2971 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2972 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2973 FIXME("Call to OpenPrinter did not succeed!\n");
2976 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2977 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2978 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2979 ClosePrinter(hPrinter
);
2980 /* Changing paper */
2981 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &(pda
->curdlg
.ptPaperSize
));
2982 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
2983 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
2984 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
2985 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2986 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2987 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2988 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2991 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2992 /* Changing paper preview */
2993 PRINTDLG_PS_ChangePaperPrev(pda
);
2994 /* Selecting paper in combo */
2995 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
2996 if(count
!= CB_ERR
){
2997 for(i
=0; i
<count
; ++i
){
2998 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
2999 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
3005 GlobalUnlock(pda
->pdlg
.hDevMode
);
3009 GETVAL(id
, pda
->curdlg
.rtMargin
.left
);
3012 GETVAL(id
, pda
->curdlg
.rtMargin
.top
);
3015 GETVAL(id
, pda
->curdlg
.rtMargin
.right
);
3018 GETVAL(id
, pda
->curdlg
.rtMargin
.bottom
);
3021 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3027 PRINTDLG_PS_WMCommandW(
3028 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3030 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3031 LOWORD(lParam
),wParam
,lParam
);
3032 switch (LOWORD(wParam
)) {
3034 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3036 EndDialog(hDlg
, TRUE
);
3040 EndDialog(hDlg
, FALSE
);
3045 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3046 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3050 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3052 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3053 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3055 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3056 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3057 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3058 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3060 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3061 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3062 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3063 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3068 pdw
->pdlg
.Flags
= 0;
3069 pdw
->pdlg
.hwndOwner
= hDlg
;
3070 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3071 if (PrintDlgW(&(pdw
->pdlg
)))
3072 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3080 /***********************************************************************
3081 * DefaultPagePaintHook
3082 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3083 * whenever the sample page is redrawn.
3087 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3088 const PageSetupDataA
*pda
)
3090 LPRECT lprc
= (LPRECT
) lParam
;
3091 HDC hdc
= (HDC
) wParam
;
3094 HFONT hfont
, holdfont
;
3096 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3097 /* Call user paint hook if enable */
3098 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3099 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3103 /* LPPAGESETUPDLG in lParam */
3104 case WM_PSD_PAGESETUPDLG
:
3105 /* Inform about the sample page rectangle */
3106 case WM_PSD_FULLPAGERECT
:
3107 /* Inform about the margin rectangle */
3108 case WM_PSD_MINMARGINRECT
:
3111 /* Draw dashed rectangle showing margins */
3112 case WM_PSD_MARGINRECT
:
3113 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3114 holdpen
= SelectObject(hdc
, hpen
);
3115 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3116 DeleteObject(SelectObject(hdc
, holdpen
));
3118 /* Draw the fake document */
3119 case WM_PSD_GREEKTEXTRECT
:
3120 /* select a nice scalable font, because we want the text really small */
3121 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3122 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3123 hfont
= CreateFontIndirectW(&lf
);
3124 holdfont
= SelectObject(hdc
, hfont
);
3126 /* if text not loaded, then do so now */
3127 if (wszFakeDocumentText
[0] == '\0')
3128 LoadStringW(COMDLG32_hInstance
,
3130 wszFakeDocumentText
,
3131 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3133 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3134 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3135 SetBkMode(hdc
, oldbkmode
);
3137 DeleteObject(SelectObject(hdc
, holdfont
));
3140 /* Envelope stamp */
3141 case WM_PSD_ENVSTAMPRECT
:
3142 /* Return address */
3143 case WM_PSD_YAFULLPAGERECT
:
3144 FIXME("envelope/stamp is not implemented\n");
3147 FIXME("Unknown message %x\n",uMsg
);
3153 /***********************************************************************
3155 * The main paint procedure for the PageSetupDlg function.
3156 * The Page Setup dialog box includes an image of a sample page that shows how
3157 * the user's selections affect the appearance of the printed output.
3158 * The image consists of a rectangle that represents the selected paper
3159 * or envelope type, with a dotted-line rectangle representing
3160 * the current margins, and partial (Greek text) characters
3161 * to show how text looks on the printed page.
3163 * The following messages in the order sends to user hook procedure:
3164 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3165 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3166 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3167 * WM_PSD_MARGINRECT Draw the margin rectangle
3168 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3169 * If any of first three messages returns TRUE, painting done.
3172 * hWnd [in] Handle to the Page Setup dialog box
3173 * uMsg [in] Received message
3176 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3177 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3180 * FALSE if all done correctly
3185 static LRESULT CALLBACK
3186 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3189 RECT rcClient
, rcMargin
;
3192 HBRUSH hbrush
, holdbrush
;
3193 PageSetupDataA
*pda
;
3194 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3195 double scalx
, scaly
;
3196 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3198 if (uMsg
!= WM_PAINT
)
3199 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3201 /* Processing WM_PAINT message */
3202 pda
= (PageSetupDataA
*)GetPropA(hWnd
, "__WINE_PAGESETUPDLGDATA");
3204 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3207 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3210 hdc
= BeginPaint(hWnd
, &ps
);
3211 GetClientRect(hWnd
, &rcClient
);
3213 scalx
= rcClient
.right
/ (double)pda
->curdlg
.ptPaperSize
.x
;
3214 scaly
= rcClient
.bottom
/ (double)pda
->curdlg
.ptPaperSize
.y
;
3215 rcMargin
= rcClient
;
3217 rcMargin
.left
+= pda
->curdlg
.rtMargin
.left
* scalx
;
3218 rcMargin
.top
+= pda
->curdlg
.rtMargin
.top
* scalx
;
3219 rcMargin
.right
-= pda
->curdlg
.rtMargin
.right
* scaly
;
3220 rcMargin
.bottom
-= pda
->curdlg
.rtMargin
.bottom
* scaly
;
3222 /* if the space is too small then we make sure to not draw anything */
3223 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3224 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3226 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3227 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3229 /* fill background */
3230 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3231 FillRect(hdc
, &rcClient
, hbrush
);
3232 holdbrush
= SelectObject(hdc
, hbrush
);
3234 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3235 holdpen
= SelectObject(hdc
, hpen
);
3237 /* paint left edge */
3238 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3239 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3241 /* paint top edge */
3242 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3243 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3245 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3246 DeleteObject(SelectObject(hdc
, hpen
));
3248 /* paint right edge */
3249 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3250 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3252 /* paint bottom edge */
3253 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3254 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3256 DeleteObject(SelectObject(hdc
, holdpen
));
3257 DeleteObject(SelectObject(hdc
, holdbrush
));
3259 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3261 /* give text a bit of a space from the frame */
3264 rcMargin
.right
-= 2;
3265 rcMargin
.bottom
-= 2;
3267 /* if the space is too small then we make sure to not draw anything */
3268 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3269 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3271 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3274 EndPaint(hWnd
, &ps
);
3276 #undef CALLPAINTHOOK
3279 /***********************************************************************
3280 * PRINTDLG_PageDlgProcA
3281 * Message handler for PageSetupDlgA
3283 static INT_PTR CALLBACK
3284 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3287 PageSetupDataA
*pda
;
3288 INT_PTR res
= FALSE
;
3291 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3292 pda
= (PageSetupDataA
*)lParam
;
3293 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3294 pda
->curdlg
= *pda
->dlga
;
3296 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3297 TRACE("set property to %p\n", pda
);
3298 SetPropA(hDlg
, "__WINE_PAGESETUPDLGDATA", pda
);
3299 SetPropA(hDrawWnd
, "__WINE_PAGESETUPDLGDATA", pda
);
3300 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3301 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3302 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3303 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3306 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3308 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3310 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3311 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3312 FIXME("Setup page hook failed?\n");
3315 /* if printer button disabled */
3316 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3317 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3318 /* if margin edit boxes disabled */
3319 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3320 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3321 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3322 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3323 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3325 /* Set orientation radiobutton properly */
3326 if(pda
->dlga
->hDevMode
)
3328 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3329 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3330 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3331 else /* this is default if papersize is not set */
3332 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3333 GlobalUnlock(pda
->dlga
->hDevMode
);
3336 /* if orientation disabled */
3337 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3338 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3339 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3341 /* We fill them out enabled or not */
3342 if (pda
->dlga
->Flags
& PSD_MARGINS
) {
3344 _c_size2strA(pda
,pda
->dlga
->rtMargin
.left
,str
);
3345 SetDlgItemTextA(hDlg
,edt4
,str
);
3346 _c_size2strA(pda
,pda
->dlga
->rtMargin
.top
,str
);
3347 SetDlgItemTextA(hDlg
,edt5
,str
);
3348 _c_size2strA(pda
,pda
->dlga
->rtMargin
.right
,str
);
3349 SetDlgItemTextA(hDlg
,edt6
,str
);
3350 _c_size2strA(pda
,pda
->dlga
->rtMargin
.bottom
,str
);
3351 SetDlgItemTextA(hDlg
,edt7
,str
);
3353 /* default is 1 inch */
3354 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3356 _c_size2strA(pda
,size
,str
);
3357 SetDlgItemTextA(hDlg
,edt4
,str
);
3358 SetDlgItemTextA(hDlg
,edt5
,str
);
3359 SetDlgItemTextA(hDlg
,edt6
,str
);
3360 SetDlgItemTextA(hDlg
,edt7
,str
);
3361 pda
->curdlg
.rtMargin
.left
= size
;
3362 pda
->curdlg
.rtMargin
.top
= size
;
3363 pda
->curdlg
.rtMargin
.right
= size
;
3364 pda
->curdlg
.rtMargin
.bottom
= size
;
3366 /* if paper disabled */
3367 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3368 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3369 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3371 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3372 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3373 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
3375 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3376 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &pda
->curdlg
.ptPaperSize
);
3377 GlobalUnlock(pda
->pdlg
.hDevMode
);
3378 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3379 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3380 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3381 DWORD tmp
= pda
->curdlg
.ptPaperSize
.y
;
3382 pda
->curdlg
.ptPaperSize
.y
= pda
->curdlg
.ptPaperSize
.x
;
3383 pda
->curdlg
.ptPaperSize
.x
= tmp
;
3386 WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda
->pdlg
.hDevMode
);
3387 /* Drawing paper prev */
3388 PRINTDLG_PS_ChangePaperPrev(pda
);
3391 pda
= (PageSetupDataA
*)GetPropA(hDlg
,"__WINE_PAGESETUPDLGDATA");
3393 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3396 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3397 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3398 if (res
) return res
;
3403 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3408 static INT_PTR CALLBACK
3409 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3411 static const WCHAR __WINE_PAGESETUPDLGDATA
[] =
3412 { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
3413 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };
3414 PageSetupDataW
*pdw
;
3417 if (uMsg
==WM_INITDIALOG
) {
3419 pdw
= (PageSetupDataW
*)lParam
;
3420 pdw
->curdlg
= *pdw
->dlgw
;
3421 SetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
, pdw
);
3422 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3423 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3425 FIXME("Setup page hook failed?\n");
3430 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3431 FIXME("PagePaintHook not yet implemented!\n");
3433 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3434 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3435 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3436 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3437 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3438 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3439 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3442 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3444 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3445 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3446 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3448 /* We fill them out enabled or not */
3449 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3451 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3452 SetDlgItemTextW(hDlg
,edt4
,str
);
3453 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3454 SetDlgItemTextW(hDlg
,edt5
,str
);
3455 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3456 SetDlgItemTextW(hDlg
,edt6
,str
);
3457 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3458 SetDlgItemTextW(hDlg
,edt7
,str
);
3460 /* default is 1 inch */
3461 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3463 _c_size2strW(pdw
,size
,str
);
3464 SetDlgItemTextW(hDlg
,edt4
,str
);
3465 SetDlgItemTextW(hDlg
,edt5
,str
);
3466 SetDlgItemTextW(hDlg
,edt6
,str
);
3467 SetDlgItemTextW(hDlg
,edt7
,str
);
3470 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3471 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3472 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3477 pdw
= (PageSetupDataW
*)GetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
);
3479 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3482 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3483 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3484 if (res
) return res
;
3489 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3494 /***********************************************************************
3495 * PageSetupDlgA (COMDLG32.@)
3497 * Displays the PAGE SETUP dialog box, which enables the user to specify
3498 * specific properties of a printed page such as
3499 * size, source, orientation and the width of the page margins.
3502 * setupdlg [IO] PAGESETUPDLGA struct
3505 * TRUE if the user pressed the OK button
3506 * FALSE if the user cancelled the window or an error occurred
3509 * The values of hDevMode and hDevNames are filled on output and can be
3510 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3514 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3518 PageSetupDataA
*pda
;
3521 if (setupdlg
== NULL
) {
3522 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3527 if(TRACE_ON(commdlg
)) {
3528 char flagstr
[1000] = "";
3529 const struct pd_flags
*pflag
= psd_flags
;
3530 for( ; pflag
->name
; pflag
++) {
3531 if(setupdlg
->Flags
& pflag
->flag
) {
3532 strcat(flagstr
, pflag
->name
);
3533 strcat(flagstr
, "|");
3536 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3537 "hinst %p, flags %08x (%s)\n",
3538 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3539 setupdlg
->hDevNames
,
3540 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3543 /* Checking setupdlg structure */
3544 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3545 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3548 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3549 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3550 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3554 /* Initialize default printer struct. If no printer device info is specified
3555 retrieve the default printer data. */
3556 memset(&pdlg
,0,sizeof(pdlg
));
3557 pdlg
.lStructSize
= sizeof(pdlg
);
3558 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3559 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3560 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3562 pdlg
.Flags
= PD_RETURNDEFAULT
;
3563 bRet
= PrintDlgA(&pdlg
);
3565 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3567 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3568 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3574 /* short cut exit, just return default values */
3575 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3578 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3579 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3580 dm
= GlobalLock(pdlg
.hDevMode
);
3581 PRINTDLG_PaperSizeA(&pdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3582 GlobalUnlock(pdlg
.hDevMode
);
3583 setupdlg
->ptPaperSize
.x
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.x
);
3584 setupdlg
->ptPaperSize
.y
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.y
);
3588 /* get dialog template */
3589 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3591 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3594 ptr
= LockResource( hDlgTmpl
);
3596 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3600 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3601 pda
->dlga
= setupdlg
;
3604 bRet
= (0<DialogBoxIndirectParamA(
3605 setupdlg
->hInstance
,
3607 setupdlg
->hwndOwner
,
3608 PRINTDLG_PageDlgProcA
,
3612 HeapFree(GetProcessHeap(),0,pda
);
3615 /***********************************************************************
3616 * PageSetupDlgW (COMDLG32.@)
3618 * See PageSetupDlgA.
3620 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3624 PageSetupDataW
*pdw
;
3627 FIXME("Unicode implementation is not done yet\n");
3629 if (setupdlg
== NULL
) {
3630 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3634 if(TRACE_ON(commdlg
)) {
3635 char flagstr
[1000] = "";
3636 const struct pd_flags
*pflag
= psd_flags
;
3637 for( ; pflag
->name
; pflag
++) {
3638 if(setupdlg
->Flags
& pflag
->flag
) {
3639 strcat(flagstr
, pflag
->name
);
3640 strcat(flagstr
, "|");
3643 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3644 "hinst %p, flags %08x (%s)\n",
3645 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3646 setupdlg
->hDevNames
,
3647 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3650 /* Initialize default printer struct. If no printer device info is specified
3651 retrieve the default printer data. */
3652 memset(&pdlg
,0,sizeof(pdlg
));
3653 pdlg
.lStructSize
= sizeof(pdlg
);
3654 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3655 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3656 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3658 pdlg
.Flags
= PD_RETURNDEFAULT
;
3659 bRet
= PrintDlgW(&pdlg
);
3661 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3663 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3664 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3670 /* short cut exit, just return default values */
3671 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3672 static const WCHAR a4
[] = {'A','4',0};
3673 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3674 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3675 /* FIXME: Just return "A4" for now. */
3676 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3677 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3678 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3681 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3683 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3686 ptr
= LockResource( hDlgTmpl
);
3688 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3691 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3692 pdw
->dlgw
= setupdlg
;
3695 bRet
= (0<DialogBoxIndirectParamW(
3696 setupdlg
->hInstance
,
3698 setupdlg
->hwndOwner
,
3705 /***********************************************************************
3706 * PrintDlgExA (COMDLG32.@)
3714 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3717 FIXME("(%p) stub\n", lppd
);
3718 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3719 return E_INVALIDARG
;
3722 if (!IsWindow(lppd
->hwndOwner
)) {
3729 /***********************************************************************
3730 * PrintDlgExW (COMDLG32.@)
3732 * Display the property sheet style PRINT dialog box
3735 * lppd [IO] ptr to PRINTDLGEX struct
3739 * Failure: One of the following COM error codes:
3740 * E_OUTOFMEMORY Insufficient memory.
3741 * E_INVALIDARG One or more arguments are invalid.
3742 * E_POINTER Invalid pointer.
3743 * E_HANDLE Invalid handle.
3744 * E_FAIL Unspecified error.
3747 * This Dialog enables the user to specify specific properties of the print job.
3748 * The property sheet can also have additional application-specific and
3749 * driver-specific property pages.
3752 * Not fully implemented
3755 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3760 FIXME("(%p) not fully implemented\n", lppd
);
3762 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3763 return E_INVALIDARG
;
3766 if (!IsWindow(lppd
->hwndOwner
)) {
3770 if (lppd
->Flags
& PD_RETURNDEFAULT
) {
3771 PRINTER_INFO_2W
*pbuf
;
3772 DRIVER_INFO_2W
*dbuf
;
3774 DWORD needed
= 1024;
3777 if (lppd
->hDevMode
|| lppd
->hDevNames
) {
3778 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
3779 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3780 return E_INVALIDARG
;
3782 if (!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
3783 WARN("Can't find default printer\n");
3784 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
3788 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3789 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3790 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3791 HeapFree(GetProcessHeap(), 0, pbuf
);
3792 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3793 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3796 HeapFree(GetProcessHeap(), 0, pbuf
);
3802 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3803 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3804 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3805 HeapFree(GetProcessHeap(), 0, dbuf
);
3806 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3807 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3810 ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
3811 GetLastError(), debugstr_w(pbuf
->pPrinterName
));
3812 HeapFree(GetProcessHeap(), 0, dbuf
);
3813 HeapFree(GetProcessHeap(), 0, pbuf
);
3814 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3820 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
3824 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
3825 pbuf
->pDevMode
->dmDriverExtra
);
3826 if (lppd
->hDevMode
) {
3827 ptr
= GlobalLock(lppd
->hDevMode
);
3829 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
3830 pbuf
->pDevMode
->dmDriverExtra
);
3831 GlobalUnlock(lppd
->hDevMode
);
3835 HeapFree(GetProcessHeap(), 0, pbuf
);
3836 HeapFree(GetProcessHeap(), 0, dbuf
);