Removed a few inter-dll dependencies.
[wine/multimedia.git] / dlls / commdlg / printdlg.c
blob7275cd68e857b89f5acb0fd6137e4580bc431a8e
1 /*
2 * COMMDLG - Print Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
7 */
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include "windef.h"
14 #include "winbase.h"
15 #include "wingdi.h"
16 #include "wine/winbase16.h"
17 #include "wine/winuser16.h"
18 #include "ldt.h"
19 #include "commdlg.h"
20 #include "dialog.h"
21 #include "dlgs.h"
22 #include "module.h"
23 #include "debugtools.h"
24 #include "winproc.h"
25 #include "cderr.h"
26 #include "winspool.h"
27 #include "winerror.h"
29 DEFAULT_DEBUG_CHANNEL(commdlg);
31 #include "cdlg.h"
34 /* This PRINTDLGA internal structure stores
35 * pointers to several throughout useful structures.
38 typedef struct
40 LPPRINTER_INFO_2A lpPrinterInfo;
41 UINT CurrentPrinter; /* used as lpPrinterInfo[CurrentPrinter] */
42 UINT DefaultPrinter; /* used as lpPrinterInfo[DefaultPrinter] */
43 DWORD NrOfPrinterInfoEntries;
44 LPPRINTDLGA lpPrintDlg;
45 UINT HelpMessageID;
46 HICON hCollateIcon; /* PrintDlg only */
47 HICON hNoCollateIcon; /* PrintDlg only */
48 HICON hPortraitIcon; /* PrintSetupDlg only */
49 HICON hLandscapeIcon; /* PrintSetupDlg only */
50 } PRINT_PTRA;
53 /* prototypes */
54 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg,
55 PRINT_PTRA* PrintStructures);
57 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
58 LPARAM lParam);
61 /***********************************************************************
62 * PrintDlg16 (COMMDLG.20)
64 * Displays the the PRINT dialog box, which enables the user to specify
65 * specific properties of the print job.
67 * RETURNS
68 * nonzero if the user pressed the OK button
69 * zero if the user cancelled the window or an error occurred
71 * BUGS
72 * * calls up to the 32-bit versions of the Dialogs, which look different
73 * * Customizing is *not* implemented.
75 BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lpPrint )
77 PRINTDLGA Print32;
78 BOOL16 ret;
80 memset(&Print32, 0, sizeof(Print32));
81 Print32.lStructSize = sizeof(Print32);
82 Print32.hwndOwner = lpPrint->hwndOwner;
83 Print32.hDevMode = lpPrint->hDevMode;
84 Print32.hDevNames = lpPrint->hDevNames;
85 Print32.Flags = lpPrint->Flags;
86 Print32.nFromPage = lpPrint->nFromPage;
87 Print32.nToPage = lpPrint->nToPage;
88 Print32.nMinPage = lpPrint->nMinPage;
89 Print32.nMaxPage = lpPrint->nMaxPage;
90 Print32.nCopies = lpPrint->nCopies;
91 Print32.hInstance = lpPrint->hInstance;
92 Print32.lCustData = lpPrint->lCustData;
93 if(lpPrint->lpfnPrintHook) {
94 FIXME("Need to allocate thunk\n");
95 /* Print32.lpfnPrintHook = lpPrint->lpfnPrintHook;*/
97 if(lpPrint->lpfnSetupHook) {
98 FIXME("Need to allocate thunk\n");
99 /* Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
101 Print32.lpPrintTemplateName = PTR_SEG_TO_LIN(lpPrint->lpPrintTemplateName);
102 Print32.lpSetupTemplateName = PTR_SEG_TO_LIN(lpPrint->lpSetupTemplateName);
103 Print32.hPrintTemplate = lpPrint->hPrintTemplate;
104 Print32.hSetupTemplate = lpPrint->hSetupTemplate;
106 ret = PrintDlgA(&Print32);
108 lpPrint->hDevMode = Print32.hDevMode;
109 lpPrint->hDevNames = Print32.hDevNames;
110 lpPrint->hDC = Print32.hDC;
111 lpPrint->Flags = Print32.Flags;
112 lpPrint->nFromPage = Print32.nFromPage;
113 lpPrint->nToPage = Print32.nToPage;
114 lpPrint->nCopies = Print32.nCopies;
116 return ret;
120 /***********************************************************************
121 * PrintDlgA (COMDLG32.17)
123 * Displays the the PRINT dialog box, which enables the user to specify
124 * specific properties of the print job.
126 * RETURNS
127 * nonzero if the user pressed the OK button
128 * zero if the user cancelled the window or an error occurred
130 * BUGS
131 * PrintDlg:
132 * * The Collate Icons do not display, even though they are in the code.
133 * * The Properties Button(s) should call DocumentPropertiesA().
134 * PrintSetupDlg:
135 * * The Paper Orientation Icons are not implemented yet.
136 * * The Properties Button(s) should call DocumentPropertiesA().
137 * * Settings are not yet taken from a provided DevMode or
138 * default printer settings.
140 BOOL WINAPI PrintDlgA(
141 LPPRINTDLGA lppd /* ptr to PRINTDLG32 struct */
144 /* My implementing strategy:
146 * step 1: display the dialog and implement the layout-flags
147 * step 2: enter valid information in the fields (e.g. real printers)
148 * step 3: fix the RETURN-TRUE-ALWAYS Fixme by checking lppd->Flags for
149 * PD_RETURNDEFAULT
150 * step 4: implement all other specs
151 * step 5: allow customisation of the dialog box
153 * current implementation is in step 4.
156 HWND hwndDialog;
157 BOOL bRet = FALSE;
158 LPCVOID ptr;
159 HANDLE hResInfo, hDlgTmpl;
160 HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
161 DWORD EnumBytesNeeded;
162 DWORD CopyOfEnumBytesNeeded;
163 PRINT_PTRA PrintStructures;
165 TRACE("(lppd: %p)\n", lppd);
166 PrintStructures.lpPrintDlg = lppd;
168 /* load Dialog resources,
169 * depending on Flags indicates Print32 or Print32_setup dialog
171 if (lppd->Flags & PD_PRINTSETUP)
172 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", RT_DIALOGA);
173 else
174 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", RT_DIALOGA);
175 if (!hResInfo)
177 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
178 return FALSE;
181 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
182 !(ptr = LockResource( hDlgTmpl )))
184 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
185 return FALSE;
188 /* load Collate ICONs */
189 PrintStructures.hCollateIcon =
190 LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
191 PrintStructures.hNoCollateIcon =
192 LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
193 if (PrintStructures.hCollateIcon==0 || PrintStructures.hNoCollateIcon==0)
195 ERR("no icon in resourcefile???");
196 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
197 return FALSE;
200 /* load Paper Orientation ICON */
201 /* FIXME: not implemented yet */
204 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
205 * must be registered and the Help button must be shown.
207 if (lppd->Flags & PD_SHOWHELP)
209 if((PrintStructures.HelpMessageID =
210 RegisterWindowMessageA(HELPMSGSTRING)) == 0)
212 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
213 return FALSE;
216 else
217 PrintStructures.HelpMessageID=0;
219 /* Use EnumPrinters to obtain a list of PRINTER_INFO_2A's
220 * and store a pointer to this list in our "global structure"
221 * as reference for the rest of the PrintDlg routines
223 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL,
224 0, &EnumBytesNeeded, &PrintStructures.NrOfPrinterInfoEntries);
225 CopyOfEnumBytesNeeded=EnumBytesNeeded+16;
226 PrintStructures.lpPrinterInfo = malloc(CopyOfEnumBytesNeeded*sizeof(char));
227 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2,
228 (LPBYTE)PrintStructures.lpPrinterInfo,
229 CopyOfEnumBytesNeeded, &EnumBytesNeeded,
230 &PrintStructures.NrOfPrinterInfoEntries);
232 /* Find the default printer.
233 * If not: display a warning message (unless PD_NOWARNING specified)
234 * and return PDERR_NODEFAULTPRN
236 /* FIXME: not implemented yet!!! */
237 if (!PrintStructures.NrOfPrinterInfoEntries)
239 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
240 return FALSE;
242 PrintStructures.CurrentPrinter=0;
243 PrintStructures.DefaultPrinter=0;
245 /* FIXME: Currently Unimplemented */
246 if (lppd->Flags & PD_NOWARNING)
248 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE);
249 WARN(": PD_NOWARNING Flag is not yet implemented.\n");
253 * FIXME : Should respond to TEMPLATE and HOOK flags here
254 * For now, only the standard dialog works.
256 if (lppd->Flags & (PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE |
257 PD_ENABLEPRINTTEMPLATEHANDLE | PD_ENABLESETUPHOOK |
258 PD_ENABLESETUPTEMPLATE|PD_ENABLESETUPTEMPLATEHANDLE))
259 FIXME(": unimplemented flag (ignored)\n");
262 * if lppd->Flags PD_RETURNDEFAULT is specified, the PrintDlg function
263 * does not display the dialog box, but returns with valid entries
264 * for hDevMode and hDevNames .
266 * According to MSDN, it is required that hDevMode and hDevNames equal
267 * zero if this flag is set.
269 if (lppd->Flags & PD_RETURNDEFAULT)
271 TRACE(" PD_RETURNDEFAULT: was requested to return printer info only.\n");
272 if (lppd->hDevMode!=0 || lppd->hDevNames !=0)
274 COMDLG32_SetCommDlgExtendedError(PDERR_INITFAILURE);
275 return(FALSE);
277 return(PRINTDLG_ValidateAndDuplicateSettings(0, &PrintStructures));
280 /* and create & process the dialog
282 if (lppd->Flags & PD_PRINTSETUP)
284 hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
285 (DLGPROC16)PrintSetupDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
287 else
289 hwndDialog= DIALOG_CreateIndirect(hInst, ptr, TRUE, lppd->hwndOwner,
290 (DLGPROC16)PrintDlgProcA, (LPARAM)&PrintStructures, WIN_PROC_32A );
292 if (hwndDialog)
293 bRet = DIALOG_DoDialogBox(hwndDialog, lppd->hwndOwner);
295 /* free memory & resources
297 free(PrintStructures.lpPrinterInfo);
298 DeleteObject(PrintStructures.hCollateIcon);
299 DeleteObject(PrintStructures.hNoCollateIcon);
300 /* FIXME: don't forget to delete the paper orientation icons here! */
302 TRACE(" exit! (%d)", bRet);
303 return bRet;
308 /***********************************************************************
309 * PrintDlgW (COMDLG32.18)
311 BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
313 FIXME("A really empty stub\n" );
314 return FALSE;
318 /***********************************************************************
319 * PRINTDLG_UpdatePrinterInfoTexts [internal]
321 static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, PRINT_PTRA* PrintStructures)
323 char StatusMsg[256];
324 char ResourceString[256];
325 int i;
326 LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
327 [PrintStructures->CurrentPrinter]);
329 /* Status Message */
330 StatusMsg[0]='\0';
331 /* FIXME: if default printer, add this first */
333 /* add all status messages */
334 for (i=0; i< 25; i++)
336 if (lpPi->Status & (1<<i))
338 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
339 ResourceString, 255);
340 strcat(StatusMsg,ResourceString);
343 /* append "ready" */
344 /* FIXME: status==ready must only be appended if really so.
345 but how to detect??? */
346 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
347 ResourceString, 255);
348 strcat(StatusMsg,ResourceString);
350 SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
352 /* set all other printer info texts */
353 SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)lpPi->pDriverName);
354 if (lpPi->pLocation != NULL && lpPi->pLocation[0]!='\0')
355 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pLocation);
356 else
357 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)lpPi->pPortName);
358 SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)lpPi->pComment);
361 /***********************************************************************
362 * PRINTSETUP32DLG_ComboBox [internal]
364 * Queries the DeviceCapabilities for a list of paper sizes / bin names
365 * and stores these in combobox cmb2 / cmb3.
366 * If there was already an item selected in the listbox,
367 * this item is looked up in the new list and reselected,
368 * the accompanying ID (for BinNames, this is the dmDefaultSource value)
369 * is returned
371 * If any entries in the listbox existed, these are deleted
373 * RETURNS:
374 * If an entry was selected and also exists in the new list,
375 * its corresponding ID is returned.
377 * returns zero on not found, error or SelectedName==NULL.
380 * BUGS:
381 * * the lookup of a new entry shouldn't be done on stringname,
382 * but on ID value, as some drivers name the same paper format
383 * differently (language differences, added paper size)
385 static short PRINTSETUP32DLG_UpdateComboBox(HWND hDlg,
386 int nIDComboBox,
387 char* PrinterName,
388 char* PortName)
390 int i;
391 DWORD NrOfEntries;
392 char* Names;
393 WORD* Sizes;
394 HGLOBAL hTempMem;
395 short returnvalue = 0;
396 char SelectedName[256];
397 int NamesSize;
398 int fwCapability_Names;
399 int fwCapability_Words;
401 TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
403 /* query the dialog box for the current selected value */
404 GetDlgItemTextA(hDlg, nIDComboBox, SelectedName, 255);
406 if (nIDComboBox == cmb2)
408 NamesSize = 64;
409 fwCapability_Names = DC_PAPERNAMES;
410 fwCapability_Words = DC_PAPERS;
412 else
414 nIDComboBox = cmb3;
415 NamesSize = 24;
416 fwCapability_Names = DC_BINNAMES;
417 fwCapability_Words = DC_BINS;
420 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
421 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
423 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
424 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
425 fwCapability_Names, NULL, NULL);
426 if (NrOfEntries == 0)
428 WARN(" no Name Entries found!\n");
430 hTempMem = GlobalAlloc(GMEM_MOVEABLE, NrOfEntries*NamesSize);
431 if (hTempMem == 0)
433 ERR(" Not enough memory to store Paper Size Names!\n");
434 return(0);
436 Names = GlobalLock(hTempMem);
437 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
438 fwCapability_Names, Names, NULL);
440 /* reset any current content in the combobox */
441 SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);
443 /* store new content */
444 for (i=0; i<NrOfEntries; i++)
446 SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
447 (LPARAM)(&Names[i*NamesSize]) );
450 /* select first entry */
451 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0,
452 (LPARAM)(&Names[0]) );
454 /* lookup SelectedName and select it, if found */
455 if (SelectedName[0] != '\0')
457 for (i=0; i<NrOfEntries; i++)
459 if (strcmp(&Names[i*NamesSize], SelectedName)==0)
461 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SELECTSTRING, 0,
462 (LPARAM)(SelectedName));
464 /* now, we need the i-th entry from the list of paper sizes */
465 /* let's recycle the memory */
466 DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words,
467 Names, NULL);
468 Sizes = (WORD*) Names;
469 returnvalue = Sizes[i];
470 break; /* quit for loop */
475 GlobalUnlock(hTempMem);
476 GlobalFree(hTempMem);
477 return(returnvalue);
482 /***********************************************************************
483 * PRINTDLG_WMInitDialog [internal]
485 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
486 PRINT_PTRA* PrintStructures)
488 int i;
489 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
490 LPPRINTER_INFO_2A lppi = PrintStructures->lpPrinterInfo;
491 PDEVMODEA pDevMode = lppi[PrintStructures->CurrentPrinter].pDevMode;
493 SetWindowLongA(hDlg, DWL_USER, lParam);
494 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
496 if (lppd->lStructSize != sizeof(PRINTDLGA))
498 FIXME("structure size failure !!!\n");
499 /* EndDialog (hDlg, 0);
500 return FALSE;
501 */ }
503 /* Fill Combobox according to info from PRINTER_INFO2A
504 * structure inside PrintStructures,
505 * select the default printer and generate an
506 * update-message to have the rest of the dialog box updated.
508 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
509 SendDlgItemMessageA(hDlg, cmb4, CB_ADDSTRING, 0,
510 (LPARAM)lppi[i].pPrinterName );
511 i=SendDlgItemMessageA(hDlg, cmb4, CB_SELECTSTRING,
512 (WPARAM) -1,
513 (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
514 SendDlgItemMessageA(hDlg, cmb4, CB_SETCURSEL,
515 (WPARAM)i, (LPARAM)0);
516 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
518 /* Flag processing to set the according buttons on/off and
519 * Initialise the various values
522 /* Print range (All/Range/Selection) */
523 /* FIXME: I allow more freedom than either Win95 or WinNT,
524 * which do not agree to what errors should be thrown or not
525 * in case nToPage or nFromPage is out-of-range.
527 if (lppd->nMaxPage < lppd->nMinPage)
528 lppd->nMaxPage = lppd->nMinPage;
529 if (lppd->nMinPage == lppd->nMaxPage)
530 lppd->Flags |= PD_NOPAGENUMS;
531 if (lppd->nToPage < lppd->nMinPage)
532 lppd->nToPage = lppd->nMinPage;
533 if (lppd->nToPage > lppd->nMaxPage)
534 lppd->nToPage = lppd->nMaxPage;
535 if (lppd->nFromPage < lppd->nMinPage)
536 lppd->nFromPage = lppd->nMinPage;
537 if (lppd->nFromPage > lppd->nMaxPage)
538 lppd->nFromPage = lppd->nMaxPage;
539 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
540 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
541 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */
542 if (lppd->Flags & PD_NOSELECTION)
543 EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
544 else
545 if (lppd->Flags & PD_SELECTION)
546 CheckRadioButton(hDlg, rad1, rad3, rad2);
547 if (lppd->Flags & PD_NOPAGENUMS)
549 EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
550 EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
551 EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
552 EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
553 EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
555 else
557 if (lppd->Flags & PD_PAGENUMS)
558 CheckRadioButton(hDlg, rad1, rad3, rad3);
560 /* "All xxx pages"... */
562 char resourcestr[64];
563 char result[64];
564 LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
565 resourcestr, 49);
566 sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
567 SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
570 /* Collate pages
572 * FIXME: The ico3 is not displayed for some reason. I don't know why.
574 if (lppd->Flags & PD_COLLATE)
576 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
577 (LPARAM)PrintStructures->hCollateIcon);
578 CheckDlgButton(hDlg, chx2, 1);
580 else
582 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
583 (LPARAM)PrintStructures->hNoCollateIcon);
584 CheckDlgButton(hDlg, chx2, 0);
587 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
588 lppd->Flags & PD_USEDEVMODECOPIES)
590 /* if printer doesn't support it: no Collate */
591 if (!(pDevMode->dmFields & DM_COLLATE))
593 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
594 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
598 /* nCopies */
599 if (lppd->hDevMode == 0)
601 SetDlgItemInt(hDlg, edt3, lppd->nCopies, FALSE);
603 else
605 SetDlgItemInt(hDlg, edt1, pDevMode->dmCopies, FALSE);
607 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
608 lppd->Flags & PD_USEDEVMODECOPIES)
610 /* if printer doesn't support it: no nCopies */
611 if (!(pDevMode->dmFields & DM_COPIES))
613 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
614 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
618 /* print to file */
619 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
620 if (lppd->Flags & PD_DISABLEPRINTTOFILE)
621 EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
622 if (lppd->Flags & PD_HIDEPRINTTOFILE)
623 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
625 /* help button */
626 if ((lppd->Flags & PD_SHOWHELP)==0)
627 { /* hide if PD_SHOWHELP not specified */
628 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
631 GlobalUnlock(lppd->hDevMode);
632 return TRUE;
638 /***********************************************************************
639 * PRINTSETUP32DLG_WMInitDialog [internal]
641 static LRESULT PRINTSETUP32DLG_WMInitDialog(HWND hDlg, WPARAM wParam,
642 LPARAM lParam,
643 PRINT_PTRA* PrintStructures)
645 int i;
646 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
647 LPPRINTER_INFO_2A lppi = PrintStructures->lpPrinterInfo;
649 SetWindowLongA(hDlg, DWL_USER, lParam);
650 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
652 if (lppd->lStructSize != sizeof(PRINTDLGA))
654 FIXME("structure size failure !!!\n");
655 /* EndDialog (hDlg, 0);
656 return FALSE;
657 */ }
659 /* Fill Combobox 1 according to info from PRINTER_INFO2A
660 * structure inside PrintStructures,
661 * select the default printer and generate an
662 * update-message to have the rest of the dialog box updated.
664 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
665 SendDlgItemMessageA(hDlg, cmb1, CB_ADDSTRING, 0,
666 (LPARAM)lppi[i].pPrinterName );
667 i=SendDlgItemMessageA(hDlg, cmb1, CB_SELECTSTRING,
668 (WPARAM) -1,
669 (LPARAM) lppi[PrintStructures->CurrentPrinter].pPrinterName);
670 SendDlgItemMessageA(hDlg, cmb1, CB_SETCURSEL,
671 (WPARAM)i, (LPARAM)0);
672 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
675 * fill both ComboBoxes with their info
677 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
678 lppi[PrintStructures->CurrentPrinter].pPrinterName,
679 lppi[PrintStructures->CurrentPrinter].pPortName);
680 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
681 lppi[PrintStructures->CurrentPrinter].pPrinterName,
682 lppi[PrintStructures->CurrentPrinter].pPortName);
685 * set the correct radiobutton & icon for print orientation
687 /* this should be dependent on a incoming DevMode
688 * (FIXME: not implemented yet) */
689 CheckRadioButton(hDlg, rad1, rad2, rad1);
690 /* also set the correct icon (FIXME: not implemented yet) */
692 return TRUE;
696 /***********************************************************************
697 * PRINTDLG_CreateDevNames [internal]
700 * creates a DevNames structure.
701 * RETURNS
702 * HGLOBAL to DevNames memory object on success or
703 * zero on faillure
705 static HGLOBAL PRINTDLG_CreateDevNames(
706 char* DeviceDriverName,
707 char* DeviceName,
708 char* OutputPort,
709 WORD Flags)
711 long size;
712 HGLOBAL hDevNames;
713 char* pDevNamesSpace;
714 char* pTempPtr;
715 LPDEVNAMES lpDevNames;
717 size = strlen(DeviceDriverName) +1
718 + strlen(DeviceName) + 1
719 + strlen(OutputPort) + 1
720 + sizeof(DEVNAMES);
722 hDevNames = GlobalAlloc(GMEM_MOVEABLE, size*sizeof(char));
723 if (hDevNames != 0)
725 pDevNamesSpace = GlobalLock(hDevNames);
726 lpDevNames = (LPDEVNAMES) pDevNamesSpace;
728 pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
729 strcpy(pTempPtr, DeviceDriverName);
730 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;
732 pTempPtr += strlen(DeviceDriverName) + 1;
733 strcpy(pTempPtr, DeviceName);
734 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
736 pTempPtr += strlen(DeviceName) + 1;
737 strcpy(pTempPtr, OutputPort);
738 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
740 lpDevNames->wDefault = Flags;
742 GlobalUnlock(hDevNames);
744 return(hDevNames);
750 /***********************************************************************
751 * PRINTDLG_ValidateAndDuplicateSettings [internal]
754 * updates the PrintDlg structure for returnvalues.
755 * (yep, the name was chosen a bit stupid...)
757 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
759 * RETURNS
760 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
761 * TRUE if succesful.
763 static BOOL PRINTDLG_ValidateAndDuplicateSettings(HWND hDlg,
764 PRINT_PTRA* PrintStructures)
766 LPPRINTER_INFO_2A lpPi = &(PrintStructures->lpPrinterInfo
767 [PrintStructures->CurrentPrinter]);
768 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
769 PDEVMODEA pDevMode;
771 if (hDlg!=0)
773 /* check whether nFromPage and nToPage are within range defined by
774 * nMinPage and nMaxPage
776 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED)
778 WORD nToPage;
779 WORD nFromPage;
780 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
781 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
782 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
783 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage)
785 char resourcestr[256];
786 char resultstr[256];
787 LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
788 resourcestr, 255);
789 sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
790 LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
791 resourcestr, 255);
792 MessageBoxA(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING);
793 return(FALSE);
795 lppd->nFromPage = nFromPage;
796 lppd->nToPage = nToPage;
800 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED)
802 lppd->Flags |= PD_PRINTTOFILE;
803 lpPi->pPortName = "FILE:";
806 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
808 FIXME("Collate lppd not yet implemented as output\n");
810 } /* end-of-if(hDlg!=0) */
813 * create or modify hDevMode
815 if (lppd->hDevMode == 0)
817 TRACE(" No hDevMode yet... Need to create my own\n");
818 /* FIXME: possible memory leak? Memory never freed again! */
819 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, lpPi->pDevMode->dmSize);
820 pDevMode = GlobalLock(lppd->hDevMode);
821 memcpy(pDevMode, lpPi->pDevMode, lpPi->pDevMode->dmSize);
823 else
825 FIXME(" already hDevMode... must adjust it... Not implemented yet\n");
826 pDevMode = GlobalLock(lppd->hDevMode);
829 /* If hDevNames already exists, trash it.
830 * But create a new one anyway
832 if (lppd->hDevNames != 0)
834 if ( (GlobalFlags(lppd->hDevNames)&0xFF) != 0)
835 ERR(" Tried to free hDevNames, but your application still has a"
836 " lock on hDevNames. Possible program crash...");
837 GlobalFree(lppd->hDevNames);
839 /* FIXME: The first entry of DevNames is fixed to "winspool",
840 * because I don't know of any printerdriver which doesn't return
841 * winspool there. But I guess they do exist...
843 lppd->hDevNames = PRINTDLG_CreateDevNames("winspool",
844 lpPi->pDriverName, lpPi->pPortName,
845 (PrintStructures->DefaultPrinter ==
846 PrintStructures->CurrentPrinter)?1:0);
848 /* set PD_Collate and nCopies */
849 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
850 lppd->Flags & PD_USEDEVMODECOPIES)
852 /* if one of the above flags was set, the application doesn't
853 * (want to) support multiple copies or collate...
855 lppd->Flags &= ~PD_COLLATE;
856 lppd->nCopies = 1;
857 /* if the printer driver supports it... store info there
858 * otherwise no collate & multiple copies !
860 if (pDevMode->dmFields & DM_COLLATE)
862 pDevMode->dmCollate = 0;
863 if (hDlg!=0)
864 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
865 pDevMode->dmCollate = 1;
867 if (pDevMode->dmFields & DM_COPIES)
869 pDevMode->dmCopies = 1;
870 if (hDlg!=0)
871 pDevMode->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
874 else
876 if (hDlg!=0)
878 /* set Collate & nCopies according to dialog */
879 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
880 lppd->Flags |= PD_COLLATE;
881 else
882 lppd->Flags &= ~PD_COLLATE;
883 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
885 else
887 /* stick to defaults */
888 lppd->Flags &= ~PD_COLLATE;
889 lppd->nCopies = 1;
894 GlobalUnlock(lppd->hDevMode);
896 return(TRUE);
901 /***********************************************************************
902 * PRINTSETUP32DLG_ValidateAndDuplicateSettings [internal]
905 * updates the PrintDlg structure for returnvalues.
906 * (yep, the name was chosen a bit stupid...)
908 * if hDlg equals zero, only hDevModes and hDevNames are adapted.
910 * RETURNS
911 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
912 * TRUE if succesful.
914 static BOOL PRINTSETUP32DLG_ValidateAndDuplicateSettings(HWND hDlg,
915 PRINT_PTRA* PrintStructures)
917 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
918 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
919 [PrintStructures->CurrentPrinter]);
920 PDEVMODEA pDevMode;
922 if (PRINTDLG_ValidateAndDuplicateSettings(0, PrintStructures)==FALSE)
923 return(FALSE);
925 pDevMode = GlobalLock(lppd->hDevMode);
927 /* set bin type and paper size to DevMode */
928 if (pDevMode->dmFields & DM_PAPERSIZE)
930 pDevMode->u1.s1.dmPaperSize = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2,
931 lppi->pPrinterName,
932 lppi->pPortName);
933 /* FIXME: should set dmPaperLength and dmPaperWidth also??? */
935 if (pDevMode->dmFields & DM_DEFAULTSOURCE)
936 pDevMode->dmDefaultSource = PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3,
937 lppi->pPrinterName,
938 lppi->pPortName);
940 /* set paper orientation to DevMode */
941 if (pDevMode->dmFields & DM_ORIENTATION)
943 if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED)
944 pDevMode->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
945 else
946 pDevMode->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
949 GlobalUnlock(lppd->hDevMode);
951 return(TRUE);
956 /***********************************************************************
957 * PRINTDLG_WMCommand [internal]
959 static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam,
960 LPARAM lParam, PRINT_PTRA* PrintStructures)
962 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
963 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
964 [PrintStructures->CurrentPrinter]);
967 switch (LOWORD(wParam))
969 case IDOK:
970 TRACE(" OK button was hit\n");
971 if (PRINTDLG_ValidateAndDuplicateSettings(hDlg, PrintStructures)!=TRUE)
972 return(FALSE);
973 DestroyWindow(hDlg);
974 return(TRUE);
975 case IDCANCEL:
976 TRACE(" CANCEL button was hit\n");
977 EndDialog(hDlg, FALSE);
978 return(FALSE);
979 case pshHelp:
980 TRACE(" HELP button was hit\n");
981 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
982 (WPARAM) hDlg, (LPARAM) lppd);
983 break;
984 case chx2: /* collate pages checkbox */
985 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
986 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
987 (LPARAM)PrintStructures->hCollateIcon);
988 else
989 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
990 (LPARAM)PrintStructures->hNoCollateIcon);
991 break;
992 case edt1: /* from page nr editbox */
993 case edt2: /* to page nr editbox */
994 if (HIWORD(wParam)==EN_CHANGE)
996 WORD nToPage;
997 WORD nFromPage;
998 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
999 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
1000 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
1001 CheckRadioButton(hDlg, rad1, rad3, rad3);
1003 break;
1004 case psh2: /* Properties button */
1006 /* HANDLE hPrinter;
1007 char PrinterName[256];
1008 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1009 if (OpenPrinterA(PrinterName, &hPrinter, NULL))
1011 PrinterProperties(hDlg, hPrinter);
1012 ClosePrinter(hPrinter);
1014 else
1015 WARN(" Call to OpenPrinter did not succeed!\n");
1016 break;
1017 */ MessageBoxA(hDlg, "Not implemented yet!", "PRINT", MB_OK);
1019 case cmb4: /* Printer combobox */
1020 if (HIWORD(wParam)==CBN_SELCHANGE)
1022 int i;
1023 char PrinterName[256];
1025 /* look the newly selected Printer up in
1026 * our array Printer_Info2As
1028 GetDlgItemTextA(hDlg, cmb4, PrinterName, 255);
1029 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1031 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName,
1032 PrinterName)==0)
1033 break;
1035 PrintStructures->CurrentPrinter = i;
1036 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1037 lppi = &(PrintStructures->lpPrinterInfo
1038 [PrintStructures->CurrentPrinter]);
1039 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE ||
1040 lppd->Flags & PD_USEDEVMODECOPIES)
1042 /* if printer doesn't support it: no nCopies */
1043 if (!(lppi->pDevMode->dmFields & DM_COPIES))
1045 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
1046 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
1048 else
1050 EnableWindow(GetDlgItem(hDlg, edt3), TRUE);
1051 EnableWindow(GetDlgItem(hDlg, stc5), TRUE);
1053 /* if printer doesn't support it: no Collate */
1054 if (!(lppi->pDevMode->dmFields & DM_COPIES))
1056 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
1057 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
1059 else
1061 EnableWindow(GetDlgItem(hDlg, ico3), TRUE);
1062 EnableWindow(GetDlgItem(hDlg, chx2), TRUE);
1067 break;
1069 return FALSE;
1073 /***********************************************************************
1074 * PRINTSETUP32DLG_WMCommand [internal]
1076 static LRESULT PRINTSETUP32DLG_WMCommand(HWND hDlg, WPARAM wParam,
1077 LPARAM lParam, PRINT_PTRA* PrintStructures)
1079 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
1080 LPPRINTER_INFO_2A lppi = &(PrintStructures->lpPrinterInfo
1081 [PrintStructures->CurrentPrinter]);
1084 switch (LOWORD(wParam))
1086 case IDOK:
1087 TRACE(" OK button was hit\n");
1088 if (PRINTSETUP32DLG_ValidateAndDuplicateSettings(hDlg, PrintStructures) != TRUE)
1089 return(FALSE);
1090 DestroyWindow(hDlg);
1091 return(TRUE);
1092 case IDCANCEL:
1093 TRACE(" CANCEL button was hit\n");
1094 EndDialog(hDlg, FALSE);
1095 return(FALSE);
1096 case pshHelp:
1097 TRACE(" HELP button was hit\n");
1098 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
1099 (WPARAM) hDlg, (LPARAM) lppd);
1100 break;
1101 case psh2: /* Properties button */
1102 MessageBoxA(hDlg, "Not implemented yet!", "PRINT SETUP", MB_OK);
1103 break;
1104 case cmb1: /* Printer combobox */
1105 if (HIWORD(wParam)==CBN_SELCHANGE)
1107 int i;
1108 char Name[256];
1110 /* look the newly selected Printer up in
1111 * our array Printer_Info2As
1113 GetDlgItemTextA(hDlg, cmb1, Name, 255);
1114 for (i=0; i < PrintStructures->NrOfPrinterInfoEntries; i++)
1116 if (strcmp(PrintStructures->lpPrinterInfo[i].pPrinterName,
1117 Name)==0)
1118 break;
1120 PrintStructures->CurrentPrinter = i;
1121 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures);
1122 lppi = &(PrintStructures->
1123 lpPrinterInfo[PrintStructures->CurrentPrinter]);
1125 /* Update both ComboBoxes to the items available for the new
1126 * printer. Keep the same entry selected, if possible
1128 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb2, lppi->pPrinterName,
1129 lppi->pPortName);
1130 PRINTSETUP32DLG_UpdateComboBox(hDlg, cmb3, lppi->pPrinterName,
1131 lppi->pPortName);
1133 break;
1135 return FALSE;
1139 /***********************************************************************
1140 * PrintDlgProcA [internal]
1142 LRESULT WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1143 LPARAM lParam)
1145 PRINT_PTRA* PrintStructures;
1146 LRESULT res=FALSE;
1147 if (uMsg!=WM_INITDIALOG)
1149 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
1150 if (!PrintStructures)
1151 return FALSE;
1153 else
1155 PrintStructures=(PRINT_PTRA*) lParam;
1156 if (!PRINTDLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures))
1158 TRACE("PRINTDLG_WMInitDialog returned FALSE\n");
1159 return FALSE;
1162 switch (uMsg)
1164 case WM_COMMAND:
1165 return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1166 case WM_DESTROY:
1167 return FALSE;
1170 return res;
1176 /***********************************************************************
1177 * PrintDlgProc16 (COMMDLG.21)
1179 LRESULT WINAPI PrintDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1180 LPARAM lParam)
1182 switch (wMsg)
1184 case WM_INITDIALOG:
1185 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1186 ShowWindow16(hWnd, SW_SHOWNORMAL);
1187 return (TRUE);
1188 case WM_COMMAND:
1189 switch (wParam)
1191 case IDOK:
1192 EndDialog(hWnd, TRUE);
1193 return(TRUE);
1194 case IDCANCEL:
1195 EndDialog(hWnd, FALSE);
1196 return(TRUE);
1198 return(FALSE);
1200 return FALSE;
1204 /***********************************************************************
1205 * PrintSetupDlgProc (COMMDLG.22)
1207 LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1208 LPARAM lParam)
1210 switch (wMsg)
1212 case WM_INITDIALOG:
1213 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1214 ShowWindow16(hWnd, SW_SHOWNORMAL);
1215 return (TRUE);
1216 case WM_COMMAND:
1217 switch (wParam) {
1218 case IDOK:
1219 EndDialog(hWnd, TRUE);
1220 return(TRUE);
1221 case IDCANCEL:
1222 EndDialog(hWnd, FALSE);
1223 return(TRUE);
1225 return(FALSE);
1227 return FALSE;
1231 /***********************************************************************
1232 * PrintSetupDlgProcA [???]
1234 * FIXME:
1235 * note: I don't know whether this function actually is allowed
1236 * to exist (i.e. is exported/overrideable from the DLL)
1237 * For now, this function is local only.
1238 * If necessary, this call can be merged with PrintDlgProcA,
1239 * as it is very similar.
1241 LRESULT WINAPI PrintSetupDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1242 LPARAM lParam)
1244 PRINT_PTRA* PrintStructures;
1245 LRESULT res=FALSE;
1246 if (uMsg!=WM_INITDIALOG)
1248 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
1249 if (!PrintStructures)
1250 return FALSE;
1252 else
1254 PrintStructures=(PRINT_PTRA*) lParam;
1255 if (!PRINTSETUP32DLG_WMInitDialog(hDlg, wParam, lParam, PrintStructures))
1257 TRACE("PRINTSETUP32DLG_WMInitDialog returned FALSE\n");
1258 return FALSE;
1261 switch (uMsg)
1263 case WM_COMMAND:
1264 return PRINTSETUP32DLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
1265 case WM_DESTROY:
1266 return FALSE;
1269 return res;
1276 /***********************************************************************
1277 * PageSetupDlgA (COMDLG32.15)
1279 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
1280 FIXME("(%p), stub!\n",setupdlg);
1281 return FALSE;