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 */
313 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
314 nToPage
= GetDlgItemInt(hDlg
, edt2
, &translated
, FALSE
);
316 /* if no ToPage value is entered, use the FromPage value */
317 if(!translated
) nToPage
= nFromPage
;
319 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
320 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
321 WCHAR resourcestr
[256];
322 WCHAR resultstr
[256];
323 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
, resourcestr
, 255);
324 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
325 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
, resourcestr
, 255);
326 MessageBoxW(hDlg
, resultstr
, resourcestr
, MB_OK
| MB_ICONWARNING
);
329 lppd
->nFromPage
= nFromPage
;
330 lppd
->nToPage
= nToPage
;
331 lppd
->Flags
|= PD_PAGENUMS
;
334 lppd
->Flags
&= ~PD_PAGENUMS
;
336 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
337 lppd
->Flags
|= PD_SELECTION
;
339 lppd
->Flags
&= ~PD_SELECTION
;
341 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
342 static char file
[] = "FILE:";
343 lppd
->Flags
|= PD_PRINTTOFILE
;
344 pi
->pPortName
= file
;
347 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
348 FIXME("Collate lppd not yet implemented as output\n");
351 /* set PD_Collate and nCopies */
352 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
353 /* The application doesn't support multiple copies or collate...
355 lppd
->Flags
&= ~PD_COLLATE
;
357 /* if the printer driver supports it... store info there
358 * otherwise no collate & multiple copies !
360 if (lpdm
->dmFields
& DM_COLLATE
)
362 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
363 if (lpdm
->dmFields
& DM_COPIES
)
364 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
366 /* Application is responsible for multiple copies */
367 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
368 lppd
->Flags
|= PD_COLLATE
;
370 lppd
->Flags
&= ~PD_COLLATE
;
371 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
372 /* multiple copies already included in the document. Driver must print only one copy */
373 lpdm
->u1
.s1
.dmCopies
= 1;
376 /* Print quality, PrintDlg16 */
377 if(GetDlgItem(hDlg
, cmb1
))
379 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
380 int Sel
= SendMessageA(hQuality
, CB_GETCURSEL
, 0, 0);
384 LONG dpi
= SendMessageA(hQuality
, CB_GETITEMDATA
, Sel
, 0);
385 lpdm
->dmFields
|= DM_PRINTQUALITY
| DM_YRESOLUTION
;
386 lpdm
->u1
.s1
.dmPrintQuality
= LOWORD(dpi
);
387 lpdm
->dmYResolution
= HIWORD(dpi
);
394 static BOOL
PRINTDLG_UpdatePrintDlgW(HWND hDlg
,
395 PRINT_PTRW
* PrintStructures
)
397 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
398 PDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
399 LPPRINTER_INFO_2W pi
= PrintStructures
->lpPrinterInfo
;
403 FIXME("No lpdm ptr?\n");
408 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
409 /* check whether nFromPage and nToPage are within range defined by
410 * nMinPage and nMaxPage
412 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
) { /* Pages */
416 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
417 nToPage
= GetDlgItemInt(hDlg
, edt2
, &translated
, FALSE
);
419 /* if no ToPage value is entered, use the FromPage value */
420 if(!translated
) nToPage
= nFromPage
;
422 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
423 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
) {
424 WCHAR resourcestr
[256];
425 WCHAR resultstr
[256];
426 LoadStringW(COMDLG32_hInstance
, PD32_INVALID_PAGE_RANGE
,
428 wsprintfW(resultstr
,resourcestr
, lppd
->nMinPage
, lppd
->nMaxPage
);
429 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,
431 MessageBoxW(hDlg
, resultstr
, resourcestr
,
432 MB_OK
| MB_ICONWARNING
);
435 lppd
->nFromPage
= nFromPage
;
436 lppd
->nToPage
= nToPage
;
437 lppd
->Flags
|= PD_PAGENUMS
;
440 lppd
->Flags
&= ~PD_PAGENUMS
;
442 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) /* Selection */
443 lppd
->Flags
|= PD_SELECTION
;
445 lppd
->Flags
&= ~PD_SELECTION
;
447 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
) {/* Print to file */
448 static WCHAR file
[] = {'F','I','L','E',':',0};
449 lppd
->Flags
|= PD_PRINTTOFILE
;
450 pi
->pPortName
= file
;
453 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
) { /* Collate */
454 FIXME("Collate lppd not yet implemented as output\n");
457 /* set PD_Collate and nCopies */
458 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
459 /* The application doesn't support multiple copies or collate...
461 lppd
->Flags
&= ~PD_COLLATE
;
463 /* if the printer driver supports it... store info there
464 * otherwise no collate & multiple copies !
466 if (lpdm
->dmFields
& DM_COLLATE
)
468 (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
);
469 if (lpdm
->dmFields
& DM_COPIES
)
470 lpdm
->u1
.s1
.dmCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
472 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
473 lppd
->Flags
|= PD_COLLATE
;
475 lppd
->Flags
&= ~PD_COLLATE
;
476 lppd
->nCopies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
482 static BOOL
PRINTDLG_PaperSizeA(
483 PRINTDLGA
*pdlga
,const WORD PaperSize
,LPPOINT size
487 LPSTR devname
,portname
;
491 POINT
*points
= NULL
;
494 dn
= GlobalLock(pdlga
->hDevNames
);
495 dm
= GlobalLock(pdlga
->hDevMode
);
496 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
497 portname
= ((char*)dn
)+dn
->wOutputOffset
;
500 NrOfEntries
= DeviceCapabilitiesA(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
502 FIXME("No papernames found for %s/%s\n",devname
,portname
);
505 if (NrOfEntries
== -1) {
506 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
510 Words
= HeapAlloc(GetProcessHeap(),0,NrOfEntries
*sizeof(WORD
));
511 if (NrOfEntries
!= (ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERS
,(LPSTR
)Words
,dm
))) {
512 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
515 for (i
=0;i
<NrOfEntries
;i
++)
516 if (Words
[i
] == PaperSize
)
518 if (i
== NrOfEntries
) {
519 FIXME("Papersize %d not found in list?\n",PaperSize
);
522 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
523 if (NrOfEntries
!=(ret
=DeviceCapabilitiesA(devname
,portname
,DC_PAPERSIZE
,(LPSTR
)points
,dm
))) {
524 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
527 /* this is _10ths_ of a millimeter */
532 GlobalUnlock(pdlga
->hDevNames
);
533 GlobalUnlock(pdlga
->hDevMode
);
534 HeapFree(GetProcessHeap(),0,Words
);
535 HeapFree(GetProcessHeap(),0,points
);
539 static BOOL
PRINTDLG_PaperSizeW(
540 PRINTDLGW
*pdlga
,const WCHAR
*PaperSize
,LPPOINT size
544 LPWSTR devname
,portname
;
548 POINT
*points
= NULL
;
551 dn
= GlobalLock(pdlga
->hDevNames
);
552 dm
= GlobalLock(pdlga
->hDevMode
);
553 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
554 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
557 NrOfEntries
= DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,NULL
,dm
);
559 FIXME("No papernames found for %s/%s\n",debugstr_w(devname
),debugstr_w(portname
));
562 if (NrOfEntries
== -1) {
563 ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
567 Names
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*NrOfEntries
*64);
568 if (NrOfEntries
!= (ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERNAMES
,Names
,dm
))) {
569 FIXME("Number of returned vals %d is not %d\n",NrOfEntries
,ret
);
572 for (i
=0;i
<NrOfEntries
;i
++)
573 if (!lstrcmpW(PaperSize
,Names
+(64*i
)))
575 if (i
==NrOfEntries
) {
576 FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize
));
579 points
= HeapAlloc(GetProcessHeap(),0,sizeof(points
[0])*NrOfEntries
);
580 if (NrOfEntries
!=(ret
=DeviceCapabilitiesW(devname
,portname
,DC_PAPERSIZE
,(LPWSTR
)points
,dm
))) {
581 FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries
,ret
);
584 /* this is _10ths_ of a millimeter */
589 GlobalUnlock(pdlga
->hDevNames
);
590 GlobalUnlock(pdlga
->hDevMode
);
591 HeapFree(GetProcessHeap(),0,Names
);
592 HeapFree(GetProcessHeap(),0,points
);
597 /************************************************************************
598 * PRINTDLG_SetUpPaperComboBox
600 * Initialize either the papersize or inputslot combos of the Printer Setup
601 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
602 * We also try to re-select the old selection.
604 static BOOL
PRINTDLG_SetUpPaperComboBoxA(HWND hDlg
,
617 int fwCapability_Names
;
618 int fwCapability_Words
;
620 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName
,PortName
,nIDComboBox
);
622 /* query the dialog box for the current selected value */
623 Sel
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
625 /* we enter here only if a different printer is selected after
626 * the Print Setup dialog is opened. The current settings are
627 * stored into the newly selected printer.
629 oldWord
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
632 if (nIDComboBox
== cmb2
)
633 dm
->u1
.s1
.dmPaperSize
= oldWord
;
635 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
639 /* we enter here only when the Print setup dialog is initially
640 * opened. In this case the settings are restored from when
641 * the dialog was last closed.
644 if (nIDComboBox
== cmb2
)
645 oldWord
= dm
->u1
.s1
.dmPaperSize
;
647 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
651 if (nIDComboBox
== cmb2
) {
653 fwCapability_Names
= DC_PAPERNAMES
;
654 fwCapability_Words
= DC_PAPERS
;
658 fwCapability_Names
= DC_BINNAMES
;
659 fwCapability_Words
= DC_BINS
;
662 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
663 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
665 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
666 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
667 fwCapability_Names
, NULL
, dm
);
668 if (NrOfEntries
== 0)
669 WARN("no Name Entries found!\n");
670 else if (NrOfEntries
< 0)
673 if(DeviceCapabilitiesA(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
675 ERR("Number of caps is different\n");
679 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(char)*NamesSize
);
680 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
681 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
682 fwCapability_Names
, Names
, dm
);
683 NrOfEntries
= DeviceCapabilitiesA(PrinterName
, PortName
,
684 fwCapability_Words
, (LPSTR
)Words
, dm
);
686 /* reset any current content in the combobox */
687 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
689 /* store new content */
690 for (i
= 0; i
< NrOfEntries
; i
++) {
691 DWORD pos
= SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
692 (LPARAM
)(&Names
[i
*NamesSize
]) );
693 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
697 /* Look for old selection - can't do this is previous loop since
698 item order will change as more items are added */
700 for (i
= 0; i
< NrOfEntries
; i
++) {
701 if(SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
707 SendDlgItemMessageA(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
709 HeapFree(GetProcessHeap(),0,Words
);
710 HeapFree(GetProcessHeap(),0,Names
);
714 static BOOL
PRINTDLG_SetUpPaperComboBoxW(HWND hDlg
,
716 const WCHAR
* PrinterName
,
717 const WCHAR
* PortName
,
727 int fwCapability_Names
;
728 int fwCapability_Words
;
730 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName
),debugstr_w(PortName
),nIDComboBox
);
732 /* query the dialog box for the current selected value */
733 Sel
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETCURSEL
, 0, 0);
735 /* we enter here only if a different printer is selected after
736 * the Print Setup dialog is opened. The current settings are
737 * stored into the newly selected printer.
739 oldWord
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
,
742 if (nIDComboBox
== cmb2
)
743 dm
->u1
.s1
.dmPaperSize
= oldWord
;
745 dm
->u1
.s1
.dmDefaultSource
= oldWord
;
749 /* we enter here only when the Print setup dialog is initially
750 * opened. In this case the settings are restored from when
751 * the dialog was last closed.
754 if (nIDComboBox
== cmb2
)
755 oldWord
= dm
->u1
.s1
.dmPaperSize
;
757 oldWord
= dm
->u1
.s1
.dmDefaultSource
;
761 if (nIDComboBox
== cmb2
) {
763 fwCapability_Names
= DC_PAPERNAMES
;
764 fwCapability_Words
= DC_PAPERS
;
768 fwCapability_Names
= DC_BINNAMES
;
769 fwCapability_Words
= DC_BINS
;
772 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
773 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
775 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
776 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
777 fwCapability_Names
, NULL
, dm
);
778 if (NrOfEntries
== 0)
779 WARN("no Name Entries found!\n");
780 else if (NrOfEntries
< 0)
783 if(DeviceCapabilitiesW(PrinterName
, PortName
, fwCapability_Words
, NULL
, dm
)
785 ERR("Number of caps is different\n");
789 Names
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WCHAR
)*NamesSize
);
790 Words
= HeapAlloc(GetProcessHeap(),0, NrOfEntries
*sizeof(WORD
));
791 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
792 fwCapability_Names
, Names
, dm
);
793 NrOfEntries
= DeviceCapabilitiesW(PrinterName
, PortName
,
794 fwCapability_Words
, (LPWSTR
)Words
, dm
);
796 /* reset any current content in the combobox */
797 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_RESETCONTENT
, 0, 0);
799 /* store new content */
800 for (i
= 0; i
< NrOfEntries
; i
++) {
801 DWORD pos
= SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_ADDSTRING
, 0,
802 (LPARAM
)(&Names
[i
*NamesSize
]) );
803 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETITEMDATA
, pos
,
807 /* Look for old selection - can't do this is previous loop since
808 item order will change as more items are added */
810 for (i
= 0; i
< NrOfEntries
; i
++) {
811 if(SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_GETITEMDATA
, i
, 0) ==
817 SendDlgItemMessageW(hDlg
, nIDComboBox
, CB_SETCURSEL
, Sel
, 0);
819 HeapFree(GetProcessHeap(),0,Words
);
820 HeapFree(GetProcessHeap(),0,Names
);
825 /***********************************************************************
826 * PRINTDLG_UpdatePrinterInfoTexts [internal]
828 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg
, const PRINTER_INFO_2A
*pi
)
831 char ResourceString
[256];
837 /* add all status messages */
838 for (i
= 0; i
< 25; i
++) {
839 if (pi
->Status
& (1<<i
)) {
840 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
841 ResourceString
, 255);
842 strcat(StatusMsg
,ResourceString
);
846 /* FIXME: status==ready must only be appended if really so.
847 but how to detect? */
848 LoadStringA(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
849 ResourceString
, 255);
850 strcat(StatusMsg
,ResourceString
);
851 SetDlgItemTextA(hDlg
, stc12
, StatusMsg
);
853 /* set all other printer info texts */
854 SetDlgItemTextA(hDlg
, stc11
, pi
->pDriverName
);
856 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
857 SetDlgItemTextA(hDlg
, stc14
, pi
->pLocation
);
859 SetDlgItemTextA(hDlg
, stc14
, pi
->pPortName
);
860 SetDlgItemTextA(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: "");
864 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg
, const PRINTER_INFO_2W
*pi
)
866 WCHAR StatusMsg
[256];
867 WCHAR ResourceString
[256];
868 static const WCHAR emptyW
[] = {0};
874 /* add all status messages */
875 for (i
= 0; i
< 25; i
++) {
876 if (pi
->Status
& (1<<i
)) {
877 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_PAUSED
+i
,
878 ResourceString
, 255);
879 lstrcatW(StatusMsg
,ResourceString
);
883 /* FIXME: status==ready must only be appended if really so.
884 but how to detect? */
885 LoadStringW(COMDLG32_hInstance
, PD32_PRINTER_STATUS_READY
,
886 ResourceString
, 255);
887 lstrcatW(StatusMsg
,ResourceString
);
888 SetDlgItemTextW(hDlg
, stc12
, StatusMsg
);
890 /* set all other printer info texts */
891 SetDlgItemTextW(hDlg
, stc11
, pi
->pDriverName
);
892 if (pi
->pLocation
!= NULL
&& pi
->pLocation
[0] != '\0')
893 SetDlgItemTextW(hDlg
, stc14
, pi
->pLocation
);
895 SetDlgItemTextW(hDlg
, stc14
, pi
->pPortName
);
896 SetDlgItemTextW(hDlg
, stc13
, pi
->pComment
? pi
->pComment
: emptyW
);
900 /*******************************************************************
902 * PRINTDLG_ChangePrinter
905 BOOL
PRINTDLG_ChangePrinterA(HWND hDlg
, char *name
,
906 PRINT_PTRA
*PrintStructures
)
908 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
909 LPDEVMODEA lpdm
= NULL
;
914 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
915 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
916 if(!OpenPrinterA(name
, &hprn
, NULL
)) {
917 ERR("Can't open printer %s\n", name
);
920 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
921 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
922 GetPrinterA(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
924 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
925 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,needed
);
926 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
928 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures
->lpPrinterInfo
->pPrinterName
);
933 PRINTDLG_UpdatePrinterInfoTextsA(hDlg
, PrintStructures
->lpPrinterInfo
);
935 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
936 PrintStructures
->lpDevMode
= NULL
;
938 dmSize
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
940 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
943 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
944 dmSize
= DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
946 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
947 !lstrcmpA( (LPSTR
) lpdm
->dmDeviceName
,
948 (LPSTR
) PrintStructures
->lpDevMode
->dmDeviceName
)) {
949 /* Supplied devicemode matches current printer so try to use it */
950 DocumentPropertiesA(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
951 DM_OUT_BUFFER
| DM_IN_BUFFER
);
954 GlobalUnlock(lppd
->hDevMode
);
956 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
958 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
959 /* Print range (All/Range/Selection) */
960 if(lppd
->nFromPage
!= 0xffff)
961 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
962 if(lppd
->nToPage
!= 0xffff)
963 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
965 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
966 if (lppd
->Flags
& PD_NOSELECTION
)
967 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
969 if (lppd
->Flags
& PD_SELECTION
)
970 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
971 if (lppd
->Flags
& PD_NOPAGENUMS
) {
972 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
973 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
974 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
975 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
976 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
978 if (lppd
->Flags
& PD_PAGENUMS
)
979 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
984 * FIXME: The ico3 is not displayed for some reason. I don't know why.
986 if (lppd
->Flags
& PD_COLLATE
) {
987 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
988 (LPARAM
)PrintStructures
->hCollateIcon
);
989 CheckDlgButton(hDlg
, chx2
, 1);
991 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
992 (LPARAM
)PrintStructures
->hNoCollateIcon
);
993 CheckDlgButton(hDlg
, chx2
, 0);
996 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
997 /* if printer doesn't support it: no Collate */
998 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
999 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1000 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1007 if (lppd
->hDevMode
== 0)
1008 copies
= lppd
->nCopies
;
1010 copies
= lpdm
->u1
.s1
.dmCopies
;
1011 if(copies
== 0) copies
= 1;
1012 else if(copies
< 0) copies
= MAX_COPIES
;
1013 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1016 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1017 /* if printer doesn't support it: no nCopies */
1018 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1019 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1020 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1025 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1026 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1027 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1028 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1029 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1031 /* Fill print quality combo, PrintDlg16 */
1032 if(GetDlgItem(hDlg
, cmb1
))
1034 DWORD numResolutions
= DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1035 PrintStructures
->lpPrinterInfo
->pPortName
,
1036 DC_ENUMRESOLUTIONS
, NULL
, lpdm
);
1038 if(numResolutions
!= -1)
1040 HWND hQuality
= GetDlgItem(hDlg
, cmb1
);
1045 HDC hPrinterDC
= CreateDCA(PrintStructures
->lpPrinterInfo
->pDriverName
,
1046 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1049 Resolutions
= HeapAlloc(GetProcessHeap(), 0, numResolutions
*sizeof(LONG
)*2);
1050 DeviceCapabilitiesA(PrintStructures
->lpPrinterInfo
->pPrinterName
,
1051 PrintStructures
->lpPrinterInfo
->pPortName
,
1052 DC_ENUMRESOLUTIONS
, (LPSTR
)Resolutions
, lpdm
);
1054 dpiX
= GetDeviceCaps(hPrinterDC
, LOGPIXELSX
);
1055 dpiY
= GetDeviceCaps(hPrinterDC
, LOGPIXELSY
);
1056 DeleteDC(hPrinterDC
);
1058 SendMessageA(hQuality
, CB_RESETCONTENT
, 0, 0);
1059 for(i
= 0; i
< (numResolutions
* 2); i
+= 2)
1061 BOOL IsDefault
= FALSE
;
1064 if(Resolutions
[i
] == Resolutions
[i
+1])
1066 if(dpiX
== Resolutions
[i
])
1068 sprintf(buf
, "%d dpi", Resolutions
[i
]);
1071 if(dpiX
== Resolutions
[i
] && dpiY
== Resolutions
[i
+1])
1073 sprintf(buf
, "%d dpi x %d dpi", Resolutions
[i
], Resolutions
[i
+1]);
1076 Index
= SendMessageA(hQuality
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
1079 SendMessageA(hQuality
, CB_SETCURSEL
, Index
, 0);
1081 SendMessageA(hQuality
, CB_SETITEMDATA
, Index
, MAKELONG(dpiX
,dpiY
));
1083 HeapFree(GetProcessHeap(), 0, Resolutions
);
1086 } else { /* PD_PRINTSETUP */
1087 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1089 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb2
,
1090 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1091 PrintStructures
->lpPrinterInfo
->pPortName
,
1093 PRINTDLG_SetUpPaperComboBoxA(hDlg
, cmb3
,
1094 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1095 PrintStructures
->lpPrinterInfo
->pPortName
,
1097 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1098 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1099 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1100 PrintStructures
->hLandscapeIcon
));
1105 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1106 /* hide if PD_SHOWHELP not specified */
1107 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1112 static BOOL
PRINTDLG_ChangePrinterW(HWND hDlg
, WCHAR
*name
,
1113 PRINT_PTRW
*PrintStructures
)
1115 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1116 LPDEVMODEW lpdm
= NULL
;
1121 HeapFree(GetProcessHeap(),0, PrintStructures
->lpPrinterInfo
);
1122 HeapFree(GetProcessHeap(),0, PrintStructures
->lpDriverInfo
);
1123 if(!OpenPrinterW(name
, &hprn
, NULL
)) {
1124 ERR("Can't open printer %s\n", debugstr_w(name
));
1127 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
1128 PrintStructures
->lpPrinterInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1129 GetPrinterW(hprn
, 2, (LPBYTE
)PrintStructures
->lpPrinterInfo
, needed
,
1131 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
1132 PrintStructures
->lpDriverInfo
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
1133 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)PrintStructures
->lpDriverInfo
,
1135 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures
->lpPrinterInfo
->pPrinterName
));
1140 PRINTDLG_UpdatePrinterInfoTextsW(hDlg
, PrintStructures
->lpPrinterInfo
);
1142 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
1143 PrintStructures
->lpDevMode
= NULL
;
1145 dmSize
= DocumentPropertiesW(0, 0, name
, NULL
, NULL
, 0);
1147 ERR("DocumentProperties fails on %s\n", debugstr_w(name
));
1150 PrintStructures
->lpDevMode
= HeapAlloc(GetProcessHeap(), 0, dmSize
);
1151 dmSize
= DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, NULL
,
1153 if(lppd
->hDevMode
&& (lpdm
= GlobalLock(lppd
->hDevMode
)) &&
1154 !lstrcmpW(lpdm
->dmDeviceName
,
1155 PrintStructures
->lpDevMode
->dmDeviceName
)) {
1156 /* Supplied devicemode matches current printer so try to use it */
1157 DocumentPropertiesW(0, 0, name
, PrintStructures
->lpDevMode
, lpdm
,
1158 DM_OUT_BUFFER
| DM_IN_BUFFER
);
1161 GlobalUnlock(lppd
->hDevMode
);
1163 lpdm
= PrintStructures
->lpDevMode
; /* use this as a shortcut */
1165 if(!(lppd
->Flags
& PD_PRINTSETUP
)) {
1166 /* Print range (All/Range/Selection) */
1167 if(lppd
->nFromPage
!= 0xffff)
1168 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
1169 if(lppd
->nToPage
!= 0xffff)
1170 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
1172 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
1173 if (lppd
->Flags
& PD_NOSELECTION
)
1174 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
1176 if (lppd
->Flags
& PD_SELECTION
)
1177 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
1178 if (lppd
->Flags
& PD_NOPAGENUMS
) {
1179 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
1180 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
1181 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
1182 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
1183 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
1185 if (lppd
->Flags
& PD_PAGENUMS
)
1186 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1191 * FIXME: The ico3 is not displayed for some reason. I don't know why.
1193 if (lppd
->Flags
& PD_COLLATE
) {
1194 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1195 (LPARAM
)PrintStructures
->hCollateIcon
);
1196 CheckDlgButton(hDlg
, chx2
, 1);
1198 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1199 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1200 CheckDlgButton(hDlg
, chx2
, 0);
1203 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1204 /* if printer doesn't support it: no Collate */
1205 if (!(lpdm
->dmFields
& DM_COLLATE
)) {
1206 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1207 EnableWindow(GetDlgItem(hDlg
, ico3
), FALSE
);
1214 if (lppd
->hDevMode
== 0)
1215 copies
= lppd
->nCopies
;
1217 copies
= lpdm
->u1
.s1
.dmCopies
;
1218 if(copies
== 0) copies
= 1;
1219 else if(copies
< 0) copies
= MAX_COPIES
;
1220 SetDlgItemInt(hDlg
, edt3
, copies
, FALSE
);
1223 if (lppd
->Flags
& PD_USEDEVMODECOPIESANDCOLLATE
) {
1224 /* if printer doesn't support it: no nCopies */
1225 if (!(lpdm
->dmFields
& DM_COPIES
)) {
1226 EnableWindow(GetDlgItem(hDlg
, edt3
), FALSE
);
1227 EnableWindow(GetDlgItem(hDlg
, stc5
), FALSE
);
1232 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
1233 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
1234 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
1235 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
1236 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
1238 } else { /* PD_PRINTSETUP */
1239 BOOL bPortrait
= (lpdm
->u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
);
1241 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb2
,
1242 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1243 PrintStructures
->lpPrinterInfo
->pPortName
,
1245 PRINTDLG_SetUpPaperComboBoxW(hDlg
, cmb3
,
1246 PrintStructures
->lpPrinterInfo
->pPrinterName
,
1247 PrintStructures
->lpPrinterInfo
->pPortName
,
1249 CheckRadioButton(hDlg
, rad1
, rad2
, bPortrait
? rad1
: rad2
);
1250 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1251 (LPARAM
)(bPortrait
? PrintStructures
->hPortraitIcon
:
1252 PrintStructures
->hLandscapeIcon
));
1257 if ((lppd
->Flags
& PD_SHOWHELP
)==0) {
1258 /* hide if PD_SHOWHELP not specified */
1259 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
1264 /***********************************************************************
1265 * check_printer_setup [internal]
1267 static LRESULT
check_printer_setup(HWND hDlg
)
1270 WCHAR resourcestr
[256],resultstr
[256];
1272 EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &needed
, &num
);
1275 EnumPrintersW(PRINTER_ENUM_CONNECTIONS
, NULL
, 2, NULL
, 0, &needed
, &num
);
1281 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEVICES
,resultstr
, 255);
1282 LoadStringW(COMDLG32_hInstance
, PD32_PRINT_TITLE
,resourcestr
, 255);
1283 MessageBoxW(hDlg
, resultstr
, resourcestr
,MB_OK
| MB_ICONWARNING
);
1288 /***********************************************************************
1289 * PRINTDLG_WMInitDialog [internal]
1291 static LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
,
1292 PRINT_PTRA
* PrintStructures
)
1294 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1298 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1300 /* load Collate ICONs */
1301 /* We load these with LoadImage because they are not a standard
1302 size and we don't want them rescaled */
1303 PrintStructures
->hCollateIcon
=
1304 LoadImageA(COMDLG32_hInstance
, "PD32_COLLATE", IMAGE_ICON
, 0, 0, 0);
1305 PrintStructures
->hNoCollateIcon
=
1306 LoadImageA(COMDLG32_hInstance
, "PD32_NOCOLLATE", IMAGE_ICON
, 0, 0, 0);
1308 /* These can be done with LoadIcon */
1309 PrintStructures
->hPortraitIcon
=
1310 LoadIconA(COMDLG32_hInstance
, "PD32_PORTRAIT");
1311 PrintStructures
->hLandscapeIcon
=
1312 LoadIconA(COMDLG32_hInstance
, "PD32_LANDSCAPE");
1314 /* display the collate/no_collate icon */
1315 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1316 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1318 if(PrintStructures
->hCollateIcon
== 0 ||
1319 PrintStructures
->hNoCollateIcon
== 0 ||
1320 PrintStructures
->hPortraitIcon
== 0 ||
1321 PrintStructures
->hLandscapeIcon
== 0) {
1322 ERR("no icon in resourcefile\n");
1323 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1324 EndDialog(hDlg
, FALSE
);
1328 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1329 * must be registered and the Help button must be shown.
1331 if (lppd
->Flags
& PD_SHOWHELP
) {
1332 if((PrintStructures
->HelpMessageID
=
1333 RegisterWindowMessageA(HELPMSGSTRINGA
)) == 0) {
1334 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1338 PrintStructures
->HelpMessageID
= 0;
1340 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1341 PrintStructures
->hwndUpDown
=
1342 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1343 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1344 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1345 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1346 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1349 /* FIXME: I allow more freedom than either Win95 or WinNT,
1350 * which do not agree to what errors should be thrown or not
1351 * in case nToPage or nFromPage is out-of-range.
1353 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1354 lppd
->nMaxPage
= lppd
->nMinPage
;
1355 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1356 lppd
->Flags
|= PD_NOPAGENUMS
;
1357 if (lppd
->nToPage
< lppd
->nMinPage
)
1358 lppd
->nToPage
= lppd
->nMinPage
;
1359 if (lppd
->nToPage
> lppd
->nMaxPage
)
1360 lppd
->nToPage
= lppd
->nMaxPage
;
1361 if (lppd
->nFromPage
< lppd
->nMinPage
)
1362 lppd
->nFromPage
= lppd
->nMinPage
;
1363 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1364 lppd
->nFromPage
= lppd
->nMaxPage
;
1366 /* if we have the combo box, fill it */
1367 if (GetDlgItem(hDlg
,comboID
)) {
1370 pdn
= GlobalLock(lppd
->hDevNames
);
1371 pdm
= GlobalLock(lppd
->hDevMode
);
1373 name
= (char*)pdn
+ pdn
->wDeviceOffset
;
1375 name
= (char*)pdm
->dmDeviceName
;
1376 PRINTDLG_SetUpPrinterListComboA(hDlg
, comboID
, name
);
1377 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1378 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1380 /* Now find selected printer and update rest of dlg */
1381 name
= HeapAlloc(GetProcessHeap(),0,256);
1382 if (GetDlgItemTextA(hDlg
, comboID
, name
, 255))
1383 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1384 HeapFree(GetProcessHeap(),0,name
);
1386 /* else use default printer */
1388 DWORD dwBufLen
= sizeof(name
);
1389 BOOL ret
= GetDefaultPrinterA(name
, &dwBufLen
);
1392 PRINTDLG_ChangePrinterA(hDlg
, name
, PrintStructures
);
1394 FIXME("No default printer found, expect problems!\n");
1399 static LRESULT
PRINTDLG_WMInitDialogW(HWND hDlg
, WPARAM wParam
,
1400 PRINT_PTRW
* PrintStructures
)
1402 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1406 UINT comboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1408 /* load Collate ICONs */
1409 /* We load these with LoadImage because they are not a standard
1410 size and we don't want them rescaled */
1411 PrintStructures
->hCollateIcon
=
1412 LoadImageW(COMDLG32_hInstance
, pd32_collateW
, IMAGE_ICON
, 0, 0, 0);
1413 PrintStructures
->hNoCollateIcon
=
1414 LoadImageW(COMDLG32_hInstance
, pd32_nocollateW
, IMAGE_ICON
, 0, 0, 0);
1416 /* These can be done with LoadIcon */
1417 PrintStructures
->hPortraitIcon
=
1418 LoadIconW(COMDLG32_hInstance
, pd32_portraitW
);
1419 PrintStructures
->hLandscapeIcon
=
1420 LoadIconW(COMDLG32_hInstance
, pd32_landscapeW
);
1422 /* display the collate/no_collate icon */
1423 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1424 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1426 if(PrintStructures
->hCollateIcon
== 0 ||
1427 PrintStructures
->hNoCollateIcon
== 0 ||
1428 PrintStructures
->hPortraitIcon
== 0 ||
1429 PrintStructures
->hLandscapeIcon
== 0) {
1430 ERR("no icon in resourcefile\n");
1431 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
1432 EndDialog(hDlg
, FALSE
);
1436 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
1437 * must be registered and the Help button must be shown.
1439 if (lppd
->Flags
& PD_SHOWHELP
) {
1440 if((PrintStructures
->HelpMessageID
=
1441 RegisterWindowMessageW(HELPMSGSTRINGW
)) == 0) {
1442 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
1446 PrintStructures
->HelpMessageID
= 0;
1448 if(!(lppd
->Flags
&PD_PRINTSETUP
)) {
1449 PrintStructures
->hwndUpDown
=
1450 CreateUpDownControl(WS_CHILD
| WS_VISIBLE
| WS_BORDER
|
1451 UDS_NOTHOUSANDS
| UDS_ARROWKEYS
|
1452 UDS_ALIGNRIGHT
| UDS_SETBUDDYINT
, 0, 0, 0, 0,
1453 hDlg
, UPDOWN_ID
, COMDLG32_hInstance
,
1454 GetDlgItem(hDlg
, edt3
), MAX_COPIES
, 1, 1);
1457 /* FIXME: I allow more freedom than either Win95 or WinNT,
1458 * which do not agree to what errors should be thrown or not
1459 * in case nToPage or nFromPage is out-of-range.
1461 if (lppd
->nMaxPage
< lppd
->nMinPage
)
1462 lppd
->nMaxPage
= lppd
->nMinPage
;
1463 if (lppd
->nMinPage
== lppd
->nMaxPage
)
1464 lppd
->Flags
|= PD_NOPAGENUMS
;
1465 if (lppd
->nToPage
< lppd
->nMinPage
)
1466 lppd
->nToPage
= lppd
->nMinPage
;
1467 if (lppd
->nToPage
> lppd
->nMaxPage
)
1468 lppd
->nToPage
= lppd
->nMaxPage
;
1469 if (lppd
->nFromPage
< lppd
->nMinPage
)
1470 lppd
->nFromPage
= lppd
->nMinPage
;
1471 if (lppd
->nFromPage
> lppd
->nMaxPage
)
1472 lppd
->nFromPage
= lppd
->nMaxPage
;
1474 /* if we have the combo box, fill it */
1475 if (GetDlgItem(hDlg
,comboID
)) {
1478 pdn
= GlobalLock(lppd
->hDevNames
);
1479 pdm
= GlobalLock(lppd
->hDevMode
);
1481 name
= (WCHAR
*)pdn
+ pdn
->wDeviceOffset
;
1483 name
= pdm
->dmDeviceName
;
1484 PRINTDLG_SetUpPrinterListComboW(hDlg
, comboID
, name
);
1485 if(pdm
) GlobalUnlock(lppd
->hDevMode
);
1486 if(pdn
) GlobalUnlock(lppd
->hDevNames
);
1488 /* Now find selected printer and update rest of dlg */
1489 /* ansi is ok here */
1490 name
= HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR
));
1491 if (GetDlgItemTextW(hDlg
, comboID
, name
, 255))
1492 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1493 HeapFree(GetProcessHeap(),0,name
);
1495 /* else use default printer */
1497 DWORD dwBufLen
= sizeof(name
) / sizeof(WCHAR
);
1498 BOOL ret
= GetDefaultPrinterW(name
, &dwBufLen
);
1501 PRINTDLG_ChangePrinterW(hDlg
, name
, PrintStructures
);
1503 FIXME("No default printer found, expect problems!\n");
1508 /***********************************************************************
1509 * PRINTDLG_WMCommand [internal]
1511 LRESULT
PRINTDLG_WMCommandA(HWND hDlg
, WPARAM wParam
,
1512 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
1514 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
1515 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1516 LPDEVMODEA lpdm
= PrintStructures
->lpDevMode
;
1518 switch (LOWORD(wParam
)) {
1520 TRACE(" OK button was hit\n");
1521 if (!PRINTDLG_UpdatePrintDlgA(hDlg
, PrintStructures
)) {
1522 FIXME("Update printdlg was not successful!\n");
1525 EndDialog(hDlg
, TRUE
);
1529 TRACE(" CANCEL button was hit\n");
1530 EndDialog(hDlg
, FALSE
);
1534 TRACE(" HELP button was hit\n");
1535 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1536 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1539 case chx2
: /* collate pages checkbox */
1540 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1541 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1542 (LPARAM
)PrintStructures
->hCollateIcon
);
1544 SendDlgItemMessageA(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1545 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1547 case edt1
: /* from page nr editbox */
1548 case edt2
: /* to page nr editbox */
1549 if (HIWORD(wParam
)==EN_CHANGE
) {
1552 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1553 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1554 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1555 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1560 if(HIWORD(wParam
) == EN_CHANGE
) {
1561 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1563 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1565 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1570 case psh1
: /* Print Setup */
1574 if (!PrintStructures
->dlg
.lpPrintDlg16
) {
1575 FIXME("The 32bit print dialog does not have this button!?\n");
1579 memcpy(&pdlg
,PrintStructures
->dlg
.lpPrintDlg16
,sizeof(pdlg
));
1580 pdlg
.Flags
|= PD_PRINTSETUP
;
1581 pdlg
.hwndOwner
= HWND_16(hDlg
);
1582 if (!PrintDlg16(&pdlg
))
1587 case psh2
: /* Properties button */
1590 char PrinterName
[256];
1592 GetDlgItemTextA(hDlg
, PrinterComboID
, PrinterName
, 255);
1593 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
1594 FIXME(" Call to OpenPrinter did not succeed!\n");
1597 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
,
1598 PrintStructures
->lpDevMode
,
1599 PrintStructures
->lpDevMode
,
1600 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1601 ClosePrinter(hPrinter
);
1605 case rad1
: /* Paperorientation */
1606 if (lppd
->Flags
& PD_PRINTSETUP
)
1608 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1609 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1610 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1614 case rad2
: /* Paperorientation */
1615 if (lppd
->Flags
& PD_PRINTSETUP
)
1617 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1618 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1619 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1623 case cmb1
: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
1624 if (PrinterComboID
!= LOWORD(wParam
)) {
1628 case cmb4
: /* Printer combobox */
1629 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1630 char PrinterName
[256];
1631 GetDlgItemTextA(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1632 PRINTDLG_ChangePrinterA(hDlg
, PrinterName
, PrintStructures
);
1636 case cmb2
: /* Papersize */
1638 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1640 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageA(hDlg
, cmb2
,
1646 case cmb3
: /* Bin */
1648 DWORD Sel
= SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1650 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,
1651 CB_GETITEMDATA
, Sel
,
1656 if(lppd
->Flags
& PD_PRINTSETUP
) {
1657 switch (LOWORD(wParam
)) {
1658 case rad1
: /* orientation */
1660 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1661 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1662 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1663 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1665 (LPARAM
)PrintStructures
->hPortraitIcon
);
1666 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1668 (LPARAM
)PrintStructures
->hPortraitIcon
);
1671 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1672 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1673 SendDlgItemMessageA(hDlg
, stc10
, STM_SETIMAGE
,
1675 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1676 SendDlgItemMessageA(hDlg
, ico1
, STM_SETIMAGE
,
1678 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1687 static LRESULT
PRINTDLG_WMCommandW(HWND hDlg
, WPARAM wParam
,
1688 LPARAM lParam
, PRINT_PTRW
* PrintStructures
)
1690 LPPRINTDLGW lppd
= PrintStructures
->lpPrintDlg
;
1691 UINT PrinterComboID
= (lppd
->Flags
& PD_PRINTSETUP
) ? cmb1
: cmb4
;
1692 LPDEVMODEW lpdm
= PrintStructures
->lpDevMode
;
1694 switch (LOWORD(wParam
)) {
1696 TRACE(" OK button was hit\n");
1697 if (!PRINTDLG_UpdatePrintDlgW(hDlg
, PrintStructures
)) {
1698 FIXME("Update printdlg was not successful!\n");
1701 EndDialog(hDlg
, TRUE
);
1705 TRACE(" CANCEL button was hit\n");
1706 EndDialog(hDlg
, FALSE
);
1710 TRACE(" HELP button was hit\n");
1711 SendMessageW(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
1712 (WPARAM
) hDlg
, (LPARAM
) lppd
);
1715 case chx2
: /* collate pages checkbox */
1716 if (IsDlgButtonChecked(hDlg
, chx2
) == BST_CHECKED
)
1717 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1718 (LPARAM
)PrintStructures
->hCollateIcon
);
1720 SendDlgItemMessageW(hDlg
, ico3
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1721 (LPARAM
)PrintStructures
->hNoCollateIcon
);
1723 case edt1
: /* from page nr editbox */
1724 case edt2
: /* to page nr editbox */
1725 if (HIWORD(wParam
)==EN_CHANGE
) {
1728 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
1729 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
1730 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
1731 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
1736 if(HIWORD(wParam
) == EN_CHANGE
) {
1737 INT copies
= GetDlgItemInt(hDlg
, edt3
, NULL
, FALSE
);
1739 EnableWindow(GetDlgItem(hDlg
, chx2
), FALSE
);
1741 EnableWindow(GetDlgItem(hDlg
, chx2
), TRUE
);
1745 case psh1
: /* Print Setup */
1747 ERR("psh1 is called from 16bit code only, we should not get here.\n");
1750 case psh2
: /* Properties button */
1753 WCHAR PrinterName
[256];
1755 if (!GetDlgItemTextW(hDlg
, PrinterComboID
, PrinterName
, 255)) break;
1756 if (!OpenPrinterW(PrinterName
, &hPrinter
, NULL
)) {
1757 FIXME(" Call to OpenPrinter did not succeed!\n");
1760 DocumentPropertiesW(hDlg
, hPrinter
, PrinterName
,
1761 PrintStructures
->lpDevMode
,
1762 PrintStructures
->lpDevMode
,
1763 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
1764 ClosePrinter(hPrinter
);
1768 case rad1
: /* Paperorientation */
1769 if (lppd
->Flags
& PD_PRINTSETUP
)
1771 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1772 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1773 (LPARAM
)(PrintStructures
->hPortraitIcon
));
1777 case rad2
: /* Paperorientation */
1778 if (lppd
->Flags
& PD_PRINTSETUP
)
1780 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1781 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
, (WPARAM
) IMAGE_ICON
,
1782 (LPARAM
)(PrintStructures
->hLandscapeIcon
));
1786 case cmb1
: /* Printer Combobox in PRINT SETUP */
1788 case cmb4
: /* Printer combobox */
1789 if (HIWORD(wParam
)==CBN_SELCHANGE
) {
1790 WCHAR PrinterName
[256];
1791 GetDlgItemTextW(hDlg
, LOWORD(wParam
), PrinterName
, 255);
1792 PRINTDLG_ChangePrinterW(hDlg
, PrinterName
, PrintStructures
);
1796 case cmb2
: /* Papersize */
1798 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
1800 lpdm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
,
1806 case cmb3
: /* Bin */
1808 DWORD Sel
= SendDlgItemMessageW(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0);
1810 lpdm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageW(hDlg
, cmb3
,
1811 CB_GETITEMDATA
, Sel
,
1816 if(lppd
->Flags
& PD_PRINTSETUP
) {
1817 switch (LOWORD(wParam
)) {
1818 case rad1
: /* orientation */
1820 if (IsDlgButtonChecked(hDlg
, rad1
) == BST_CHECKED
) {
1821 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_PORTRAIT
) {
1822 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
1823 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1825 (LPARAM
)PrintStructures
->hPortraitIcon
);
1826 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1828 (LPARAM
)PrintStructures
->hPortraitIcon
);
1831 if(lpdm
->u1
.s1
.dmOrientation
!= DMORIENT_LANDSCAPE
) {
1832 lpdm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
1833 SendDlgItemMessageW(hDlg
, stc10
, STM_SETIMAGE
,
1835 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1836 SendDlgItemMessageW(hDlg
, ico1
, STM_SETIMAGE
,
1838 (LPARAM
)PrintStructures
->hLandscapeIcon
);
1847 /***********************************************************************
1848 * PrintDlgProcA [internal]
1850 static INT_PTR CALLBACK
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1853 PRINT_PTRA
* PrintStructures
;
1854 INT_PTR res
= FALSE
;
1856 if (uMsg
!=WM_INITDIALOG
) {
1857 PrintStructures
= GetPropA(hDlg
,"__WINE_PRINTDLGDATA");
1858 if (!PrintStructures
)
1861 PrintStructures
= (PRINT_PTRA
*) lParam
;
1862 SetPropA(hDlg
,"__WINE_PRINTDLGDATA",PrintStructures
);
1863 if(!check_printer_setup(hDlg
))
1865 EndDialog(hDlg
,FALSE
);
1868 res
= PRINTDLG_WMInitDialog(hDlg
, wParam
, PrintStructures
);
1870 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1871 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(
1872 hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
1877 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1878 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
,
1885 return PRINTDLG_WMCommandA(hDlg
, wParam
, lParam
, PrintStructures
);
1888 DestroyIcon(PrintStructures
->hCollateIcon
);
1889 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1890 DestroyIcon(PrintStructures
->hPortraitIcon
);
1891 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1892 if(PrintStructures
->hwndUpDown
)
1893 DestroyWindow(PrintStructures
->hwndUpDown
);
1899 static INT_PTR CALLBACK
PrintDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
1902 PRINT_PTRW
* PrintStructures
;
1903 INT_PTR res
= FALSE
;
1905 if (uMsg
!=WM_INITDIALOG
) {
1906 PrintStructures
= GetPropW(hDlg
, propW
);
1907 if (!PrintStructures
)
1910 PrintStructures
= (PRINT_PTRW
*) lParam
;
1911 SetPropW(hDlg
, propW
, PrintStructures
);
1912 if(!check_printer_setup(hDlg
))
1914 EndDialog(hDlg
,FALSE
);
1917 res
= PRINTDLG_WMInitDialogW(hDlg
, wParam
, PrintStructures
);
1919 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
)
1920 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
, uMsg
, wParam
, (LPARAM
)PrintStructures
->lpPrintDlg
);
1924 if(PrintStructures
->lpPrintDlg
->Flags
& PD_ENABLEPRINTHOOK
) {
1925 res
= PrintStructures
->lpPrintDlg
->lpfnPrintHook(hDlg
,uMsg
,wParam
, lParam
);
1931 return PRINTDLG_WMCommandW(hDlg
, wParam
, lParam
, PrintStructures
);
1934 DestroyIcon(PrintStructures
->hCollateIcon
);
1935 DestroyIcon(PrintStructures
->hNoCollateIcon
);
1936 DestroyIcon(PrintStructures
->hPortraitIcon
);
1937 DestroyIcon(PrintStructures
->hLandscapeIcon
);
1938 if(PrintStructures
->hwndUpDown
)
1939 DestroyWindow(PrintStructures
->hwndUpDown
);
1945 /************************************************************
1947 * PRINTDLG_GetDlgTemplate
1950 static HGLOBAL
PRINTDLG_GetDlgTemplateA(const PRINTDLGA
*lppd
)
1955 if (lppd
->Flags
& PD_PRINTSETUP
) {
1956 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1957 hDlgTmpl
= lppd
->hSetupTemplate
;
1958 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1959 hResInfo
= FindResourceA(lppd
->hInstance
,
1960 lppd
->lpSetupTemplateName
, (LPSTR
)RT_DIALOG
);
1961 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1963 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32_SETUP",
1965 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1968 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
1969 hDlgTmpl
= lppd
->hPrintTemplate
;
1970 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
1971 hResInfo
= FindResourceA(lppd
->hInstance
,
1972 lppd
->lpPrintTemplateName
,
1974 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1976 hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32",
1978 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
1984 static HGLOBAL
PRINTDLG_GetDlgTemplateW(const PRINTDLGW
*lppd
)
1988 static const WCHAR xpsetup
[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
1989 static const WCHAR xprint
[] = { 'P','R','I','N','T','3','2',0};
1991 if (lppd
->Flags
& PD_PRINTSETUP
) {
1992 if(lppd
->Flags
& PD_ENABLESETUPTEMPLATEHANDLE
) {
1993 hDlgTmpl
= lppd
->hSetupTemplate
;
1994 } else if(lppd
->Flags
& PD_ENABLESETUPTEMPLATE
) {
1995 hResInfo
= FindResourceW(lppd
->hInstance
,
1996 lppd
->lpSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
1997 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
1999 hResInfo
= FindResourceW(COMDLG32_hInstance
, xpsetup
, (LPWSTR
)RT_DIALOG
);
2000 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2003 if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATEHANDLE
) {
2004 hDlgTmpl
= lppd
->hPrintTemplate
;
2005 } else if(lppd
->Flags
& PD_ENABLEPRINTTEMPLATE
) {
2006 hResInfo
= FindResourceW(lppd
->hInstance
,
2007 lppd
->lpPrintTemplateName
,
2009 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2011 hResInfo
= FindResourceW(COMDLG32_hInstance
, xprint
, (LPWSTR
)RT_DIALOG
);
2012 hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
);
2018 /***********************************************************************
2023 static BOOL
PRINTDLG_CreateDCA(LPPRINTDLGA lppd
)
2025 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2026 DEVMODEA
*pdm
= GlobalLock(lppd
->hDevMode
);
2028 if(lppd
->Flags
& PD_RETURNDC
) {
2029 lppd
->hDC
= CreateDCA((char*)pdn
+ pdn
->wDriverOffset
,
2030 (char*)pdn
+ pdn
->wDeviceOffset
,
2031 (char*)pdn
+ pdn
->wOutputOffset
,
2033 } else if(lppd
->Flags
& PD_RETURNIC
) {
2034 lppd
->hDC
= CreateICA((char*)pdn
+ pdn
->wDriverOffset
,
2035 (char*)pdn
+ pdn
->wDeviceOffset
,
2036 (char*)pdn
+ pdn
->wOutputOffset
,
2039 GlobalUnlock(lppd
->hDevNames
);
2040 GlobalUnlock(lppd
->hDevMode
);
2041 return lppd
->hDC
? TRUE
: FALSE
;
2044 static BOOL
PRINTDLG_CreateDCW(LPPRINTDLGW lppd
)
2046 DEVNAMES
*pdn
= GlobalLock(lppd
->hDevNames
);
2047 DEVMODEW
*pdm
= GlobalLock(lppd
->hDevMode
);
2049 if(lppd
->Flags
& PD_RETURNDC
) {
2050 lppd
->hDC
= CreateDCW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2051 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2052 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2054 } else if(lppd
->Flags
& PD_RETURNIC
) {
2055 lppd
->hDC
= CreateICW((WCHAR
*)pdn
+ pdn
->wDriverOffset
,
2056 (WCHAR
*)pdn
+ pdn
->wDeviceOffset
,
2057 (WCHAR
*)pdn
+ pdn
->wOutputOffset
,
2060 GlobalUnlock(lppd
->hDevNames
);
2061 GlobalUnlock(lppd
->hDevMode
);
2062 return lppd
->hDC
? TRUE
: FALSE
;
2065 /***********************************************************************
2066 * PrintDlgA (COMDLG32.@)
2068 * Displays the PRINT dialog box, which enables the user to specify
2069 * specific properties of the print job.
2072 * lppd [IO] ptr to PRINTDLG32 struct
2075 * nonzero if the user pressed the OK button
2076 * zero if the user cancelled the window or an error occurred
2080 * * The Collate Icons do not display, even though they are in the code.
2081 * * The Properties Button(s) should call DocumentPropertiesA().
2084 BOOL WINAPI
PrintDlgA(LPPRINTDLGA lppd
)
2092 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2096 hInst
= (HINSTANCE
)GetWindowLongPtrA( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2097 if(TRACE_ON(commdlg
)) {
2098 char flagstr
[1000] = "";
2099 const struct pd_flags
*pflag
= pd_flags
;
2100 for( ; pflag
->name
; pflag
++) {
2101 if(lppd
->Flags
& pflag
->flag
)
2102 strcat(flagstr
, pflag
->name
);
2104 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2105 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2106 "flags %08x (%s)\n",
2107 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2108 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2109 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2112 if(lppd
->lStructSize
!= sizeof(PRINTDLGA
)) {
2113 WARN("structure size failure !!!\n");
2114 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2118 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2119 PRINTER_INFO_2A
*pbuf
;
2120 DRIVER_INFO_3A
*dbuf
;
2124 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2125 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2126 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2129 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2130 WARN("Can't find default printer\n");
2131 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2135 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2136 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2137 GetPrinterA(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2139 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2140 dbuf
= HeapAlloc(GetProcessHeap(),0,needed
);
2141 if (!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2142 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2143 GetLastError(),pbuf
->pPrinterName
);
2144 HeapFree(GetProcessHeap(), 0, dbuf
);
2145 HeapFree(GetProcessHeap(), 0, pbuf
);
2146 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2151 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2155 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2156 pbuf
->pDevMode
->dmDriverExtra
);
2157 ptr
= GlobalLock(lppd
->hDevMode
);
2158 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2159 pbuf
->pDevMode
->dmDriverExtra
);
2160 GlobalUnlock(lppd
->hDevMode
);
2161 HeapFree(GetProcessHeap(), 0, pbuf
);
2162 HeapFree(GetProcessHeap(), 0, dbuf
);
2166 PRINT_PTRA
*PrintStructures
;
2168 /* load Dialog resources,
2169 * depending on Flags indicates Print32 or Print32_setup dialog
2171 hDlgTmpl
= PRINTDLG_GetDlgTemplateA(lppd
);
2173 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2176 ptr
= LockResource( hDlgTmpl
);
2178 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2182 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2183 sizeof(PRINT_PTRA
));
2184 PrintStructures
->lpPrintDlg
= lppd
;
2186 /* and create & process the dialog .
2187 * -1 is failure, 0 is broken hwnd, everything else is ok.
2189 bRet
= (0<DialogBoxIndirectParamA(hInst
, ptr
, lppd
->hwndOwner
,
2191 (LPARAM
)PrintStructures
));
2194 DEVMODEA
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2195 PRINTER_INFO_2A
*pi
= PrintStructures
->lpPrinterInfo
;
2196 DRIVER_INFO_3A
*di
= PrintStructures
->lpDriverInfo
;
2198 if (lppd
->hDevMode
== 0) {
2199 TRACE(" No hDevMode yet... Need to create my own\n");
2200 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2201 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2203 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2204 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2207 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2208 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2210 PRINTDLG_CreateDevNames(&(lppd
->hDevNames
),
2215 GlobalUnlock(lppd
->hDevMode
);
2217 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2218 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2219 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2220 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2222 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2223 bRet
= PRINTDLG_CreateDCA(lppd
);
2225 TRACE("exit! (%d)\n", bRet
);
2229 /***********************************************************************
2230 * PrintDlgW (COMDLG32.@)
2234 BOOL WINAPI
PrintDlgW(LPPRINTDLGW lppd
)
2242 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
2246 hInst
= (HINSTANCE
)GetWindowLongPtrW( lppd
->hwndOwner
, GWLP_HINSTANCE
);
2247 if(TRACE_ON(commdlg
)) {
2248 char flagstr
[1000] = "";
2249 const struct pd_flags
*pflag
= pd_flags
;
2250 for( ; pflag
->name
; pflag
++) {
2251 if(lppd
->Flags
& pflag
->flag
)
2252 strcat(flagstr
, pflag
->name
);
2254 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
2255 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
2256 "flags %08x (%s)\n",
2257 lppd
, lppd
->hwndOwner
, lppd
->hDevMode
, lppd
->hDevNames
,
2258 lppd
->nFromPage
, lppd
->nToPage
, lppd
->nMinPage
, lppd
->nMaxPage
,
2259 lppd
->nCopies
, lppd
->hInstance
, lppd
->Flags
, flagstr
);
2262 if(lppd
->lStructSize
!= sizeof(PRINTDLGW
)) {
2263 WARN("structure size failure !!!\n");
2264 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
2268 if(lppd
->Flags
& PD_RETURNDEFAULT
) {
2269 PRINTER_INFO_2W
*pbuf
;
2270 DRIVER_INFO_3W
*dbuf
;
2274 if(lppd
->hDevMode
|| lppd
->hDevNames
) {
2275 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
2276 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2279 if(!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
2280 WARN("Can't find default printer\n");
2281 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
2285 GetPrinterW(hprn
, 2, NULL
, 0, &needed
);
2286 pbuf
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*needed
);
2287 GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
2289 GetPrinterDriverW(hprn
, NULL
, 3, NULL
, 0, &needed
);
2290 dbuf
= HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR
)*needed
);
2291 if (!GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
)) {
2292 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
2293 GetLastError(),debugstr_w(pbuf
->pPrinterName
));
2294 HeapFree(GetProcessHeap(), 0, dbuf
);
2295 HeapFree(GetProcessHeap(), 0, pbuf
);
2296 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
2301 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2305 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
2306 pbuf
->pDevMode
->dmDriverExtra
);
2307 ptr
= GlobalLock(lppd
->hDevMode
);
2308 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
2309 pbuf
->pDevMode
->dmDriverExtra
);
2310 GlobalUnlock(lppd
->hDevMode
);
2311 HeapFree(GetProcessHeap(), 0, pbuf
);
2312 HeapFree(GetProcessHeap(), 0, dbuf
);
2316 PRINT_PTRW
*PrintStructures
;
2318 /* load Dialog resources,
2319 * depending on Flags indicates Print32 or Print32_setup dialog
2321 hDlgTmpl
= PRINTDLG_GetDlgTemplateW(lppd
);
2323 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2326 ptr
= LockResource( hDlgTmpl
);
2328 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
2332 PrintStructures
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2333 sizeof(PRINT_PTRW
));
2334 PrintStructures
->lpPrintDlg
= lppd
;
2336 /* and create & process the dialog .
2337 * -1 is failure, 0 is broken hwnd, everything else is ok.
2339 bRet
= (0<DialogBoxIndirectParamW(hInst
, ptr
, lppd
->hwndOwner
,
2341 (LPARAM
)PrintStructures
));
2344 DEVMODEW
*lpdm
= PrintStructures
->lpDevMode
, *lpdmReturn
;
2345 PRINTER_INFO_2W
*pi
= PrintStructures
->lpPrinterInfo
;
2346 DRIVER_INFO_3W
*di
= PrintStructures
->lpDriverInfo
;
2348 if (lppd
->hDevMode
== 0) {
2349 TRACE(" No hDevMode yet... Need to create my own\n");
2350 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
,
2351 lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2354 if((locks
= (GlobalFlags(lppd
->hDevMode
) & GMEM_LOCKCOUNT
))) {
2355 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks
);
2357 GlobalUnlock(lppd
->hDevMode
);
2358 TRACE("Now got %d locks\n", locks
);
2361 lppd
->hDevMode
= GlobalReAlloc(lppd
->hDevMode
,
2362 lpdm
->dmSize
+ lpdm
->dmDriverExtra
,
2365 lpdmReturn
= GlobalLock(lppd
->hDevMode
);
2366 memcpy(lpdmReturn
, lpdm
, lpdm
->dmSize
+ lpdm
->dmDriverExtra
);
2368 if (lppd
->hDevNames
!= 0) {
2370 if((locks
= (GlobalFlags(lppd
->hDevNames
) & GMEM_LOCKCOUNT
))) {
2371 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks
);
2373 GlobalUnlock(lppd
->hDevNames
);
2376 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
2381 GlobalUnlock(lppd
->hDevMode
);
2383 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDevMode
);
2384 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpPrinterInfo
);
2385 HeapFree(GetProcessHeap(), 0, PrintStructures
->lpDriverInfo
);
2386 HeapFree(GetProcessHeap(), 0, PrintStructures
);
2388 if(bRet
&& (lppd
->Flags
& PD_RETURNDC
|| lppd
->Flags
& PD_RETURNIC
))
2389 bRet
= PRINTDLG_CreateDCW(lppd
);
2391 TRACE("exit! (%d)\n", bRet
);
2395 /***********************************************************************
2400 * cmb1 - printer select (not in standard dialog template)
2402 * cmb3 - source (tray?)
2403 * edt4 - border left
2405 * edt6 - border right
2406 * edt7 - border bottom
2407 * psh3 - "Printer..."
2411 LPPAGESETUPDLGA dlga
; /* Handler to user defined struct */
2413 HWND hDlg
; /* Page Setup dialog handler */
2414 PAGESETUPDLGA curdlg
; /* Stores the current dialog state */
2415 RECT rtDrawRect
; /* Drawing rect for page */
2419 LPPAGESETUPDLGW dlgw
;
2421 PAGESETUPDLGW curdlg
; /* Current dialog state */
2425 static HGLOBAL
PRINTDLG_GetPGSTemplateA(const PAGESETUPDLGA
*lppd
)
2430 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2431 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2432 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2433 hResInfo
= FindResourceA(lppd
->hInstance
,
2434 lppd
->lpPageSetupTemplateName
, (LPSTR
)RT_DIALOG
);
2435 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2437 hResInfo
= FindResourceA(COMDLG32_hInstance
,(LPCSTR
)PAGESETUPDLGORD
,(LPSTR
)RT_DIALOG
);
2438 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2443 static HGLOBAL
PRINTDLG_GetPGSTemplateW(const PAGESETUPDLGW
*lppd
)
2448 if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATEHANDLE
) {
2449 hDlgTmpl
= lppd
->hPageSetupTemplate
;
2450 } else if(lppd
->Flags
& PSD_ENABLEPAGESETUPTEMPLATE
) {
2451 hResInfo
= FindResourceW(lppd
->hInstance
,
2452 lppd
->lpPageSetupTemplateName
, (LPWSTR
)RT_DIALOG
);
2453 hDlgTmpl
= LoadResource(lppd
->hInstance
, hResInfo
);
2455 hResInfo
= FindResourceW(COMDLG32_hInstance
,(LPCWSTR
)PAGESETUPDLGORD
,(LPWSTR
)RT_DIALOG
);
2456 hDlgTmpl
= LoadResource(COMDLG32_hInstance
,hResInfo
);
2462 _c_10mm2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2463 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2464 return 10*size
*100/254;
2465 /* If we don't have a flag, we can choose one. Use millimeters
2466 * to avoid confusing me
2468 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2474 _c_inch2size(PAGESETUPDLGA
*dlga
,DWORD size
) {
2475 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2477 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2478 return (size
*254)/100;
2479 /* if we don't have a flag, we can choose one. Use millimeters
2480 * to avoid confusing me
2482 dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2483 return (size
*254)/100;
2487 _c_size2strA(PageSetupDataA
*pda
,DWORD size
,LPSTR strout
) {
2488 strcpy(strout
,"<undef>");
2489 if (pda
->dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2490 sprintf(strout
,"%d",(size
)/100);
2493 if (pda
->dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2494 sprintf(strout
,"%din",(size
)/1000);
2497 pda
->dlga
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2498 sprintf(strout
,"%d",(size
)/100);
2502 _c_size2strW(PageSetupDataW
*pdw
,DWORD size
,LPWSTR strout
) {
2503 static const char mm_fmt
[] = "%.2f mm";
2504 static const char in_fmt
[] = "%.2f in";
2506 if (pdw
->dlgw
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2507 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2508 } else if (pdw
->dlgw
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2509 sprintf(buf
, in_fmt
, (size
* 1.0) / 1000.0);
2511 pdw
->dlgw
->Flags
|= PSD_INHUNDREDTHSOFMILLIMETERS
;
2512 sprintf(buf
, mm_fmt
, (size
* 1.0) / 100.0);
2515 MultiByteToWideChar(CP_ACP
, 0, buf
, -1, strout
, 20);
2519 _c_str2sizeA(const PAGESETUPDLGA
*dlga
, LPCSTR strin
) {
2524 if (!sscanf(strin
,"%f%s",&val
,rest
))
2527 if (!strcmp(rest
,"in") || !strcmp(rest
,"inch")) {
2528 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
)
2531 return val
*25.4*100;
2533 if (!strcmp(rest
,"cm")) { rest
[0]='m'; val
= val
*10.0; }
2534 if (!strcmp(rest
,"m")) { strcpy(rest
,"mm"); val
= val
*1000.0; }
2536 if (!strcmp(rest
,"mm")) {
2537 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
)
2540 return 1000.0*val
/25.4;
2542 if (rest
[0]=='\0') {
2543 /* use application supplied default */
2544 if (dlga
->Flags
& PSD_INHUNDREDTHSOFMILLIMETERS
) {
2548 if (dlga
->Flags
& PSD_INTHOUSANDTHSOFINCHES
) {
2553 ERR("Did not find a conversion for type '%s'!\n",rest
);
2559 _c_str2sizeW(const PAGESETUPDLGW
*dlga
, LPCWSTR strin
) {
2562 /* this W -> A transition is OK */
2563 /* we need a unicode version of sscanf to avoid it */
2564 WideCharToMultiByte(CP_ACP
, 0, strin
, -1, buf
, sizeof(buf
), NULL
, NULL
);
2565 return _c_str2sizeA((const PAGESETUPDLGA
*)dlga
, buf
);
2569 /****************************************************************************
2570 * PRINTDLG_PS_UpdateDlgStructA
2572 * Updates pda->dlga structure
2573 * Function calls when user presses OK button
2576 * hDlg [in] main window dialog HANDLE
2577 * pda [in/out] ptr to PageSetupDataA structure
2583 PRINTDLG_PS_UpdateDlgStructA(HWND hDlg
, PageSetupDataA
*pda
) {
2587 memcpy(pda
->dlga
, &pda
->curdlg
, sizeof(pda
->curdlg
));
2588 pda
->dlga
->hDevMode
= pda
->pdlg
.hDevMode
;
2589 pda
->dlga
->hDevNames
= pda
->pdlg
.hDevNames
;
2591 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2593 /* Save paper orientation into device context */
2594 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
)
2595 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2597 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2599 /* Save paper size into the device context */
2600 paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2601 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2602 if (paperword
!= CB_ERR
)
2603 dm
->u1
.s1
.dmPaperSize
= paperword
;
2605 FIXME("could not get dialog text for papersize cmbbox?\n");
2607 /* Save paper source into the device context */
2608 paperword
= SendDlgItemMessageA(hDlg
,cmb1
,CB_GETITEMDATA
,
2609 SendDlgItemMessageA(hDlg
, cmb1
, CB_GETCURSEL
, 0, 0), 0);
2610 if (paperword
!= CB_ERR
)
2611 dm
->u1
.s1
.dmDefaultSource
= paperword
;
2613 FIXME("could not get dialog text for papersize cmbbox?\n");
2615 GlobalUnlock(pda
->pdlg
.hDevMode
);
2621 PRINTDLG_PS_UpdateDlgStructW(HWND hDlg
, PageSetupDataW
*pdw
) {
2624 LPWSTR devname
,portname
;
2625 WCHAR papername
[64];
2628 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2629 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2630 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2631 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2633 /* Save paper size into device context */
2634 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2635 /* Save paper source into device context */
2636 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2638 if (GetDlgItemTextW(hDlg
,cmb2
,papername
,sizeof(papername
)/sizeof(papername
[0]))>0) {
2639 PRINTDLG_PaperSizeW(&(pdw
->pdlg
),papername
,&(pdw
->dlgw
->ptPaperSize
));
2640 pdw
->dlgw
->ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.x
);
2641 pdw
->dlgw
->ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
,pdw
->dlgw
->ptPaperSize
.y
);
2643 FIXME("could not get dialog text for papersize cmbbox?\n");
2644 #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); }
2645 GETVAL(edt4
,pdw
->dlgw
->rtMargin
.left
);
2646 GETVAL(edt5
,pdw
->dlgw
->rtMargin
.top
);
2647 GETVAL(edt6
,pdw
->dlgw
->rtMargin
.right
);
2648 GETVAL(edt7
,pdw
->dlgw
->rtMargin
.bottom
);
2651 /* If we are in landscape, swap x and y of page size */
2652 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2654 tmp
= pdw
->dlgw
->ptPaperSize
.x
;
2655 pdw
->dlgw
->ptPaperSize
.x
= pdw
->dlgw
->ptPaperSize
.y
;
2656 pdw
->dlgw
->ptPaperSize
.y
= tmp
;
2659 /* Save orientation */
2660 if (pdw
->dlgw
->ptPaperSize
.x
> pdw
->dlgw
->ptPaperSize
.y
)
2661 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2663 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2665 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2666 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2670 /**********************************************************************************************
2671 * PRINTDLG_PS_ChangeActivePrinerA
2673 * Redefines hDevMode and hDevNames HANDLES and initialises it.
2676 * name [in] Name of a printer for activation
2677 * pda [in/out] ptr to PageSetupDataA structure
2684 PRINTDLG_PS_ChangeActivePrinterA(LPSTR name
, PageSetupDataA
*pda
){
2687 LPPRINTER_INFO_2A lpPrinterInfo
;
2688 LPDRIVER_INFO_3A lpDriverInfo
;
2689 DEVMODEA
*pDevMode
, *dm
;
2691 if(!OpenPrinterA(name
, &hprn
, NULL
)){
2692 ERR("Can't open printer %s\n", name
);
2695 GetPrinterA(hprn
, 2, NULL
, 0, &needed
);
2696 lpPrinterInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2697 GetPrinterA(hprn
, 2, (LPBYTE
)lpPrinterInfo
, needed
, &needed
);
2698 GetPrinterDriverA(hprn
, NULL
, 3, NULL
, 0, &needed
);
2699 lpDriverInfo
= HeapAlloc(GetProcessHeap(), 0, needed
);
2700 if(!GetPrinterDriverA(hprn
, NULL
, 3, (LPBYTE
)lpDriverInfo
, needed
, &needed
)) {
2701 ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo
->pPrinterName
);
2702 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2703 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2708 needed
= DocumentPropertiesA(0, 0, name
, NULL
, NULL
, 0);
2710 ERR("DocumentProperties fails on %s\n", debugstr_a(name
));
2711 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2712 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2715 pDevMode
= HeapAlloc(GetProcessHeap(), 0, needed
);
2716 DocumentPropertiesA(0, 0, name
, pDevMode
, NULL
, DM_OUT_BUFFER
);
2718 pda
->pdlg
.hDevMode
= GlobalReAlloc(pda
->pdlg
.hDevMode
,
2719 pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
,
2721 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2722 memcpy(dm
, pDevMode
, pDevMode
->dmSize
+ pDevMode
->dmDriverExtra
);
2724 PRINTDLG_CreateDevNames(&(pda
->pdlg
.hDevNames
),
2725 lpDriverInfo
->pDriverPath
,
2726 lpPrinterInfo
->pPrinterName
,
2727 lpPrinterInfo
->pPortName
);
2729 GlobalUnlock(pda
->pdlg
.hDevMode
);
2730 HeapFree(GetProcessHeap(), 0, pDevMode
);
2731 HeapFree(GetProcessHeap(), 0, lpPrinterInfo
);
2732 HeapFree(GetProcessHeap(), 0, lpDriverInfo
);
2736 /****************************************************************************************
2737 * PRINTDLG_PS_ChangePrinterA
2739 * Fills Printers, Paper and Source combo
2745 PRINTDLG_PS_ChangePrinterA(HWND hDlg
, PageSetupDataA
*pda
) {
2748 LPSTR devname
,portname
;
2750 dn
= GlobalLock(pda
->pdlg
.hDevNames
);
2751 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2752 devname
= ((char*)dn
)+dn
->wDeviceOffset
;
2753 portname
= ((char*)dn
)+dn
->wOutputOffset
;
2754 PRINTDLG_SetUpPrinterListComboA(hDlg
, cmb1
, devname
);
2755 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb2
,devname
,portname
,dm
);
2756 PRINTDLG_SetUpPaperComboBoxA(hDlg
,cmb3
,devname
,portname
,dm
);
2757 GlobalUnlock(pda
->pdlg
.hDevNames
);
2758 GlobalUnlock(pda
->pdlg
.hDevMode
);
2762 static void PRINTDLG_PS_SetOrientationW(HWND hDlg
, PageSetupDataW
* pdw
)
2764 WCHAR PaperName
[64];
2766 GetDlgItemTextW(hDlg
, cmb2
, PaperName
, sizeof(PaperName
)/sizeof(WCHAR
));
2767 PRINTDLG_PaperSizeW(&pdw
->pdlg
, PaperName
, &pdw
->curdlg
.ptPaperSize
);
2768 pdw
->curdlg
.ptPaperSize
.x
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.x
);
2769 pdw
->curdlg
.ptPaperSize
.y
= _c_10mm2size((LPPAGESETUPDLGA
)pdw
->dlgw
, pdw
->curdlg
.ptPaperSize
.y
);
2771 if(IsDlgButtonChecked(hDlg
, rad2
))
2773 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.x
;
2774 pdw
->curdlg
.ptPaperSize
.x
= pdw
->curdlg
.ptPaperSize
.y
;
2775 pdw
->curdlg
.ptPaperSize
.y
= tmp
;
2779 static void PRINTDLG_PS_UpdatePrintDlgW(PageSetupDataW
* pdw
, HWND hDlg
)
2784 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2789 if(pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
)
2790 dm
->u1
.s1
.dmOrientation
= DMORIENT_PORTRAIT
;
2792 dm
->u1
.s1
.dmOrientation
= DMORIENT_LANDSCAPE
;
2794 sel
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0);
2797 dm
->u1
.s1
.dmPaperSize
= SendDlgItemMessageW(hDlg
, cmb2
, CB_GETITEMDATA
, sel
, 0);
2799 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2803 PRINTDLG_PS_ChangePrinterW(HWND hDlg
, PageSetupDataW
*pdw
) {
2806 LPWSTR devname
,portname
;
2808 dn
= GlobalLock(pdw
->pdlg
.hDevNames
);
2809 dm
= GlobalLock(pdw
->pdlg
.hDevMode
);
2810 devname
= ((WCHAR
*)dn
)+dn
->wDeviceOffset
;
2811 portname
= ((WCHAR
*)dn
)+dn
->wOutputOffset
;
2812 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb2
,devname
,portname
,dm
);
2813 PRINTDLG_SetUpPaperComboBoxW(hDlg
,cmb3
,devname
,portname
,dm
);
2815 /* Landscape orientation */
2816 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
2817 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
2818 else /* this is default if papersize is not set */
2819 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
2821 GlobalUnlock(pdw
->pdlg
.hDevNames
);
2822 GlobalUnlock(pdw
->pdlg
.hDevMode
);
2824 PRINTDLG_PS_SetOrientationW(hDlg
, pdw
);
2829 /******************************************************************************************
2830 * PRINTDLG_PS_ChangePaperPrev
2832 * Changes paper preview size / position
2835 * pda [i] Pointer for current PageSetupDataA structure
2841 PRINTDLG_PS_ChangePaperPrev(const PageSetupDataA
*pda
)
2843 LONG width
, height
, x
, y
;
2846 if(pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) {
2847 width
= pda
->rtDrawRect
.right
- pda
->rtDrawRect
.left
;
2848 height
= pda
->curdlg
.ptPaperSize
.y
* width
/ pda
->curdlg
.ptPaperSize
.x
;
2850 height
= pda
->rtDrawRect
.bottom
- pda
->rtDrawRect
.top
;
2851 width
= pda
->curdlg
.ptPaperSize
.x
* height
/ pda
->curdlg
.ptPaperSize
.y
;
2853 x
= (pda
->rtDrawRect
.right
+ pda
->rtDrawRect
.left
- width
) / 2;
2854 y
= (pda
->rtDrawRect
.bottom
+ pda
->rtDrawRect
.top
- height
) / 2;
2855 TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n",
2856 pda
->rtDrawRect
.left
, pda
->rtDrawRect
.top
, pda
->rtDrawRect
.right
, pda
->rtDrawRect
.bottom
,
2857 x
, y
, width
, height
);
2860 MoveWindow(GetDlgItem(pda
->hDlg
, rct2
), x
+width
, y
+SHADOW
, SHADOW
, height
, FALSE
);
2861 MoveWindow(GetDlgItem(pda
->hDlg
, rct3
), x
+SHADOW
, y
+height
, width
, SHADOW
, FALSE
);
2862 MoveWindow(GetDlgItem(pda
->hDlg
, rct1
), x
, y
, width
, height
, FALSE
);
2863 rtTmp
= pda
->rtDrawRect
;
2864 rtTmp
.right
+= SHADOW
;
2865 rtTmp
.bottom
+= SHADOW
;
2868 InvalidateRect(pda
->hDlg
, &rtTmp
, TRUE
);
2872 #define GETVAL(idc,val) \
2873 if(msg == EN_CHANGE){ \
2874 if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\
2875 val = _c_str2sizeA(pda->dlga,buf); \
2877 FIXME("could not get dlgitemtexta for %x\n",id); \
2880 /********************************************************************************
2881 * PRINTDLG_PS_WMCommandA
2882 * process WM_COMMAND message for PageSetupDlgA
2885 * hDlg [in] Main dialog HANDLE
2886 * wParam [in] WM_COMMAND wParam
2887 * lParam [in] WM_COMMAND lParam
2888 * pda [in/out] ptr to PageSetupDataA
2892 PRINTDLG_PS_WMCommandA(
2893 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataA
*pda
2895 WORD msg
= HIWORD(wParam
);
2896 WORD id
= LOWORD(wParam
);
2899 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
2900 LOWORD(lParam
),wParam
,lParam
);
2903 if (!PRINTDLG_PS_UpdateDlgStructA(hDlg
, pda
))
2905 EndDialog(hDlg
, TRUE
);
2909 EndDialog(hDlg
, FALSE
);
2913 pda
->pdlg
.Flags
= 0;
2914 pda
->pdlg
.hwndOwner
= hDlg
;
2915 if (PrintDlgA(&(pda
->pdlg
)))
2916 PRINTDLG_PS_ChangePrinterA(hDlg
,pda
);
2921 if((id
== rad1
&& pda
->curdlg
.ptPaperSize
.x
> pda
->curdlg
.ptPaperSize
.y
) ||
2922 (id
== rad2
&& pda
->curdlg
.ptPaperSize
.y
> pda
->curdlg
.ptPaperSize
.x
))
2926 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2928 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2929 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2931 GetDlgItemTextA(hDlg
, edt4
, TmpText
, sizeof(TmpText
));
2932 GetDlgItemTextA(hDlg
, edt5
, TmpText2
, sizeof(TmpText2
));
2933 SetDlgItemTextA(hDlg
, edt5
, TmpText
);
2934 SetDlgItemTextA(hDlg
, edt4
, TmpText2
);
2936 GetDlgItemTextA(hDlg
, edt6
, TmpText
, sizeof(TmpText
));
2937 GetDlgItemTextA(hDlg
, edt7
, TmpText2
, sizeof(TmpText2
));
2938 SetDlgItemTextA(hDlg
, edt7
, TmpText
);
2939 SetDlgItemTextA(hDlg
, edt6
, TmpText2
);
2941 PRINTDLG_PS_ChangePaperPrev(pda
);
2944 case cmb1
: /* Printer combo */
2945 if(msg
== CBN_SELCHANGE
){
2946 char crPrinterName
[256];
2947 GetDlgItemTextA(hDlg
, id
, crPrinterName
, 255);
2948 PRINTDLG_PS_ChangeActivePrinterA(crPrinterName
, pda
);
2949 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
2952 case cmb2
: /* Paper combo */
2953 if(msg
== CBN_SELCHANGE
){
2954 DWORD paperword
= SendDlgItemMessageA(hDlg
,cmb2
,CB_GETITEMDATA
,
2955 SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCURSEL
, 0, 0), 0);
2956 if (paperword
!= CB_ERR
) {
2957 PRINTDLG_PaperSizeA(&(pda
->pdlg
), paperword
,&(pda
->curdlg
.ptPaperSize
));
2958 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.x
);
2959 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
,pda
->curdlg
.ptPaperSize
.y
);
2961 if (IsDlgButtonChecked(hDlg
, rad2
)) {
2962 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
2963 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
2964 pda
->curdlg
.ptPaperSize
.y
= tmp
;
2966 PRINTDLG_PS_ChangePaperPrev(pda
);
2968 FIXME("could not get dialog text for papersize cmbbox?\n");
2972 if(msg
== CBN_SELCHANGE
){
2973 DEVMODEA
*dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2974 dm
->u1
.s1
.dmDefaultSource
= SendDlgItemMessageA(hDlg
, cmb3
,CB_GETITEMDATA
,
2975 SendDlgItemMessageA(hDlg
, cmb3
, CB_GETCURSEL
, 0, 0), 0);
2976 GlobalUnlock(pda
->pdlg
.hDevMode
);
2979 case psh2
: /* Printer Properties button */
2982 char PrinterName
[256];
2987 GetDlgItemTextA(hDlg
, cmb1
, PrinterName
, 255);
2988 if (!OpenPrinterA(PrinterName
, &hPrinter
, NULL
)) {
2989 FIXME("Call to OpenPrinter did not succeed!\n");
2992 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
2993 DocumentPropertiesA(hDlg
, hPrinter
, PrinterName
, dm
, dm
,
2994 DM_IN_BUFFER
| DM_OUT_BUFFER
| DM_IN_PROMPT
);
2995 ClosePrinter(hPrinter
);
2996 /* Changing paper */
2997 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &(pda
->curdlg
.ptPaperSize
));
2998 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
2999 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3000 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
){
3001 DWORD tmp
= pda
->curdlg
.ptPaperSize
.x
;
3002 pda
->curdlg
.ptPaperSize
.x
= pda
->curdlg
.ptPaperSize
.y
;
3003 pda
->curdlg
.ptPaperSize
.y
= tmp
;
3004 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3007 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3008 /* Changing paper preview */
3009 PRINTDLG_PS_ChangePaperPrev(pda
);
3010 /* Selecting paper in combo */
3011 count
= SendDlgItemMessageA(hDlg
, cmb2
, CB_GETCOUNT
, 0, 0);
3012 if(count
!= CB_ERR
){
3013 for(i
=0; i
<count
; ++i
){
3014 if(SendDlgItemMessageA(hDlg
, cmb2
, CB_GETITEMDATA
, i
, 0) == dm
->u1
.s1
.dmPaperSize
) {
3015 SendDlgItemMessageA(hDlg
, cmb2
, CB_SETCURSEL
, i
, 0);
3021 GlobalUnlock(pda
->pdlg
.hDevMode
);
3025 GETVAL(id
, pda
->curdlg
.rtMargin
.left
);
3028 GETVAL(id
, pda
->curdlg
.rtMargin
.top
);
3031 GETVAL(id
, pda
->curdlg
.rtMargin
.right
);
3034 GETVAL(id
, pda
->curdlg
.rtMargin
.bottom
);
3037 InvalidateRect(GetDlgItem(hDlg
, rct1
), NULL
, TRUE
);
3043 PRINTDLG_PS_WMCommandW(
3044 HWND hDlg
, WPARAM wParam
, LPARAM lParam
, PageSetupDataW
*pdw
3046 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
3047 LOWORD(lParam
),wParam
,lParam
);
3048 switch (LOWORD(wParam
)) {
3050 if (!PRINTDLG_PS_UpdateDlgStructW(hDlg
, pdw
))
3052 EndDialog(hDlg
, TRUE
);
3056 EndDialog(hDlg
, FALSE
);
3061 if((LOWORD(wParam
) == rad1
&& pdw
->curdlg
.ptPaperSize
.x
> pdw
->curdlg
.ptPaperSize
.y
) ||
3062 (LOWORD(wParam
) == rad2
&& pdw
->curdlg
.ptPaperSize
.y
> pdw
->curdlg
.ptPaperSize
.x
))
3066 DWORD tmp
= pdw
->curdlg
.ptPaperSize
.y
;
3068 pdw
->curdlg
.ptPaperSize
.y
= pdw
->curdlg
.ptPaperSize
.x
;
3069 pdw
->curdlg
.ptPaperSize
.x
= tmp
;
3071 GetDlgItemTextW(hDlg
, edt4
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3072 GetDlgItemTextW(hDlg
, edt5
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3073 SetDlgItemTextW(hDlg
, edt5
, tmpText
);
3074 SetDlgItemTextW(hDlg
, edt4
, tmpText2
);
3076 GetDlgItemTextW(hDlg
, edt6
, tmpText
, sizeof(tmpText
)/sizeof(WCHAR
));
3077 GetDlgItemTextW(hDlg
, edt7
, tmpText2
, sizeof(tmpText2
)/sizeof(WCHAR
));
3078 SetDlgItemTextW(hDlg
, edt7
, tmpText
);
3079 SetDlgItemTextW(hDlg
, edt6
, tmpText2
);
3084 pdw
->pdlg
.Flags
= 0;
3085 pdw
->pdlg
.hwndOwner
= hDlg
;
3086 PRINTDLG_PS_UpdatePrintDlgW(pdw
, hDlg
);
3087 if (PrintDlgW(&(pdw
->pdlg
)))
3088 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3096 /***********************************************************************
3097 * DefaultPagePaintHook
3098 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box
3099 * whenever the sample page is redrawn.
3103 PRINTDLG_DefaultPagePaintHook(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
3104 const PageSetupDataA
*pda
)
3106 LPRECT lprc
= (LPRECT
) lParam
;
3107 HDC hdc
= (HDC
) wParam
;
3110 HFONT hfont
, holdfont
;
3112 TRACE("uMsg: WM_USER+%d\n",uMsg
-WM_USER
);
3113 /* Call user paint hook if enable */
3114 if (pda
->dlga
->Flags
& PSD_ENABLEPAGEPAINTHOOK
)
3115 if (pda
->dlga
->lpfnPagePaintHook(hwndDlg
, uMsg
, wParam
, lParam
))
3119 /* LPPAGESETUPDLG in lParam */
3120 case WM_PSD_PAGESETUPDLG
:
3121 /* Inform about the sample page rectangle */
3122 case WM_PSD_FULLPAGERECT
:
3123 /* Inform about the margin rectangle */
3124 case WM_PSD_MINMARGINRECT
:
3127 /* Draw dashed rectangle showing margins */
3128 case WM_PSD_MARGINRECT
:
3129 hpen
= CreatePen(PS_DASH
, 1, GetSysColor(COLOR_3DSHADOW
));
3130 holdpen
= SelectObject(hdc
, hpen
);
3131 Rectangle(hdc
, lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
3132 DeleteObject(SelectObject(hdc
, holdpen
));
3134 /* Draw the fake document */
3135 case WM_PSD_GREEKTEXTRECT
:
3136 /* select a nice scalable font, because we want the text really small */
3137 SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(lf
), &lf
, 0);
3138 lf
.lfHeight
= 6; /* value chosen based on visual effect */
3139 hfont
= CreateFontIndirectW(&lf
);
3140 holdfont
= SelectObject(hdc
, hfont
);
3142 /* if text not loaded, then do so now */
3143 if (wszFakeDocumentText
[0] == '\0')
3144 LoadStringW(COMDLG32_hInstance
,
3146 wszFakeDocumentText
,
3147 sizeof(wszFakeDocumentText
)/sizeof(wszFakeDocumentText
[0]));
3149 oldbkmode
= SetBkMode(hdc
, TRANSPARENT
);
3150 DrawTextW(hdc
, wszFakeDocumentText
, -1, lprc
, DT_TOP
|DT_LEFT
|DT_NOPREFIX
|DT_WORDBREAK
);
3151 SetBkMode(hdc
, oldbkmode
);
3153 DeleteObject(SelectObject(hdc
, holdfont
));
3156 /* Envelope stamp */
3157 case WM_PSD_ENVSTAMPRECT
:
3158 /* Return address */
3159 case WM_PSD_YAFULLPAGERECT
:
3160 FIXME("envelope/stamp is not implemented\n");
3163 FIXME("Unknown message %x\n",uMsg
);
3169 /***********************************************************************
3171 * The main paint procedure for the PageSetupDlg function.
3172 * The Page Setup dialog box includes an image of a sample page that shows how
3173 * the user's selections affect the appearance of the printed output.
3174 * The image consists of a rectangle that represents the selected paper
3175 * or envelope type, with a dotted-line rectangle representing
3176 * the current margins, and partial (Greek text) characters
3177 * to show how text looks on the printed page.
3179 * The following messages in the order sends to user hook procedure:
3180 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page
3181 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle
3182 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?)
3183 * WM_PSD_MARGINRECT Draw the margin rectangle
3184 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle
3185 * If any of first three messages returns TRUE, painting done.
3188 * hWnd [in] Handle to the Page Setup dialog box
3189 * uMsg [in] Received message
3192 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only)
3193 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes)
3196 * FALSE if all done correctly
3201 static LRESULT CALLBACK
3202 PRINTDLG_PagePaintProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3205 RECT rcClient
, rcMargin
;
3208 HBRUSH hbrush
, holdbrush
;
3209 PageSetupDataA
*pda
;
3210 int papersize
=0, orientation
=0; /* FIXME: set this values for user paint hook */
3211 double scalx
, scaly
;
3212 #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda)
3214 if (uMsg
!= WM_PAINT
)
3215 return CallWindowProcA(lpfnStaticWndProc
, hWnd
, uMsg
, wParam
, lParam
);
3217 /* Processing WM_PAINT message */
3218 pda
= GetPropA(hWnd
, "__WINE_PAGESETUPDLGDATA");
3220 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3223 if (PRINTDLG_DefaultPagePaintHook(hWnd
, WM_PSD_PAGESETUPDLG
, MAKELONG(papersize
, orientation
), (LPARAM
)pda
->dlga
, pda
))
3226 hdc
= BeginPaint(hWnd
, &ps
);
3227 GetClientRect(hWnd
, &rcClient
);
3229 scalx
= rcClient
.right
/ (double)pda
->curdlg
.ptPaperSize
.x
;
3230 scaly
= rcClient
.bottom
/ (double)pda
->curdlg
.ptPaperSize
.y
;
3231 rcMargin
= rcClient
;
3233 rcMargin
.left
+= pda
->curdlg
.rtMargin
.left
* scalx
;
3234 rcMargin
.top
+= pda
->curdlg
.rtMargin
.top
* scalx
;
3235 rcMargin
.right
-= pda
->curdlg
.rtMargin
.right
* scaly
;
3236 rcMargin
.bottom
-= pda
->curdlg
.rtMargin
.bottom
* scaly
;
3238 /* if the space is too small then we make sure to not draw anything */
3239 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3240 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3242 if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT
, &rcClient
) &&
3243 !CALLPAINTHOOK(WM_PSD_MINMARGINRECT
, &rcMargin
) )
3245 /* fill background */
3246 hbrush
= GetSysColorBrush(COLOR_3DHIGHLIGHT
);
3247 FillRect(hdc
, &rcClient
, hbrush
);
3248 holdbrush
= SelectObject(hdc
, hbrush
);
3250 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DSHADOW
));
3251 holdpen
= SelectObject(hdc
, hpen
);
3253 /* paint left edge */
3254 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3255 LineTo(hdc
, rcClient
.left
, rcClient
.bottom
-1);
3257 /* paint top edge */
3258 MoveToEx(hdc
, rcClient
.left
, rcClient
.top
, NULL
);
3259 LineTo(hdc
, rcClient
.right
, rcClient
.top
);
3261 hpen
= CreatePen(PS_SOLID
, 1, GetSysColor(COLOR_3DDKSHADOW
));
3262 DeleteObject(SelectObject(hdc
, hpen
));
3264 /* paint right edge */
3265 MoveToEx(hdc
, rcClient
.right
-1, rcClient
.top
, NULL
);
3266 LineTo(hdc
, rcClient
.right
-1, rcClient
.bottom
);
3268 /* paint bottom edge */
3269 MoveToEx(hdc
, rcClient
.left
, rcClient
.bottom
-1, NULL
);
3270 LineTo(hdc
, rcClient
.right
, rcClient
.bottom
-1);
3272 DeleteObject(SelectObject(hdc
, holdpen
));
3273 DeleteObject(SelectObject(hdc
, holdbrush
));
3275 CALLPAINTHOOK(WM_PSD_MARGINRECT
, &rcMargin
);
3277 /* give text a bit of a space from the frame */
3280 rcMargin
.right
-= 2;
3281 rcMargin
.bottom
-= 2;
3283 /* if the space is too small then we make sure to not draw anything */
3284 rcMargin
.left
= min(rcMargin
.left
, rcMargin
.right
);
3285 rcMargin
.top
= min(rcMargin
.top
, rcMargin
.bottom
);
3287 CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT
, &rcMargin
);
3290 EndPaint(hWnd
, &ps
);
3292 #undef CALLPAINTHOOK
3295 /***********************************************************************
3296 * PRINTDLG_PageDlgProcA
3297 * Message handler for PageSetupDlgA
3299 static INT_PTR CALLBACK
3300 PRINTDLG_PageDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3303 PageSetupDataA
*pda
;
3304 INT_PTR res
= FALSE
;
3307 if (uMsg
== WM_INITDIALOG
) { /*Init dialog*/
3308 pda
= (PageSetupDataA
*)lParam
;
3309 pda
->hDlg
= hDlg
; /* saving handle to main window to PageSetupDataA structure */
3310 pda
->curdlg
= *pda
->dlga
;
3312 hDrawWnd
= GetDlgItem(hDlg
, rct1
);
3313 TRACE("set property to %p\n", pda
);
3314 SetPropA(hDlg
, "__WINE_PAGESETUPDLGDATA", pda
);
3315 SetPropA(hDrawWnd
, "__WINE_PAGESETUPDLGDATA", pda
);
3316 GetWindowRect(hDrawWnd
, &pda
->rtDrawRect
); /* Calculating rect in client coordinates where paper draws */
3317 ScreenToClient(hDlg
, (LPPOINT
)&pda
->rtDrawRect
);
3318 ScreenToClient(hDlg
, (LPPOINT
)(&pda
->rtDrawRect
.right
));
3319 lpfnStaticWndProc
= (WNDPROC
)SetWindowLongPtrW(
3322 (ULONG_PTR
)PRINTDLG_PagePaintProc
);
3324 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */
3326 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3327 if (!pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pda
->dlga
))
3328 FIXME("Setup page hook failed?\n");
3331 /* if printer button disabled */
3332 if (pda
->dlga
->Flags
& PSD_DISABLEPRINTER
)
3333 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3334 /* if margin edit boxes disabled */
3335 if (pda
->dlga
->Flags
& PSD_DISABLEMARGINS
) {
3336 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3337 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3338 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3339 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3341 /* Set orientation radiobutton properly */
3342 if(pda
->dlga
->hDevMode
)
3344 dm
= GlobalLock(pda
->dlga
->hDevMode
);
3345 if (dm
->u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
)
3346 CheckRadioButton(hDlg
, rad1
, rad2
, rad2
);
3347 else /* this is default if papersize is not set */
3348 CheckRadioButton(hDlg
, rad1
, rad2
, rad1
);
3349 GlobalUnlock(pda
->dlga
->hDevMode
);
3352 /* if orientation disabled */
3353 if (pda
->dlga
->Flags
& PSD_DISABLEORIENTATION
) {
3354 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3355 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3357 /* We fill them out enabled or not */
3358 if (pda
->dlga
->Flags
& PSD_MARGINS
) {
3360 _c_size2strA(pda
,pda
->dlga
->rtMargin
.left
,str
);
3361 SetDlgItemTextA(hDlg
,edt4
,str
);
3362 _c_size2strA(pda
,pda
->dlga
->rtMargin
.top
,str
);
3363 SetDlgItemTextA(hDlg
,edt5
,str
);
3364 _c_size2strA(pda
,pda
->dlga
->rtMargin
.right
,str
);
3365 SetDlgItemTextA(hDlg
,edt6
,str
);
3366 _c_size2strA(pda
,pda
->dlga
->rtMargin
.bottom
,str
);
3367 SetDlgItemTextA(hDlg
,edt7
,str
);
3369 /* default is 1 inch */
3370 DWORD size
= _c_inch2size(pda
->dlga
,1000);
3372 _c_size2strA(pda
,size
,str
);
3373 SetDlgItemTextA(hDlg
,edt4
,str
);
3374 SetDlgItemTextA(hDlg
,edt5
,str
);
3375 SetDlgItemTextA(hDlg
,edt6
,str
);
3376 SetDlgItemTextA(hDlg
,edt7
,str
);
3377 pda
->curdlg
.rtMargin
.left
= size
;
3378 pda
->curdlg
.rtMargin
.top
= size
;
3379 pda
->curdlg
.rtMargin
.right
= size
;
3380 pda
->curdlg
.rtMargin
.bottom
= size
;
3382 /* if paper disabled */
3383 if (pda
->dlga
->Flags
& PSD_DISABLEPAPER
) {
3384 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3385 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3387 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
3388 PRINTDLG_PS_ChangePrinterA(hDlg
, pda
);
3389 dm
= GlobalLock(pda
->pdlg
.hDevMode
);
3391 dm
->u1
.s1
.dmDefaultSource
= 15; /*FIXME: Automatic select. Does it always 15 at start? */
3392 PRINTDLG_PaperSizeA(&(pda
->pdlg
), dm
->u1
.s1
.dmPaperSize
, &pda
->curdlg
.ptPaperSize
);
3393 GlobalUnlock(pda
->pdlg
.hDevMode
);
3394 pda
->curdlg
.ptPaperSize
.x
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.x
);
3395 pda
->curdlg
.ptPaperSize
.y
= _c_10mm2size(pda
->dlga
, pda
->curdlg
.ptPaperSize
.y
);
3396 if (IsDlgButtonChecked(hDlg
, rad2
) == BST_CHECKED
) { /* Landscape orientation */
3397 DWORD tmp
= pda
->curdlg
.ptPaperSize
.y
;
3398 pda
->curdlg
.ptPaperSize
.y
= pda
->curdlg
.ptPaperSize
.x
;
3399 pda
->curdlg
.ptPaperSize
.x
= tmp
;
3402 WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda
->pdlg
.hDevMode
);
3403 /* Drawing paper prev */
3404 PRINTDLG_PS_ChangePaperPrev(pda
);
3407 pda
= GetPropA(hDlg
,"__WINE_PAGESETUPDLGDATA");
3409 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3412 if (pda
->dlga
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3413 res
= pda
->dlga
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3414 if (res
) return res
;
3419 return PRINTDLG_PS_WMCommandA(hDlg
, wParam
, lParam
, pda
);
3424 static INT_PTR CALLBACK
3425 PageDlgProcW(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3427 static const WCHAR __WINE_PAGESETUPDLGDATA
[] =
3428 { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
3429 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };
3430 PageSetupDataW
*pdw
;
3433 if (uMsg
==WM_INITDIALOG
) {
3435 pdw
= (PageSetupDataW
*)lParam
;
3436 pdw
->curdlg
= *pdw
->dlgw
;
3437 SetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
, pdw
);
3438 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3439 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,(LPARAM
)pdw
->dlgw
);
3441 FIXME("Setup page hook failed?\n");
3446 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) {
3447 FIXME("PagePaintHook not yet implemented!\n");
3449 if (pdw
->dlgw
->Flags
& PSD_DISABLEPRINTER
)
3450 EnableWindow(GetDlgItem(hDlg
, psh3
), FALSE
);
3451 if (pdw
->dlgw
->Flags
& PSD_DISABLEMARGINS
) {
3452 EnableWindow(GetDlgItem(hDlg
, edt4
), FALSE
);
3453 EnableWindow(GetDlgItem(hDlg
, edt5
), FALSE
);
3454 EnableWindow(GetDlgItem(hDlg
, edt6
), FALSE
);
3455 EnableWindow(GetDlgItem(hDlg
, edt7
), FALSE
);
3458 PRINTDLG_PS_ChangePrinterW(hDlg
,pdw
);
3460 if (pdw
->dlgw
->Flags
& PSD_DISABLEORIENTATION
) {
3461 EnableWindow(GetDlgItem(hDlg
,rad1
),FALSE
);
3462 EnableWindow(GetDlgItem(hDlg
,rad2
),FALSE
);
3464 /* We fill them out enabled or not */
3465 if (pdw
->dlgw
->Flags
& PSD_MARGINS
) {
3467 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.left
,str
);
3468 SetDlgItemTextW(hDlg
,edt4
,str
);
3469 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.top
,str
);
3470 SetDlgItemTextW(hDlg
,edt5
,str
);
3471 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.right
,str
);
3472 SetDlgItemTextW(hDlg
,edt6
,str
);
3473 _c_size2strW(pdw
,pdw
->dlgw
->rtMargin
.bottom
,str
);
3474 SetDlgItemTextW(hDlg
,edt7
,str
);
3476 /* default is 1 inch */
3477 DWORD size
= _c_inch2size((LPPAGESETUPDLGA
)pdw
->dlgw
,1000);
3479 _c_size2strW(pdw
,size
,str
);
3480 SetDlgItemTextW(hDlg
,edt4
,str
);
3481 SetDlgItemTextW(hDlg
,edt5
,str
);
3482 SetDlgItemTextW(hDlg
,edt6
,str
);
3483 SetDlgItemTextW(hDlg
,edt7
,str
);
3486 if (pdw
->dlgw
->Flags
& PSD_DISABLEPAPER
) {
3487 EnableWindow(GetDlgItem(hDlg
,cmb2
),FALSE
);
3488 EnableWindow(GetDlgItem(hDlg
,cmb3
),FALSE
);
3493 pdw
= GetPropW(hDlg
, __WINE_PAGESETUPDLGDATA
);
3495 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
3498 if (pdw
->dlgw
->Flags
& PSD_ENABLEPAGESETUPHOOK
) {
3499 res
= pdw
->dlgw
->lpfnPageSetupHook(hDlg
,uMsg
,wParam
,lParam
);
3500 if (res
) return res
;
3505 return PRINTDLG_PS_WMCommandW(hDlg
, wParam
, lParam
, pdw
);
3510 /***********************************************************************
3511 * PageSetupDlgA (COMDLG32.@)
3513 * Displays the PAGE SETUP dialog box, which enables the user to specify
3514 * specific properties of a printed page such as
3515 * size, source, orientation and the width of the page margins.
3518 * setupdlg [IO] PAGESETUPDLGA struct
3521 * TRUE if the user pressed the OK button
3522 * FALSE if the user cancelled the window or an error occurred
3525 * The values of hDevMode and hDevNames are filled on output and can be
3526 * changed in PAGESETUPDLG when they are passed in PageSetupDlg.
3530 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
3534 PageSetupDataA
*pda
;
3537 if (setupdlg
== NULL
) {
3538 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3543 if(TRACE_ON(commdlg
)) {
3544 char flagstr
[1000] = "";
3545 const struct pd_flags
*pflag
= psd_flags
;
3546 for( ; pflag
->name
; pflag
++) {
3547 if(setupdlg
->Flags
& pflag
->flag
) {
3548 strcat(flagstr
, pflag
->name
);
3549 strcat(flagstr
, "|");
3552 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3553 "hinst %p, flags %08x (%s)\n",
3554 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3555 setupdlg
->hDevNames
,
3556 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3559 /* Checking setupdlg structure */
3560 if(setupdlg
->lStructSize
!= sizeof(PAGESETUPDLGA
)) {
3561 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE
);
3564 if ((setupdlg
->Flags
& PSD_ENABLEPAGEPAINTHOOK
) &&
3565 (setupdlg
->lpfnPagePaintHook
== NULL
)) {
3566 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK
);
3570 /* Initialize default printer struct. If no printer device info is specified
3571 retrieve the default printer data. */
3572 memset(&pdlg
,0,sizeof(pdlg
));
3573 pdlg
.lStructSize
= sizeof(pdlg
);
3574 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3575 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3576 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3578 pdlg
.Flags
= PD_RETURNDEFAULT
;
3579 bRet
= PrintDlgA(&pdlg
);
3581 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3583 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3584 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3590 /* short cut exit, just return default values */
3591 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3594 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3595 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3596 dm
= GlobalLock(pdlg
.hDevMode
);
3597 PRINTDLG_PaperSizeA(&pdlg
, dm
->u1
.s1
.dmPaperSize
, &setupdlg
->ptPaperSize
);
3598 GlobalUnlock(pdlg
.hDevMode
);
3599 setupdlg
->ptPaperSize
.x
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.x
);
3600 setupdlg
->ptPaperSize
.y
=_c_10mm2size(setupdlg
,setupdlg
->ptPaperSize
.y
);
3604 /* get dialog template */
3605 hDlgTmpl
= PRINTDLG_GetPGSTemplateA(setupdlg
);
3607 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3610 ptr
= LockResource( hDlgTmpl
);
3612 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3616 pda
= HeapAlloc(GetProcessHeap(),0,sizeof(*pda
));
3617 pda
->dlga
= setupdlg
;
3620 bRet
= (0<DialogBoxIndirectParamA(
3621 setupdlg
->hInstance
,
3623 setupdlg
->hwndOwner
,
3624 PRINTDLG_PageDlgProcA
,
3628 HeapFree(GetProcessHeap(),0,pda
);
3631 /***********************************************************************
3632 * PageSetupDlgW (COMDLG32.@)
3634 * See PageSetupDlgA.
3636 BOOL WINAPI
PageSetupDlgW(LPPAGESETUPDLGW setupdlg
) {
3640 PageSetupDataW
*pdw
;
3643 FIXME("Unicode implementation is not done yet\n");
3645 if (setupdlg
== NULL
) {
3646 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION
);
3650 if(TRACE_ON(commdlg
)) {
3651 char flagstr
[1000] = "";
3652 const struct pd_flags
*pflag
= psd_flags
;
3653 for( ; pflag
->name
; pflag
++) {
3654 if(setupdlg
->Flags
& pflag
->flag
) {
3655 strcat(flagstr
, pflag
->name
);
3656 strcat(flagstr
, "|");
3659 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
3660 "hinst %p, flags %08x (%s)\n",
3661 setupdlg
, setupdlg
->hwndOwner
, setupdlg
->hDevMode
,
3662 setupdlg
->hDevNames
,
3663 setupdlg
->hInstance
, setupdlg
->Flags
, flagstr
);
3666 /* Initialize default printer struct. If no printer device info is specified
3667 retrieve the default printer data. */
3668 memset(&pdlg
,0,sizeof(pdlg
));
3669 pdlg
.lStructSize
= sizeof(pdlg
);
3670 if (setupdlg
->hDevMode
&& setupdlg
->hDevNames
) {
3671 pdlg
.hDevMode
= setupdlg
->hDevMode
;
3672 pdlg
.hDevNames
= setupdlg
->hDevNames
;
3674 pdlg
.Flags
= PD_RETURNDEFAULT
;
3675 bRet
= PrintDlgW(&pdlg
);
3677 if (!(setupdlg
->Flags
& PSD_NOWARNING
)) {
3679 LoadStringW(COMDLG32_hInstance
, PD32_NO_DEFAULT_PRINTER
, errstr
, 255);
3680 MessageBoxW(setupdlg
->hwndOwner
, errstr
, 0, MB_OK
| MB_ICONERROR
);
3686 /* short cut exit, just return default values */
3687 if (setupdlg
->Flags
& PSD_RETURNDEFAULT
) {
3688 static const WCHAR a4
[] = {'A','4',0};
3689 setupdlg
->hDevMode
= pdlg
.hDevMode
;
3690 setupdlg
->hDevNames
= pdlg
.hDevNames
;
3691 /* FIXME: Just return "A4" for now. */
3692 PRINTDLG_PaperSizeW(&pdlg
,a4
,&setupdlg
->ptPaperSize
);
3693 setupdlg
->ptPaperSize
.x
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.x
);
3694 setupdlg
->ptPaperSize
.y
=_c_10mm2size((LPPAGESETUPDLGA
)setupdlg
,setupdlg
->ptPaperSize
.y
);
3697 hDlgTmpl
= PRINTDLG_GetPGSTemplateW(setupdlg
);
3699 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3702 ptr
= LockResource( hDlgTmpl
);
3704 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
3707 pdw
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdw
));
3708 pdw
->dlgw
= setupdlg
;
3711 bRet
= (0<DialogBoxIndirectParamW(
3712 setupdlg
->hInstance
,
3714 setupdlg
->hwndOwner
,
3721 /***********************************************************************
3722 * PrintDlgExA (COMDLG32.@)
3730 HRESULT WINAPI
PrintDlgExA(LPPRINTDLGEXA lppd
)
3733 FIXME("(%p) stub\n", lppd
);
3734 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXA
))) {
3735 return E_INVALIDARG
;
3738 if (!IsWindow(lppd
->hwndOwner
)) {
3745 /***********************************************************************
3746 * PrintDlgExW (COMDLG32.@)
3748 * Display the property sheet style PRINT dialog box
3751 * lppd [IO] ptr to PRINTDLGEX struct
3755 * Failure: One of the following COM error codes:
3756 * E_OUTOFMEMORY Insufficient memory.
3757 * E_INVALIDARG One or more arguments are invalid.
3758 * E_POINTER Invalid pointer.
3759 * E_HANDLE Invalid handle.
3760 * E_FAIL Unspecified error.
3763 * This Dialog enables the user to specify specific properties of the print job.
3764 * The property sheet can also have additional application-specific and
3765 * driver-specific property pages.
3768 * Not fully implemented
3771 HRESULT WINAPI
PrintDlgExW(LPPRINTDLGEXW lppd
)
3776 FIXME("(%p) not fully implemented\n", lppd
);
3778 if ((lppd
== NULL
) || (lppd
->lStructSize
!= sizeof(PRINTDLGEXW
))) {
3779 return E_INVALIDARG
;
3782 if (!IsWindow(lppd
->hwndOwner
)) {
3786 if (lppd
->Flags
& PD_RETURNDEFAULT
) {
3787 PRINTER_INFO_2W
*pbuf
;
3788 DRIVER_INFO_2W
*dbuf
;
3790 DWORD needed
= 1024;
3793 if (lppd
->hDevMode
|| lppd
->hDevNames
) {
3794 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
3795 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3796 return E_INVALIDARG
;
3798 if (!PRINTDLG_OpenDefaultPrinter(&hprn
)) {
3799 WARN("Can't find default printer\n");
3800 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN
);
3804 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3805 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3806 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3807 HeapFree(GetProcessHeap(), 0, pbuf
);
3808 pbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3809 bRet
= GetPrinterW(hprn
, 2, (LPBYTE
)pbuf
, needed
, &needed
);
3812 HeapFree(GetProcessHeap(), 0, pbuf
);
3818 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3819 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3820 if (!bRet
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
3821 HeapFree(GetProcessHeap(), 0, dbuf
);
3822 dbuf
= HeapAlloc(GetProcessHeap(), 0, needed
);
3823 bRet
= GetPrinterDriverW(hprn
, NULL
, 3, (LPBYTE
)dbuf
, needed
, &needed
);
3826 ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
3827 GetLastError(), debugstr_w(pbuf
->pPrinterName
));
3828 HeapFree(GetProcessHeap(), 0, dbuf
);
3829 HeapFree(GetProcessHeap(), 0, pbuf
);
3830 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE
);
3836 PRINTDLG_CreateDevNamesW(&(lppd
->hDevNames
),
3840 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, pbuf
->pDevMode
->dmSize
+
3841 pbuf
->pDevMode
->dmDriverExtra
);
3842 if (lppd
->hDevMode
) {
3843 ptr
= GlobalLock(lppd
->hDevMode
);
3845 memcpy(ptr
, pbuf
->pDevMode
, pbuf
->pDevMode
->dmSize
+
3846 pbuf
->pDevMode
->dmDriverExtra
);
3847 GlobalUnlock(lppd
->hDevMode
);
3851 HeapFree(GetProcessHeap(), 0, pbuf
);
3852 HeapFree(GetProcessHeap(), 0, dbuf
);