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"
27 DEFAULT_DEBUG_CHANNEL(commdlg)
32 /* This PRINTDLGA internal structure stores
33 * pointers to several throughout useful structures.
38 LPPRINTER_INFO_2A lpPrinterInfo;
39 UINT CurrentPrinter; /* used as lpPrinterInfo[CurrentPrinter] */
40 UINT DefaultPrinter; /* used as lpPrinterInfo[DefaultPrinter] */
41 DWORD NrOfPrinterInfoEntries;
42 LPPRINTDLGA lpPrintDlg;
44 HICON hCollateIcon; /* PrintDlg only */
45 HICON hNoCollateIcon; /* PrintDlg only */
46 HICON hPortraitIcon; /* PrintSetupDlg only */
47 HICON hLandscapeIcon; /* PrintSetupDlg only */
52 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg,
53 PRINT_PTRA* PrintStructures);
55 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
59 /***********************************************************************
60 * PrintDlg16 (COMMDLG.20)
62 * Displays the the PRINT dialog box, which enables the user to specify
63 * specific properties of the print job.
66 * nonzero if the user pressed the OK button
67 * zero if the user cancelled the window or an error occurred
70 * * calls up to the 32-bit versions of the Dialogs, which look different
71 * * Customizing is *not* implemented.
73 BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lpPrint )
78 memset(&Print32, 0, sizeof(Print32));
79 Print32.lStructSize = sizeof(Print32);
80 Print32.hwndOwner = lpPrint->hwndOwner;
81 Print32.hDevMode = lpPrint->hDevMode;
82 Print32.hDevNames = lpPrint->hDevNames;
83 Print32.Flags = lpPrint->Flags;
84 Print32.nFromPage = lpPrint->nFromPage;
85 Print32.nToPage = lpPrint->nToPage;
86 Print32.nMinPage = lpPrint->nMinPage;
87 Print32.nMaxPage = lpPrint->nMaxPage;
88 Print32.nCopies = lpPrint->nCopies;
89 Print32.hInstance = lpPrint->hInstance;
90 Print32.lCustData = lpPrint->lCustData;
91 if(lpPrint->lpfnPrintHook) {
92 FIXME("Need to allocate thunk\n");
93 /* Print32.lpfnPrintHook = lpPrint->lpfnPrintHook;*/
95 if(lpPrint->lpfnSetupHook) {
96 FIXME("Need to allocate thunk\n");
97 /* Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
99 Print32.lpPrintTemplateName = PTR_SEG_TO_LIN(lpPrint->lpPrintTemplateName);
100 Print32.lpSetupTemplateName = PTR_SEG_TO_LIN(lpPrint->lpSetupTemplateName);
101 Print32.hPrintTemplate = lpPrint->hPrintTemplate;
102 Print32.hSetupTemplate = lpPrint->hSetupTemplate;
104 ret = PrintDlgA(&Print32);
106 lpPrint->hDevMode = Print32.hDevMode;
107 lpPrint->hDevNames = Print32.hDevNames;
108 lpPrint->hDC = Print32.hDC;
109 lpPrint->Flags = Print32.Flags;
110 lpPrint->nFromPage = Print32.nFromPage;
111 lpPrint->nToPage = Print32.nToPage;
112 lpPrint->nCopies = Print32.nCopies;
118 /***********************************************************************
119 * PrintDlgA (COMDLG32.17)
121 * Displays the the PRINT dialog box, which enables the user to specify
122 * specific properties of the print job.
125 * nonzero if the user pressed the OK button
126 * zero if the user cancelled the window or an error occurred
130 * * The Collate Icons do not display, even though they are in the code.
131 * * The Properties Button(s) should call DocumentPropertiesA().
133 * * The Paper Orientation Icons are not implemented yet.
134 * * The Properties Button(s) should call DocumentPropertiesA().
135 * * Settings are not yet taken from a provided DevMode or
136 * default printer settings.
138 BOOL WINAPI PrintDlgA(
139 LPPRINTDLGA lppd /* ptr to PRINTDLG32 struct */
142 /* My implementing strategy:
144 * step 1: display the dialog and implement the layout-flags
145 * step 2: enter valid information in the fields (e.g. real printers)
146 * step 3: fix the RETURN-TRUE-ALWAYS Fixme by checking lppd->Flags for
148 * step 4: implement all other specs
149 * step 5: allow customisation of the dialog box
151 * current implementation is in step 4.
157 HANDLE hResInfo, hDlgTmpl;
158 HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
159 DWORD EnumBytesNeeded;
160 DWORD CopyOfEnumBytesNeeded;
161 PRINT_PTRA PrintStructures;
163 TRACE("(lppd: %p)\n", lppd);
164 PrintStructures.lpPrintDlg = lppd;
166 /* load Dialog resources,
167 * depending on Flags indicates Print32 or Print32_setup dialog
169 if (lppd->Flags & PD_PRINTSETUP)
170 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", RT_DIALOGA);
172 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", RT_DIALOGA);
175 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
179 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
180 !(ptr = LockResource( hDlgTmpl )))
182 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
186 /* load Collate ICONs */
187 PrintStructures.hCollateIcon =
188 LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
189 PrintStructures.hNoCollateIcon =
190 LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
191 if (PrintStructures.hCollateIcon==0 || PrintStructures.hNoCollateIcon==0)
193 ERR("no icon in resourcefile???");
194 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
198 /* load Paper Orientation ICON */
199 /* FIXME: not implemented yet */
202 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
203 * must be registered and the Help button must be shown.
205 if (lppd->Flags & PD_SHOWHELP)
207 if((PrintStructures.HelpMessageID =
208 RegisterWindowMessageA(HELPMSGSTRING)) == 0)
210 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
215 PrintStructures.HelpMessageID=0;
217 /* Use EnumPrinters to obtain a list of PRINTER_INFO_2A's
218 * and store a pointer to this list in our "global structure"
219 * as reference for the rest of the PrintDlg routines
221 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL,
222 0, &EnumBytesNeeded, &PrintStructures.NrOfPrinterInfoEntries);
223 CopyOfEnumBytesNeeded=EnumBytesNeeded+16;
224 PrintStructures.lpPrinterInfo = malloc(CopyOfEnumBytesNeeded*sizeof(char));
225 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2,
226 (LPBYTE)PrintStructures.lpPrinterInfo,
227 CopyOfEnumBytesNeeded, &EnumBytesNeeded,
228 &PrintStructures.NrOfPrinterInfoEntries);
230 /* Find the default printer.
231 * If not: display a warning message (unless PD_NOWARNING specified)
232 * and return PDERR_NODEFAULTPRN
234 /* FIXME: not implemented yet!!! */
235 if (!PrintStructures.NrOfPrinterInfoEntries)
237 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
240 PrintStructures.CurrentPrinter=0;
241 PrintStructures.DefaultPrinter=0;
243 /* FIXME: Currently Unimplemented */
244 if (lppd->Flags & PD_NOWARNING)
246 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE);
247 WARN(": PD_NOWARNING Flag is not yet implemented.\n");
251 * FIXME : Should respond to TEMPLATE and HOOK flags here
252 * For now, only the standard dialog works.
254 if (lppd->Flags & (PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE |
255 PD_ENABLEPRINTTEMPLATEHANDLE | PD_ENABLESETUPHOOK |
256 PD_ENABLESETUPTEMPLATE|PD_ENABLESETUPTEMPLATEHANDLE))
257 FIXME(": unimplemented flag (ignored)\n");
260 * if lppd->Flags PD_RETURNDEFAULT is specified, the PrintDlg function
261 * does not display the dialog box, but returns with valid entries
262 * for hDevMode and hDevNames .
264 * According to MSDN, it is required that hDevMode and hDevNames equal
265 * zero if this flag is set.
267 if (lppd->Flags & PD_RETURNDEFAULT)
269 TRACE(" PD_RETURNDEFAULT: was requested to return printer info only.\n");
270 if (lppd->hDevMode!=0 || lppd->hDevNames !=0)
272 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE);
275 return(PRINTDLG_ValidateAndDuplicateSettings(0, &PrintStructures));
278 /* and create & process the dialog
280 if (lppd->Flags & PD_PRINTSETUP)
282 hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
283 (DLGPROC16)PrintSetupDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
287 hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
288 (DLGPROC16)PrintDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
291 bRet = DIALOG_DoDialogBox(hwndDialog, lppd->hwndOwner);
293 /* free memory & resources
295 free(PrintStructures.lpPrinterInfo);
296 DeleteObject(PrintStructures.hCollateIcon);
297 DeleteObject(PrintStructures.hNoCollateIcon);
298 /* FIXME: don't forget to delete the paper orientation icons here! */
300 TRACE(" exit! (%d)", bRet);
306 /***********************************************************************
307 * PrintDlg32W (COMDLG32.18)
309 BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
311 FIXME("A really empty stub\n" );
316 /***********************************************************************
317 * PRINTDLG_UpdatePrinterInfoTexts [internal]
319 void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, PRINT_PTRA* PrintStructures)
322 char ResourceString[256];
324 LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
325 [PrintStructures->CurrentPrinter]);
329 /* FIXME: if default printer, add this first */
331 /* add all status messages */
332 for (i=0; i< 25; i++)
334 if (lpPi->Status & (1<<i))
336 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
337 ResourceString, 255);
338 strcat(StatusMsg,ResourceString);
342 /* FIXME: status==ready must only be appended if really so.
343 but how to detect??? */
344 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
345 ResourceString, 255);
346 strcat(StatusMsg,ResourceString);
348 SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
350 /* set all other printer info texts */
351 SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)lpPi->pDriverName);
352 if (lpPi->pLocation != NULL && lpPi->pLocation[0]!='\0')
353 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pLocation);
355 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pPortName);
356 SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)lpPi->pComment);
359 /***********************************************************************
360 * PRINTSETUP32DLG_ComboBox [internal]
362 * Queries the DeviceCapabilities for a list of paper sizes / bin names
363 * and stores these in combobox cmb2 / cmb3.
364 * If there was already an item selected in the listbox,
365 * this item is looked up in the new list and reselected,
366 * the accompanying ID (for BinNames, this is the dmDefaultSource value)
369 * If any entries in the listbox existed, these are deleted
372 * If an entry was selected and also exists in the new list,
373 * its corresponding ID is returned.
375 * returns zero on not found, error or SelectedName==NULL.
379 * * the lookup of a new entry shouldn't be done on stringname,
380 * but on ID value, as some drivers name the same paper format
381 * differently (language differences, added paper size)
383 short PRINTSETUP32DLG_UpdateComboBox(HWND hDlg,
393 short returnvalue = 0;
394 char SelectedName[256];
396 int fwCapability_Names;
397 int fwCapability_Words;
399 TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
401 /* query the dialog box for the current selected value */
402 GetDlgItemTextA(hDlg, nIDComboBox, SelectedName, 255);
404 if (nIDComboBox == cmb2)
407 fwCapability_Names = DC_PAPERNAMES;
408 fwCapability_Words = DC_PAPERS;
414 fwCapability_Names = DC_BINNAMES;
415 fwCapability_Words = DC_BINS;
418 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
419 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
421 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
422 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
423 fwCapability_Names, NULL, NULL);
424 if (NrOfEntries == 0)
426 WARN(" no Name Entries found!\n");
428 hTempMem = GlobalAlloc(GMEM_MOVEABLE, NrOfEntries*NamesSize);
431 ERR(" Not enough memory to store Paper Size Names!\n");
434 Names = GlobalLock(hTempMem);
435 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
436 fwCapability_Names, Names, NULL);
438 /* reset any current content in the combobox */
439 SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);
441 /* store new content */
442 for (i=0; i<NrOfEntries; i++)
444 SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
445 (LPARAM)(&Names[i*NamesSize]) );
448 /* select first entry */
449 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0,
450 (LPARAM)(&Names[0]) );
452 /* lookup SelectedName and select it, if found */
453 if (SelectedName[0] != '\0')
455 for (i=0; i<NrOfEntries; i++)
457 if (strcmp(&Names[i*NamesSize], SelectedName)==0)
459 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0,
460 (LPARAM)(SelectedName));
462 /* now, we need the i-th entry from the list of paper sizes */
463 /* let's recycle the memory */
464 DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words,
466 Sizes = (WORD*) Names;
467 returnvalue = Sizes[i];
468 break; /* quit for loop */
473 GlobalUnlock(hTempMem);
474 GlobalFree(hTempMem);
480 /***********************************************************************
481 * PRINTDLG_WMInitDialog [internal]
483 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
484 PRINT_PTRA* PrintStructures)
487 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
488 LPPRINTER_INFO_2A lppi = PrintStructures->lpPrinterInfo;
489 PDEVMODEA pDevMode = lppi[PrintStructures->CurrentPrinter].pDevMode;
491 SetWindowLongA(hDlg, DWL_USER, lParam);
492 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
494 if (lppd->lStructSize != sizeof(PRINTDLGA))
496 FIXME("structure size failure !!!\n");
497 /* EndDialog (hDlg, 0);
501 /* Fill Combobox according to info from PRINTER_INFO2A
502 * structure inside PrintStructures,
503 * select the default printer and generate an
504 * update-message to have the rest of the dialog box updated.
506 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
507 SendDlgItemMessageA(hDlg, cmb4, CB_ADDSTRING, 0,
508 (LPARAM)lppi[i].pPrinterName );
509 i=SendDlgItemMessageA(hDlg, cmb4, CB_SELECTSTRING,
511 (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
512 SendDlgItemMessageA(hDlg, cmb4, CB_SETCURSEL,
513 (WPARAM)i, (LPARAM)0);
514 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
516 /* Flag processing to set the according buttons on/off and
517 * Initialise the various values
520 /* Print range (All/Range/Selection) */
521 /* FIXME: I allow more freedom than either Win95 or WinNT,
522 * which do not agree to what errors should be thrown or not
523 * in case nToPage or nFromPage is out-of-range.
525 if (lppd->nMaxPage < lppd->nMinPage)
526 lppd->nMaxPage = lppd->nMinPage;
527 if (lppd->nMinPage == lppd->nMaxPage)
528 lppd->Flags |= PD_NOPAGENUMS;
529 if (lppd->nToPage < lppd->nMinPage)
530 lppd->nToPage = lppd->nMinPage;
531 if (lppd->nToPage > lppd->nMaxPage)
532 lppd->nToPage = lppd->nMaxPage;
533 if (lppd->nFromPage < lppd->nMinPage)
534 lppd->nFromPage = lppd->nMinPage;
535 if (lppd->nFromPage > lppd->nMaxPage)
536 lppd->nFromPage = lppd->nMaxPage;
537 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
538 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
539 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */
540 if (lppd->Flags & PD_NOSELECTION)
541 EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
543 if (lppd->Flags & PD_SELECTION)
544 CheckRadioButton(hDlg, rad1, rad3, rad2);
545 if (lppd->Flags & PD_NOPAGENUMS)
547 EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
548 EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
549 EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
550 EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
551 EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
555 if (lppd->Flags & PD_PAGENUMS)
556 CheckRadioButton(hDlg, rad1, rad3, rad3);
558 /* "All xxx pages"... */
560 char resourcestr[64];
562 LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
564 sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
565 SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
570 * FIXME: The ico3 is not displayed for some reason. I don't know why.
572 if (lppd->Flags & PD_COLLATE)
574 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
575 (LPARAM)PrintStructures->hCollateIcon);
576 CheckDlgButton(hDlg, chx2, 1);
580 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
581 (LPARAM)PrintStructures->hNoCollateIcon);
582 CheckDlgButton(hDlg, chx2, 0);
585 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
586 lppd->Flags & PD_USEDEVMODECOPIES)
588 /* if printer doesn't support it: no Collate */
589 if (!(pDevMode->dmFields & DM_COLLATE))
591 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
592 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
597 if (lppd->hDevMode == 0)
599 SetDlgItemInt(hDlg, edt3, lppd->nCopies, FALSE);
603 SetDlgItemInt(hDlg, edt1, pDevMode->dmCopies, FALSE);
605 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
606 lppd->Flags & PD_USEDEVMODECOPIES)
608 /* if printer doesn't support it: no nCopies */
609 if (!(pDevMode->dmFields & DM_COPIES))
611 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
612 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
617 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
618 if (lppd->Flags & PD_DISABLEPRINTTOFILE)
619 EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
620 if (lppd->Flags & PD_HIDEPRINTTOFILE)
621 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
624 if ((lppd->Flags & PD_SHOWHELP)==0)
625 { /* hide if PD_SHOWHELP not specified */
626 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
629 GlobalUnlock(lppd->hDevMode);
636 /***********************************************************************
637 * PRINTSETUP32DLG_WMInitDialog [internal]
639 static LRESULT PRINTSETUP32DLG_WMInitDialog(HWND hDlg, WPARAM wParam,
641 PRINT_PTRA* PrintStructures)
644 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
645 LPPRINTER_INFO_2A lppi = PrintStructures->lpPrinterInfo;
647 SetWindowLongA(hDlg, DWL_USER, lParam);
648 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
650 if (lppd->lStructSize != sizeof(PRINTDLGA))
652 FIXME("structure size failure !!!\n");
653 /* EndDialog (hDlg, 0);
657 /* Fill Combobox 1 according to info from PRINTER_INFO2A
658 * structure inside PrintStructures,
659 * select the default printer and generate an
660 * update-message to have the rest of the dialog box updated.
662 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
663 SendDlgItemMessageA(hDlg, cmb1, CB_ADDSTRING, 0,
664 (LPARAM)lppi[i].pPrinterName );
665 i=SendDlgItemMessageA(hDlg, cmb1, CB_SELECTSTRING,
667 (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
668 SendDlgItemMessageA(hDlg, cmb1, CB_SETCURSEL,
669 (WPARAM)i, (LPARAM)0);
670 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
673 * fill both ComboBoxes with their info
675 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
676 lppi[PrintStructures->CurrentPrinter].pPrinterName,
677 lppi[PrintStructures->CurrentPrinter].pPortName);
678 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
679 lppi[PrintStructures->CurrentPrinter].pPrinterName,
680 lppi[PrintStructures->CurrentPrinter].pPortName);
683 * set the correct radiobutton & icon for print orientation
685 /* this should be dependent on a incoming DevMode
686 * (FIXME: not implemented yet) */
687 CheckRadioButton(hDlg, rad1, rad2, rad1);
688 /* also set the correct icon (FIXME: not implemented yet) */
694 /***********************************************************************
695 * PRINTDLG_CreateDevNames [internal]
698 * creates a DevNames structure.
700 * HGLOBAL to DevNames memory object on success or
703 HGLOBAL PRINTDLG_CreateDevNames(
704 char* DeviceDriverName,
711 char* pDevNamesSpace;
713 LPDEVNAMES lpDevNames;
715 size = strlen(DeviceDriverName) +1
716 + strlen(DeviceName) + 1
717 + strlen(OutputPort) + 1
720 hDevNames = GlobalAlloc(GMEM_MOVEABLE, size*sizeof(char));
723 pDevNamesSpace = GlobalLock(hDevNames);
724 lpDevNames = (LPDEVNAMES) pDevNamesSpace;
726 pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
727 strcpy(pTempPtr, DeviceDriverName);
728 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;
730 pTempPtr += strlen(DeviceDriverName) + 1;
731 strcpy(pTempPtr, DeviceName);
732 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
734 pTempPtr += strlen(DeviceName) + 1;
735 strcpy(pTempPtr, OutputPort);
736 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
738 lpDevNames->wDefault = Flags;
740 GlobalUnlock(hDevNames);
748 /***********************************************************************
749 * PRINTDLG_ValidateAndDuplicateSettings [internal]
752 * updates the PrintDlg structure for returnvalues.
753 * (yep, the name was chosen a bit stupid...)
755 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
758 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
761 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg,
762 PRINT_PTRA* PrintStructures)
764 LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
765 [PrintStructures->CurrentPrinter]);
766 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
771 /* check whether nFromPage and nToPage are within range defined by
772 * nMinPage and nMaxPage
774 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED)
778 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
779 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
780 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
781 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage)
783 char resourcestr[256];
785 LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
787 sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
788 LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
790 MessageBoxA(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING);
793 lppd->nFromPage = nFromPage;
794 lppd->nToPage = nToPage;
798 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED)
800 lppd->Flags |= PD_PRINTTOFILE;
801 lpPi->pPortName = "FILE:";
804 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
806 FIXME("Collate lppd not yet implemented as output\n");
808 } /* end-of-if(hDlg!=0) */
811 * create or modify hDevMode
813 if (lppd->hDevMode == 0)
815 TRACE(" No hDevMode yet... Need to create my own\n");
816 /* FIXME: possible memory leak? Memory never freed again! */
817 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, lpPi->pDevMode->dmSize);
818 pDevMode = GlobalLock(lppd->hDevMode);
819 memcpy(pDevMode, lpPi->pDevMode, lpPi->pDevMode->dmSize);
823 FIXME(" already hDevMode... must adjust it... Not implemented yet\n");
824 pDevMode = GlobalLock(lppd->hDevMode);
827 /* If hDevNames already exists, trash it.
828 * But create a new one anyway
830 if (lppd->hDevNames != 0)
832 if ( (GlobalFlags(lppd->hDevNames)&0xFF) != 0)
833 ERR(" Tried to free hDevNames, but your application still has a"
834 " lock on hDevNames. Possible program crash...");
835 GlobalFree(lppd->hDevNames);
837 /* FIXME: The first entry of DevNames is fixed to "winspool",
838 * because I don't know of any printerdriver which doesn't return
839 * winspool there. But I guess they do exist...
841 lppd->hDevNames = PRINTDLG_CreateDevNames("winspool",
842 lpPi->pDriverName, lpPi->pPortName,
843 (PrintStructures->DefaultPrinter ==
844 PrintStructures->CurrentPrinter)?1:0);
846 /* set PD_Collate and nCopies */
847 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
848 lppd->Flags & PD_USEDEVMODECOPIES)
850 /* if one of the above flags was set, the application doesn't
851 * (want to) support multiple copies or collate...
853 lppd->Flags &= ~PD_COLLATE;
855 /* if the printer driver supports it... store info there
856 * otherwise no collate & multiple copies !
858 if (pDevMode->dmFields & DM_COLLATE)
860 pDevMode->dmCollate = 0;
862 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
863 pDevMode->dmCollate = 1;
865 if (pDevMode->dmFields & DM_COPIES)
867 pDevMode->dmCopies = 1;
869 pDevMode->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
876 /* set Collate & nCopies according to dialog */
877 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
878 lppd->Flags |= PD_COLLATE;
880 lppd->Flags &= ~PD_COLLATE;
881 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
885 /* stick to defaults */
886 lppd->Flags &= ~PD_COLLATE;
892 GlobalUnlock(lppd->hDevMode);
899 /***********************************************************************
900 * PRINTSETUP32DLG_ValidateAndDuplicateSettings [internal]
903 * updates the PrintDlg structure for returnvalues.
904 * (yep, the name was chosen a bit stupid...)
906 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
909 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
912 static BOOL PRINTSETUP32DLG_ValidateAndDuplicateSettings(HWND hDlg,
913 PRINT_PTRA* PrintStructures)
915 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
916 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
917 [PrintStructures->CurrentPrinter]);
920 if (PRINTDLG_ValidateAndDuplicateSettings(0, PrintStructures)==FALSE)
923 pDevMode = GlobalLock(lppd->hDevMode);
925 /* set bin type and paper size to DevMode */
926 if (pDevMode->dmFields & DM_PAPERSIZE)
928 pDevMode->u1.s1.dmPaperSize = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
931 /* FIXME: should set dmPaperLength and dmPaperWidth also??? */
933 if (pDevMode->dmFields & DM_DEFAULTSOURCE)
934 pDevMode->dmDefaultSource = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
938 /* set paper orientation to DevMode */
939 if (pDevMode->dmFields & DM_ORIENTATION)
941 if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED)
942 pDevMode->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
944 pDevMode->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
947 GlobalUnlock(lppd->hDevMode);
954 /***********************************************************************
955 * PRINTDLG_WMCommand [internal]
957 static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam,
958 LPARAM lParam, PRINT_PTRA* PrintStructures)
960 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
961 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
962 [PrintStructures->CurrentPrinter]);
965 switch (LOWORD(wParam))
968 TRACE(" OK button was hit\n");
969 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg, PrintStructures)!=TRUE)
974 TRACE(" CANCEL button was hit\n");
975 EndDialog(hDlg, FALSE);
978 TRACE(" HELP button was hit\n");
979 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
980 (WPARAM) hDlg, (LPARAM) lppd);
982 case chx2: /* collate pages checkbox */
983 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
984 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
985 (LPARAM)PrintStructures->hCollateIcon);
987 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
988 (LPARAM)PrintStructures->hNoCollateIcon);
990 case edt1: /* from page nr editbox */
991 case edt2: /* to page nr editbox */
992 if (HIWORD(wParam)==EN_CHANGE)
996 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
997 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
998 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
999 CheckRadioButton(hDlg, rad1, rad3, rad3);
1002 case psh2: /* Properties button */
1005 char PrinterName[256];
1006 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1007 if (OpenPrinterA(PrinterName, &hPrinter, NULL))
1009 PrinterProperties(hDlg, hPrinter);
1010 ClosePrinter(hPrinter);
1013 WARN(" Call to OpenPrinter did not succeed!\n");
1015 */ MessageBoxA(hDlg, "Not implemented yet!", "PRINT", MB_OK);
1017 case cmb4: /* Printer combobox */
1018 if (HIWORD(wParam)==CBN_SELCHANGE)
1021 char PrinterName[256];
1023 /* look the newly selected Printer up in
1024 * our array Printer_Info2As
1026 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1027 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1029 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName,
1033 PrintStructures->CurrentPrinter = i;
1034 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1035 lppi = &(PrintStructures->lpPrinterInfo
1036 [PrintStructures->CurrentPrinter]);
1037 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
1038 lppd->Flags & PD_USEDEVMODECOPIES)
1040 /* if printer doesn't support it: no nCopies */
1041 if (!(lppi->pDevMode->dmFields & DM_COPIES))
1043 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
1044 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
1048 EnableWindow(GetDlgItem(hDlg, edt3), TRUE);
1049 EnableWindow(GetDlgItem(hDlg, stc5), TRUE);
1051 /* if printer doesn't support it: no Collate */
1052 if (!(lppi->pDevMode->dmFields & DM_COPIES))
1054 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
1055 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
1059 EnableWindow(GetDlgItem(hDlg, ico3), TRUE);
1060 EnableWindow(GetDlgItem(hDlg, chx2), TRUE);
1071 /***********************************************************************
1072 * PRINTSETUP32DLG_WMCommand [internal]
1074 static LRESULT PRINTSETUP32DLG_WMCommand(HWND hDlg, WPARAM wParam,
1075 LPARAM lParam, PRINT_PTRA* PrintStructures)
1077 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
1078 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
1079 [PrintStructures->CurrentPrinter]);
1082 switch (LOWORD(wParam))
1085 TRACE(" OK button was hit\n");
1086 if (PRINTSETUP32DLG_ValidateAndDuplicateSettings(hDlg, PrintStructures) != TRUE)
1088 DestroyWindow(hDlg);
1091 TRACE(" CANCEL button was hit\n");
1092 EndDialog(hDlg, FALSE);
1095 TRACE(" HELP button was hit\n");
1096 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
1097 (WPARAM) hDlg, (LPARAM) lppd);
1099 case psh2: /* Properties button */
1100 MessageBoxA(hDlg, "Not implemented yet!", "PRINT SETUP", MB_OK);
1102 case cmb1: /* Printer combobox */
1103 if (HIWORD(wParam)==CBN_SELCHANGE)
1108 /* look the newly selected Printer up in
1109 * our array Printer_Info2As
1111 GetDlgItemTextA(hDlg, cmb1, Name, 255);
1112 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1114 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName,
1118 PrintStructures->CurrentPrinter = i;
1119 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1120 lppi = &(PrintStructures->
1121 lpPrinterInfo[PrintStructures->CurrentPrinter]);
1123 /* Update both ComboBoxes to the items available for the new
1124 * printer. Keep the same entry selected, if possible
1126 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2, lppi->pPrinterName,
1128 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3, lppi->pPrinterName,
1137 /***********************************************************************
1138 * PrintDlgProcA [internal]
1140 LRESULT WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1143 PRINT_PTRA* PrintStructures;
1145 if (uMsg!=WM_INITDIALOG)
1147 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
1148 if (!PrintStructures)
1153 PrintStructures=(PRINT_PTRA*) lParam;
1154 if (!PRINTDLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures))
1156 TRACE("PRINTDLG_WMInitDialog returned FALSE\n");
1163 return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1174 /***********************************************************************
1175 * PrintDlgProc16 (COMMDLG.21)
1177 LRESULT WINAPI PrintDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1183 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1184 ShowWindow16(hWnd, SW_SHOWNORMAL);
1190 EndDialog(hWnd, TRUE);
1193 EndDialog(hWnd, FALSE);
1202 /***********************************************************************
1203 * PrintSetupDlgProc (COMMDLG.22)
1205 LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1211 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1212 ShowWindow16(hWnd, SW_SHOWNORMAL);
1217 EndDialog(hWnd, TRUE);
1220 EndDialog(hWnd, FALSE);
1229 /***********************************************************************
1230 * PrintSetupDlgProcA [???]
1233 * note: I don't know whether this function actually is allowed
1234 * to exist (i.e. is exported/overrideable from the DLL)
1235 * For now, this function is local only.
1236 * If necessary, this call can be merged with PrintDlgProcA,
1237 * as it is very similar.
1239 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1242 PRINT_PTRA* PrintStructures;
1244 if (uMsg!=WM_INITDIALOG)
1246 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
1247 if (!PrintStructures)
1252 PrintStructures=(PRINT_PTRA*) lParam;
1253 if (!PRINTSETUP32DLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures))
1255 TRACE("PRINTSETUP32DLG_WMInitDialog returned FALSE\n");
1262 return PRINTSETUP32DLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1274 /***********************************************************************
1275 * PageSetupDlgA (COMDLG32.15)
1277 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
1278 FIXME("(%p), stub!\n",setupdlg);