2 * COMMDLG - Print Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
13 #include "wine/winbase16.h"
14 #include "wine/winuser16.h"
26 DEFAULT_DEBUG_CHANNEL(commdlg
)
30 /***********************************************************************
31 * PrintDlg16 (COMMDLG.20)
33 BOOL16 WINAPI
PrintDlg16( SEGPTR printdlg
)
39 HANDLE hResInfo
, hDlgTmpl
;
41 LPPRINTDLG16 lpPrint
= (LPPRINTDLG16
)PTR_SEG_TO_LIN(printdlg
);
43 TRACE(commdlg
,"(%p) -- Flags=%08lX\n", lpPrint
, lpPrint
->Flags
);
45 if (lpPrint
->Flags
& PD_RETURNDEFAULT
)
46 /* FIXME: should fill lpPrint->hDevMode and lpPrint->hDevNames here */
49 if (lpPrint
->Flags
& PD_PRINTSETUP
)
50 rscname
= "PRINT_SETUP";
54 if (!(hResInfo
= FindResourceA(COMMDLG_hInstance32
, rscname
, RT_DIALOGA
)))
56 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
59 if (!(hDlgTmpl
= LoadResource(COMMDLG_hInstance32
, hResInfo
)) ||
60 !(template = LockResource( hDlgTmpl
)))
62 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
66 hInst
= GetWindowLongA( lpPrint
->hwndOwner
, GWL_HINSTANCE
);
67 hwndDialog
= DIALOG_CreateIndirect( hInst
, template, TRUE
,
69 (DLGPROC16
)((lpPrint
->Flags
& PD_PRINTSETUP
) ?
70 MODULE_GetWndProcEntry16("PrintSetupDlgProc") :
71 MODULE_GetWndProcEntry16("PrintDlgProc")),
72 printdlg
, WIN_PROC_16
);
73 if (hwndDialog
) bRet
= DIALOG_DoDialogBox( hwndDialog
, lpPrint
->hwndOwner
);
78 /* This PRINTDLGA internal structure stores
79 * pointers to several throughout useful structures.
84 LPPRINTER_INFO_2A lpPrinterInfo
;
85 DWORD NrOfPrinterInfoEntries
;
86 LPPRINTDLGA lpPrintDlg
;
90 /***********************************************************************
91 * PrintDlgA (COMDLG32.17)
93 * Displays the the PRINT dialog box, which enables the user to specify
94 * specific properties of the print job.
96 * (Note: according to the MS Platform SDK, this call was in the past
97 * also used to display some PRINT SETUP dialog. As this is superseded
98 * by PageSetupDlg, this now results in an error!)
101 * nonzero if the user pressed the OK button
102 * zero if the user cancelled the window or an error occurred
105 * The function is a stub only, returning TRUE to allow more programs
108 BOOL WINAPI
PrintDlgA(
109 LPPRINTDLGA lppd
/* ptr to PRINTDLG32 struct */
112 /* My implementing strategy:
114 * step 1: display the dialog and implement the layout-flags
115 * step 2: enter valid information in the fields (e.g. real printers)
116 * step 3: fix the RETURN-TRUE-ALWAYS Fixme by checking lppd->Flags for
118 * step 4: implement all other specs
119 * step 5: allow customisation of the dialog box
121 * current implementation is in step 2, nearly going to 3.
127 HANDLE hResInfo
, hDlgTmpl
;
128 HINSTANCE hInst
= GetWindowLongA( lppd
->hwndOwner
, GWL_HINSTANCE
);
129 DWORD EnumBytesNeeded
;
130 DWORD CopyOfEnumBytesNeeded
;
131 PRINT_PTRA PrintStructures
;
133 FIXME(commdlg
, "KVG (%p): stub\n", lppd
);
134 PrintStructures
.lpPrintDlg
= lppd
;
136 if (!(hResInfo
= FindResourceA(COMDLG32_hInstance
, "PRINT32", RT_DIALOGA
)))
138 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
141 if (!(hDlgTmpl
= LoadResource(COMDLG32_hInstance
, hResInfo
)) ||
142 !(ptr
= LockResource( hDlgTmpl
)))
144 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
149 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
150 * must be registered and the Help button must be shown.
152 if (lppd
->Flags
& PD_SHOWHELP
)
154 if((PrintStructures
.HelpMessageID
= RegisterWindowMessageA(HELPMSGSTRING
))
157 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL
);
162 PrintStructures
.HelpMessageID
=0;
165 * if lppd->Flags PD_RETURNDEFAULT is specified, the PrintDlg function
166 * does not display the dialog box, but returns with valid entries
167 * for hDevMode and hDevNames .
169 * Currently the flag is recognised, but we return empty hDevMode and
170 * and hDevNames. This will be fixed when I am in step 3.
172 if (lppd
->Flags
& PD_RETURNDEFAULT
)
174 WARN(commdlg
, ": PrintDlg was requested to return printer info only."
175 "\n The return value currently does NOT provide these.\n");
176 COMDLG32_SetCommDlgExtendedError(PDERR_NODEVICES
);
177 /* return TRUE, thus never checked! */
181 if (lppd
->Flags
& PD_PRINTSETUP
)
183 FIXME(commdlg
, ": PrintDlg was requested to display PrintSetup box.\n");
184 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE
);
188 /* Use EnumPrinters to obtain a list of PRINTER_INFO_2A's
189 * and store a pointer to this list in our "global structure"
190 * as reference for the rest of the PrintDlg routines
192 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
,
193 0, &EnumBytesNeeded
, &PrintStructures
.NrOfPrinterInfoEntries
);
194 CopyOfEnumBytesNeeded
=EnumBytesNeeded
+16;
195 PrintStructures
.lpPrinterInfo
= malloc(CopyOfEnumBytesNeeded
*sizeof(char));
196 EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2,
197 (LPBYTE
)PrintStructures
.lpPrinterInfo
,
198 CopyOfEnumBytesNeeded
, &EnumBytesNeeded
,
199 &PrintStructures
.NrOfPrinterInfoEntries
);
201 /* Find the default printer.
202 * If not: display a warning message (unless PD_NOWARNING specified)
204 /* FIXME: Currently Unimplemented */
205 if (lppd
->Flags
& PD_NOWARNING
)
207 WARN(commdlg
, ": PD_NOWARNING Flag is not yet implemented.\n");
211 * FIXME : Should respond to TEMPLATE and HOOK flags here
212 * For now, only the standard dialog works.
214 if (lppd
->Flags
& (PD_ENABLEPRINTHOOK
| PD_ENABLEPRINTTEMPLATE
|
215 PD_ENABLEPRINTTEMPLATEHANDLE
| PD_ENABLESETUPHOOK
|
216 PD_ENABLESETUPTEMPLATE
|PD_ENABLESETUPTEMPLATEHANDLE
))
217 FIXME(commdlg
, ": unimplemented flag (ignored)\n");
220 hwndDialog
= DIALOG_CreateIndirect(hInst
, ptr
, TRUE
, lppd
->hwndOwner
,
221 (DLGPROC16
)PrintDlgProcA
, (LPARAM
)&PrintStructures
, WIN_PROC_32A
);
223 bRet
= DIALOG_DoDialogBox(hwndDialog
, lppd
->hwndOwner
);
225 free(PrintStructures
.lpPrinterInfo
);
232 /***********************************************************************
233 * PrintDlg32W (COMDLG32.18)
235 BOOL WINAPI
PrintDlgW( LPPRINTDLGW printdlg
)
237 FIXME(commdlg
, "A really empty stub\n" );
242 /***********************************************************************
243 * PRINTDLG_UpdatePrinterInfoTexts [internal]
245 void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg
, PRINT_PTRA
* PrintStructures
)
247 char PrinterName
[256];
250 LPPRINTER_INFO_2A lpPi
= NULL
;
251 GetDlgItemTextA(hDlg
, cmb4
, PrinterName
, 255);
253 /* look the selected PrinterName up in our array Printer_Info2As*/
254 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
256 lpPi
= &PrintStructures
->lpPrinterInfo
[i
];
257 if (strcmp(lpPi
->pPrinterName
, PrinterName
)==0)
260 /* FIXME: the status byte must be converted to user-understandable text...*/
261 sprintf(StatusMsg
,"%ld = 0x%08lx", lpPi
->Status
, lpPi
->Status
);
262 SendDlgItemMessageA(hDlg
, stc12
, WM_SETTEXT
, 0, (LPARAM
)StatusMsg
);
263 SendDlgItemMessageA(hDlg
, stc11
, WM_SETTEXT
, 0, (LPARAM
)lpPi
->pDriverName
);
264 if (lpPi
->pLocation
!= NULL
&& lpPi
->pLocation
[0]!='\0')
265 SendDlgItemMessageA(hDlg
, stc14
, WM_SETTEXT
, 0,(LPARAM
)lpPi
->pLocation
);
267 SendDlgItemMessageA(hDlg
, stc14
, WM_SETTEXT
, 0, (LPARAM
)lpPi
->pPortName
);
268 SendDlgItemMessageA(hDlg
, stc13
, WM_SETTEXT
, 0, (LPARAM
)lpPi
->pComment
);
272 /***********************************************************************
273 * PRINTDLG_WMInitDialog [internal]
275 LRESULT
PRINTDLG_WMInitDialog(HWND hDlg
, WPARAM wParam
, LPARAM lParam
,
276 PRINT_PTRA
* PrintStructures
)
279 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
280 LPPRINTER_INFO_2A lppi
= PrintStructures
->lpPrinterInfo
;
282 SetWindowLongA(hDlg
, DWL_USER
, lParam
);
283 TRACE(commdlg
,"WM_INITDIALOG lParam=%08lX\n", lParam
);
285 if (lppd
->lStructSize
!= sizeof(PRINTDLGA
))
287 FIXME(commdlg
,"structure size failure !!!\n");
288 /* EndDialog (hDlg, 0);
292 /* Fill Combobox according to info from PRINTER_INFO2A
293 * structure inside PrintStructures and generate an
294 * update-message to have the rest of the dialog box updated.
296 for (i
=0; i
< PrintStructures
->NrOfPrinterInfoEntries
; i
++)
297 SendDlgItemMessageA(hDlg
, cmb4
, CB_ADDSTRING
, 0,
298 (LPARAM
)lppi
[i
].pPrinterName
);
299 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
301 /* Flag processing to set the according buttons on/off and
302 * Initialise the various values
305 /* Print range (All/Range/Selection) */
306 /* FIXME: I allow more freedom than either Win95 or WinNT,
307 * which do not agree to what errors should be thrown or not
308 * in case nToPage or nFromPage is out-of-range.
310 if (lppd
->nMaxPage
< lppd
->nMinPage
)
311 lppd
->nMaxPage
= lppd
->nMinPage
;
312 if (lppd
->nMinPage
== lppd
->nMaxPage
)
313 lppd
->Flags
|= PD_NOPAGENUMS
;
314 if (lppd
->nToPage
< lppd
->nMinPage
)
315 lppd
->nToPage
= lppd
->nMinPage
;
316 if (lppd
->nToPage
> lppd
->nMaxPage
)
317 lppd
->nToPage
= lppd
->nMaxPage
;
318 if (lppd
->nFromPage
< lppd
->nMinPage
)
319 lppd
->nFromPage
= lppd
->nMinPage
;
320 if (lppd
->nFromPage
> lppd
->nMaxPage
)
321 lppd
->nFromPage
= lppd
->nMaxPage
;
322 SetDlgItemInt(hDlg
, edt1
, lppd
->nFromPage
, FALSE
);
323 SetDlgItemInt(hDlg
, edt2
, lppd
->nToPage
, FALSE
);
324 CheckRadioButton(hDlg
, rad1
, rad3
, rad1
); /* default */
325 if (lppd
->Flags
& PD_NOSELECTION
)
326 EnableWindow(GetDlgItem(hDlg
, rad2
), FALSE
);
328 if (lppd
->Flags
& PD_SELECTION
)
329 CheckRadioButton(hDlg
, rad1
, rad3
, rad2
);
330 if (lppd
->Flags
& PD_NOPAGENUMS
)
332 EnableWindow(GetDlgItem(hDlg
, rad3
), FALSE
);
333 EnableWindow(GetDlgItem(hDlg
, stc2
),FALSE
);
334 EnableWindow(GetDlgItem(hDlg
, edt1
), FALSE
);
335 EnableWindow(GetDlgItem(hDlg
, stc3
),FALSE
);
336 EnableWindow(GetDlgItem(hDlg
, edt2
), FALSE
);
340 if (lppd
->Flags
& PD_PAGENUMS
)
341 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
343 /* FIXME: in Win95, the radiobutton "All" is displayed as
344 * "Print all xxx pages"... This is not done here (yet?)
348 if (lppd
->Flags
& PD_COLLATE
)
349 FIXME(commdlg
, "PD_COLLATE not implemented yet\n");
352 CheckDlgButton(hDlg
, chx1
, (lppd
->Flags
& PD_PRINTTOFILE
) ? 1 : 0);
353 if (lppd
->Flags
& PD_DISABLEPRINTTOFILE
)
354 EnableWindow(GetDlgItem(hDlg
, chx1
), FALSE
);
355 if (lppd
->Flags
& PD_HIDEPRINTTOFILE
)
356 ShowWindow(GetDlgItem(hDlg
, chx1
), SW_HIDE
);
361 if ((lppd
->Flags
& PD_SHOWHELP
)==0)
362 { /* hide if PD_SHOWHELP not specified */
363 ShowWindow(GetDlgItem(hDlg
, pshHelp
), SW_HIDE
);
366 TRACE(commdlg
, "succesful!\n");
371 /***********************************************************************
372 * PRINTDLG_ValidateAndDuplicateSettings [internal]
375 * updates the PrintDlg structure for returnvalues.
377 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
380 BOOL
PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg
,
381 PRINT_PTRA
* PrintStructures
)
383 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
385 /* check whether nFromPage and nToPage are within range defined by
386 * nMinPage and nMaxPage
388 if (IsDlgButtonChecked(hDlg
, rad3
) == BST_CHECKED
)
392 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
393 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
394 if (nFromPage
< lppd
->nMinPage
|| nFromPage
> lppd
->nMaxPage
||
395 nToPage
< lppd
->nMinPage
|| nToPage
> lppd
->nMaxPage
)
397 char TempBuffer
[256];
398 FIXME(commdlg
, "This MessageBox is not internationalised.");
399 sprintf(TempBuffer
, "This value lies not within Page range\n"
400 "Please enter a value between %d and %d",
401 lppd
->nMinPage
, lppd
->nMaxPage
);
402 MessageBoxA(hDlg
, TempBuffer
, "Print", MB_OK
| MB_ICONWARNING
);
405 lppd
->nFromPage
= nFromPage
;
406 lppd
->nToPage
= nToPage
;
409 if (IsDlgButtonChecked(hDlg
, chx1
) == BST_CHECKED
)
411 lppd
->Flags
|= PD_PRINTTOFILE
;
412 /* FIXME: insert code to set "FILE:" in DEVNAMES structure */
419 /***********************************************************************
420 * PRINTDLG_WMCommand [internal]
422 static LRESULT
PRINTDLG_WMCommand(HWND hDlg
, WPARAM wParam
,
423 LPARAM lParam
, PRINT_PTRA
* PrintStructures
)
425 LPPRINTDLGA lppd
= PrintStructures
->lpPrintDlg
;
427 switch (LOWORD(wParam
))
430 TRACE(commdlg
, " OK button was hit\n");
431 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg
, PrintStructures
) != TRUE
)
436 TRACE(commdlg
, " CANCEL button was hit\n");
437 EndDialog(hDlg
, FALSE
);
440 TRACE(commdlg
, " HELP button was hit\n");
441 SendMessageA(lppd
->hwndOwner
, PrintStructures
->HelpMessageID
,
442 (WPARAM
) hDlg
, (LPARAM
) lppd
);
444 case edt1
: /* from page nr editbox */
445 case edt2
: /* to page nr editbox */
446 if (HIWORD(wParam
)==EN_CHANGE
)
450 nFromPage
= GetDlgItemInt(hDlg
, edt1
, NULL
, FALSE
);
451 nToPage
= GetDlgItemInt(hDlg
, edt2
, NULL
, FALSE
);
452 if (nFromPage
!= lppd
->nFromPage
|| nToPage
!= lppd
->nToPage
)
453 CheckRadioButton(hDlg
, rad1
, rad3
, rad3
);
456 case psh2
: /* Properties button */
459 char PrinterName
[256];
460 GetDlgItemTextA(hDlg
, cmb4
, PrinterName
, 255);
461 if (OpenPrinterA(PrinterName
, &hPrinter
, NULL
))
463 PrinterProperties(hDlg
, hPrinter
);
464 ClosePrinter(hPrinter
);
467 WARN(commdlg
, " Call to OpenPrinter did not succeed!\n");
470 case cmb4
: /* Printer combobox */
471 if (HIWORD(wParam
)==CBN_SELCHANGE
)
472 PRINTDLG_UpdatePrinterInfoTexts(hDlg
, PrintStructures
);
475 printf("wParam: 0x%x ",wParam);
483 /***********************************************************************
484 * PrintDlgProcA [internal]
486 LRESULT WINAPI
PrintDlgProcA(HWND hDlg
, UINT uMsg
, WPARAM wParam
,
489 PRINT_PTRA
* PrintStructures
;
491 if (uMsg
!=WM_INITDIALOG
)
493 PrintStructures
= (PRINT_PTRA
*) GetWindowLongA(hDlg
, DWL_USER
);
494 if (!PrintStructures
)
499 PrintStructures
=(PRINT_PTRA
*) lParam
;
500 if (!PRINTDLG_WMInitDialog(hDlg
, wParam
, lParam
, PrintStructures
))
502 TRACE(commdlg
, "PRINTDLG_WMInitDialog returned FALSE\n");
505 MessageBoxA(hDlg
,"Warning: this dialog has no functionality yet!",
511 return PRINTDLG_WMCommand(hDlg
, wParam
, lParam
, PrintStructures
);
522 /***********************************************************************
523 * PrintDlgProc16 (COMMDLG.21)
525 LRESULT WINAPI
PrintDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
531 TRACE(commdlg
,"WM_INITDIALOG lParam=%08lX\n", lParam
);
532 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
538 EndDialog(hWnd
, TRUE
);
541 EndDialog(hWnd
, FALSE
);
550 /***********************************************************************
551 * PrintSetupDlgProc (COMMDLG.22)
553 LRESULT WINAPI
PrintSetupDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
559 TRACE(commdlg
,"WM_INITDIALOG lParam=%08lX\n", lParam
);
560 ShowWindow16(hWnd
, SW_SHOWNORMAL
);
565 EndDialog(hWnd
, TRUE
);
568 EndDialog(hWnd
, FALSE
);
579 /***********************************************************************
580 * PageSetupDlgA (COMDLG32.15)
582 BOOL WINAPI
PageSetupDlgA(LPPAGESETUPDLGA setupdlg
) {
583 FIXME(commdlg
,"(%p), stub!\n",setupdlg
);