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"
21 #include "debugtools.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("(%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("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(": 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(": 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(": 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(": 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("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("WM_INITDIALOG lParam=%08lX\n", lParam);
285 if (lppd->lStructSize != sizeof(PRINTDLGA))
287 FIXME("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("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("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("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(" OK button was hit\n");
431 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg, PrintStructures) != TRUE)
436 TRACE(" CANCEL button was hit\n");
437 EndDialog(hDlg, FALSE);
440 TRACE(" 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(" 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("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("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("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("(%p), stub!\n",setupdlg);