Fixed handling of DialogBoxIndirectParamA return value.
[wine/hacks.git] / dlls / commdlg / printdlg.c
blob726556129aa5f6d781448f3b8e43a4d606d71a45
1 /*
2 * COMMDLG - Print Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
7 * Copyright 2000 Huw D M Davies
8 */
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/wingdi16.h"
17 #include "winuser.h"
18 #include "wine/winuser16.h"
19 #include "ldt.h"
20 #include "commdlg.h"
21 #include "dlgs.h"
22 #include "debugtools.h"
23 #include "cderr.h"
24 #include "winspool.h"
25 #include "winerror.h"
27 DEFAULT_DEBUG_CHANNEL(commdlg);
29 #include "cdlg.h"
32 /* This PRINTDLGA internal structure stores
33 * pointers to several throughout useful structures.
36 typedef struct
38 LPDEVMODEA lpDevMode;
39 LPPRINTDLGA lpPrintDlg;
40 LPPRINTER_INFO_2A lpPrinterInfo;
41 UINT HelpMessageID;
42 HICON hCollateIcon; /* PrintDlg only */
43 HICON hNoCollateIcon; /* PrintDlg only */
44 HICON hPortraitIcon; /* PrintSetupDlg only */
45 HICON hLandscapeIcon; /* PrintSetupDlg only */
46 } PRINT_PTRA;
48 /* Debugiging info */
49 static struct pd_flags {
50 DWORD flag;
51 LPSTR name;
52 } pd_flags[] = {
53 {PD_SELECTION, "PD_SELECTION "},
54 {PD_PAGENUMS, "PD_PAGENUMS "},
55 {PD_NOSELECTION, "PD_NOSELECTION "},
56 {PD_NOPAGENUMS, "PD_NOPAGENUMS "},
57 {PD_COLLATE, "PD_COLLATE "},
58 {PD_PRINTTOFILE, "PD_PRINTTOFILE "},
59 {PD_PRINTSETUP, "PD_PRINTSETUP "},
60 {PD_NOWARNING, "PD_NOWARNING "},
61 {PD_RETURNDC, "PD_RETURNDC "},
62 {PD_RETURNIC, "PD_RETURNIC "},
63 {PD_RETURNDEFAULT, "PD_RETURNDEFAULT "},
64 {PD_SHOWHELP, "PD_SHOWHELP "},
65 {PD_ENABLEPRINTHOOK, "PD_ENABLEPRINTHOOK "},
66 {PD_ENABLESETUPHOOK, "PD_ENABLESETUPHOOK "},
67 {PD_ENABLEPRINTTEMPLATE, "PD_ENABLEPRINTTEMPLATE "},
68 {PD_ENABLESETUPTEMPLATE, "PD_ENABLESETUPTEMPLATE "},
69 {PD_ENABLEPRINTTEMPLATEHANDLE, "PD_ENABLEPRINTTEMPLATEHANDLE "},
70 {PD_ENABLESETUPTEMPLATEHANDLE, "PD_ENABLESETUPTEMPLATEHANDLE "},
71 {PD_USEDEVMODECOPIES, "PD_USEDEVMODECOPIES[ANDCOLLATE] "},
72 {PD_DISABLEPRINTTOFILE, "PD_DISABLEPRINTTOFILE "},
73 {PD_HIDEPRINTTOFILE, "PD_HIDEPRINTTOFILE "},
74 {PD_NONETWORKBUTTON, "PD_NONETWORKBUTTON "},
75 {-1, NULL}
79 /***********************************************************************
80 * PRINTDLG_GetDefaultPrinterName
82 * Returns the default printer name in buf.
83 * Even under WinNT/2000 default printer is retrieved via GetProfileString -
84 * these entries are mapped somewhere in the registry rather than win.ini.
86 * Returns TRUE on success else FALSE
88 static BOOL PRINTDLG_GetDefaultPrinterName(LPSTR buf, DWORD len)
90 char *ptr;
92 if(!GetProfileStringA("windows", "device", "", buf, len))
93 return FALSE;
94 if((ptr = strchr(buf, ',')) == NULL)
95 return FALSE;
96 *ptr = '\0';
97 return TRUE;
100 /***********************************************************************
101 * PRINTDLG_OpenDefaultPrinter
103 * Returns a winspool printer handle to the default printer in *hprn
104 * Caller must call ClosePrinter on the handle
106 * Returns TRUE on success else FALSE
108 static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn)
110 char buf[260];
111 if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
112 return FALSE;
113 return OpenPrinterA(buf, hprn, NULL);
116 /***********************************************************************
117 * PRINTDLG_SetUpPrinterListCombo
119 * Initializes printer list combox.
120 * hDlg: HWND of dialog
121 * id: Control id of combo
122 * name: Name of printer to select
124 * Initializes combo with list of available printers. Selects printer 'name'
125 * If name is NULL or does not exist select the default printer.
127 * Returns number of printers added to list.
129 static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name)
131 DWORD needed, num;
132 INT i;
133 LPPRINTER_INFO_2A pi;
134 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num);
135 pi = HeapAlloc(GetProcessHeap(), 0, needed);
136 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed,
137 &num);
139 for(i = 0; i < num; i++) {
140 SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0,
141 (LPARAM)pi[i].pPrinterName );
143 HeapFree(GetProcessHeap(), 0, pi);
144 if(!name ||
145 (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1,
146 (LPARAM)name)) == CB_ERR) {
148 char buf[260];
149 TRACE("Can't find '%s' in printer list so trying to find default\n",
150 name);
151 if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
152 return num;
153 i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
154 if(i == CB_ERR)
155 TRACE("Can't find default printer in printer list\n");
157 SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0);
158 return num;
161 /***********************************************************************
162 * PRINTDLG_CreateDevNames [internal]
165 * creates a DevNames structure.
167 * (NB. when we handle unicode the offsets will be in wchars).
169 static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, char* DeviceDriverName,
170 char* DeviceName, char* OutputPort)
172 long size;
173 char* pDevNamesSpace;
174 char* pTempPtr;
175 LPDEVNAMES lpDevNames;
176 char buf[260];
178 size = strlen(DeviceDriverName) + 1
179 + strlen(DeviceName) + 1
180 + strlen(OutputPort) + 1
181 + sizeof(DEVNAMES);
183 if(*hmem)
184 *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE);
185 else
186 *hmem = GlobalAlloc(GMEM_MOVEABLE, size);
187 if (*hmem == 0)
188 return FALSE;
190 pDevNamesSpace = GlobalLock(*hmem);
191 lpDevNames = (LPDEVNAMES) pDevNamesSpace;
193 pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
194 strcpy(pTempPtr, DeviceDriverName);
195 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;
197 pTempPtr += strlen(DeviceDriverName) + 1;
198 strcpy(pTempPtr, DeviceName);
199 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
201 pTempPtr += strlen(DeviceName) + 1;
202 strcpy(pTempPtr, OutputPort);
203 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
205 PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf));
206 lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0;
207 GlobalUnlock(*hmem);
208 return TRUE;
211 /***********************************************************************
212 * PRINTDLG_UpdatePrintDlg [internal]
215 * updates the PrintDlg structure for returnvalues.
217 * RETURNS
218 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
219 * TRUE if succesful.
221 static BOOL PRINTDLG_UpdatePrintDlg(HWND hDlg,
222 PRINT_PTRA* PrintStructures)
224 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
225 PDEVMODEA lpdm = PrintStructures->lpDevMode;
226 LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo;
229 if(!lpdm) return FALSE;
232 if(!(lppd->Flags & PD_PRINTSETUP)) {
233 /* check whether nFromPage and nToPage are within range defined by
234 * nMinPage and nMaxPage
236 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
237 WORD nToPage;
238 WORD nFromPage;
239 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
240 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
241 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
242 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
243 char resourcestr[256];
244 char resultstr[256];
245 LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
246 resourcestr, 255);
247 sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
248 LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
249 resourcestr, 255);
250 MessageBoxA(hDlg, resultstr, resourcestr,
251 MB_OK | MB_ICONWARNING);
252 return FALSE;
254 lppd->nFromPage = nFromPage;
255 lppd->nToPage = nToPage;
258 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */
259 lppd->Flags |= PD_PRINTTOFILE;
260 pi->pPortName = "FILE:";
263 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */
264 FIXME("Collate lppd not yet implemented as output\n");
267 /* set PD_Collate and nCopies */
268 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
269 /* The application doesn't support multiple copies or collate...
271 lppd->Flags &= ~PD_COLLATE;
272 lppd->nCopies = 1;
273 /* if the printer driver supports it... store info there
274 * otherwise no collate & multiple copies !
276 if (lpdm->dmFields & DM_COLLATE)
277 lpdm->dmCollate =
278 (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED);
279 if (lpdm->dmFields & DM_COPIES)
280 lpdm->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
281 } else {
282 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
283 lppd->Flags |= PD_COLLATE;
284 else
285 lppd->Flags &= ~PD_COLLATE;
286 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
289 return TRUE;
293 /************************************************************************
294 * PRINTDLG_SetUpPaperComboBox
296 * Initialize either the papersize or inputslot combos of the Printer Setup
297 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
298 * We also try to re-select the old selection.
300 static BOOL PRINTDLG_SetUpPaperComboBox(HWND hDlg,
301 int nIDComboBox,
302 char* PrinterName,
303 char* PortName,
304 LPDEVMODEA dm)
306 int i;
307 DWORD NrOfEntries;
308 char* Names;
309 WORD* Words;
310 DWORD Sel;
311 WORD oldWord = 0;
312 int NamesSize;
313 int fwCapability_Names;
314 int fwCapability_Words;
316 TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
318 /* query the dialog box for the current selected value */
319 Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0);
320 if(Sel != CB_ERR) {
321 oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, Sel,
325 if (nIDComboBox == cmb2) {
326 NamesSize = 64;
327 fwCapability_Names = DC_PAPERNAMES;
328 fwCapability_Words = DC_PAPERS;
329 } else {
330 nIDComboBox = cmb3;
331 NamesSize = 24;
332 fwCapability_Names = DC_BINNAMES;
333 fwCapability_Words = DC_BINS;
336 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
337 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
339 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
340 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
341 fwCapability_Names, NULL, dm);
342 if (NrOfEntries == 0)
343 WARN("no Name Entries found!\n");
345 if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm)
346 != NrOfEntries) {
347 ERR("Number of caps is different\n");
348 NrOfEntries = 0;
351 Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*NamesSize);
352 Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD));
353 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
354 fwCapability_Names, Names, dm);
355 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
356 fwCapability_Words, (LPSTR)Words, dm);
358 /* reset any current content in the combobox */
359 SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);
361 /* store new content */
362 for (i = 0; i < NrOfEntries; i++) {
363 DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
364 (LPARAM)(&Names[i*NamesSize]) );
365 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
366 Words[i]);
369 /* Look for old selection - can't do this is previous loop since
370 item order will change as more items are added */
371 Sel = 0;
372 for (i = 0; i < NrOfEntries; i++) {
373 if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) ==
374 oldWord) {
375 Sel = i;
376 break;
379 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0);
381 HeapFree(GetProcessHeap(),0,Words);
382 HeapFree(GetProcessHeap(),0,Names);
383 return TRUE;
386 /***********************************************************************
387 * PRINTDLG_UpdatePrinterInfoTexts [internal]
389 static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, LPPRINTER_INFO_2A pi)
391 char StatusMsg[256];
392 char ResourceString[256];
393 int i;
395 /* Status Message */
396 StatusMsg[0]='\0';
398 /* add all status messages */
399 for (i = 0; i < 25; i++) {
400 if (pi->Status & (1<<i)) {
401 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
402 ResourceString, 255);
403 strcat(StatusMsg,ResourceString);
406 /* append "ready" */
407 /* FIXME: status==ready must only be appended if really so.
408 but how to detect? */
409 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
410 ResourceString, 255);
411 strcat(StatusMsg,ResourceString);
413 SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
415 /* set all other printer info texts */
416 SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)pi->pDriverName);
417 if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
418 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation);
419 else
420 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName);
421 SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)pi->pComment);
422 return;
426 /*******************************************************************
428 * PRINTDLG_ChangePrinter
431 static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name,
432 PRINT_PTRA *PrintStructures)
434 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
435 LPDEVMODEA lpdm = NULL;
436 LONG dmSize;
437 DWORD needed;
438 HANDLE hprn;
440 if(PrintStructures->lpPrinterInfo)
441 HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo);
442 if(!OpenPrinterA(name, &hprn, NULL)) {
443 ERR("Can't open printer %s\n", name);
444 return FALSE;
446 GetPrinterA(hprn, 2, NULL, 0, &needed);
447 PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed);
448 GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
449 &needed);
450 ClosePrinter(hprn);
452 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures->lpPrinterInfo);
454 if(PrintStructures->lpDevMode) {
455 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
456 PrintStructures->lpDevMode = NULL;
459 dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0);
460 if(dmSize == -1) {
461 ERR("DocumentProperties fails on %s\n", debugstr_a(name));
462 return FALSE;
464 PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize);
465 dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL,
466 DM_OUT_BUFFER);
467 if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) &&
468 !strcmp(lpdm->dmDeviceName,
469 PrintStructures->lpDevMode->dmDeviceName)) {
470 /* Supplied devicemode matches current printer so try to use it */
471 DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm,
472 DM_OUT_BUFFER | DM_IN_BUFFER);
474 if(lpdm)
475 GlobalUnlock(lppd->hDevMode);
477 lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */
479 if(!(lppd->Flags & PD_PRINTSETUP)) {
480 /* Print range (All/Range/Selection) */
481 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
482 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
483 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */
484 if (lppd->Flags & PD_NOSELECTION)
485 EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
486 else
487 if (lppd->Flags & PD_SELECTION)
488 CheckRadioButton(hDlg, rad1, rad3, rad2);
489 if (lppd->Flags & PD_NOPAGENUMS) {
490 EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
491 EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
492 EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
493 EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
494 EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
495 } else {
496 if (lppd->Flags & PD_PAGENUMS)
497 CheckRadioButton(hDlg, rad1, rad3, rad3);
499 /* "All xxx pages"... */
501 char resourcestr[64];
502 char result[64];
503 LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
504 resourcestr, 49);
505 sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
506 SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
509 /* Collate pages
511 * FIXME: The ico3 is not displayed for some reason. I don't know why.
513 if (lppd->Flags & PD_COLLATE) {
514 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
515 (LPARAM)PrintStructures->hCollateIcon);
516 CheckDlgButton(hDlg, chx2, 1);
517 } else {
518 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
519 (LPARAM)PrintStructures->hNoCollateIcon);
520 CheckDlgButton(hDlg, chx2, 0);
523 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
524 /* if printer doesn't support it: no Collate */
525 if (!(lpdm->dmFields & DM_COLLATE)) {
526 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
527 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
531 /* nCopies */
532 if (lppd->hDevMode == 0)
533 SetDlgItemInt(hDlg, edt3, lppd->nCopies, FALSE);
534 else
535 SetDlgItemInt(hDlg, edt3, lpdm->dmCopies, FALSE);
537 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
538 /* if printer doesn't support it: no nCopies */
539 if (!(lpdm->dmFields & DM_COPIES)) {
540 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
541 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
545 /* print to file */
546 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
547 if (lppd->Flags & PD_DISABLEPRINTTOFILE)
548 EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
549 if (lppd->Flags & PD_HIDEPRINTTOFILE)
550 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
552 } else { /* PD_PRINTSETUP */
553 PRINTDLG_SetUpPaperComboBox(hDlg, cmb2,
554 PrintStructures->lpPrinterInfo->pPrinterName,
555 PrintStructures->lpPrinterInfo->pPortName,
556 lpdm);
557 PRINTDLG_SetUpPaperComboBox(hDlg, cmb3,
558 PrintStructures->lpPrinterInfo->pPrinterName,
559 PrintStructures->lpPrinterInfo->pPortName,
560 lpdm);
561 CheckRadioButton(hDlg, rad1, rad2,
562 (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT) ?
563 rad1: rad2);
566 /* help button */
567 if ((lppd->Flags & PD_SHOWHELP)==0) {
568 /* hide if PD_SHOWHELP not specified */
569 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
572 return TRUE;
575 /***********************************************************************
576 * PRINTDLG_WMInitDialog [internal]
578 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam,
579 PRINT_PTRA* PrintStructures)
581 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
582 DEVNAMES *pdn;
583 DEVMODEA *pdm;
584 char *name = NULL;
585 UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
587 /* load Collate ICONs */
588 PrintStructures->hCollateIcon =
589 LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
590 PrintStructures->hNoCollateIcon =
591 LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
592 if(PrintStructures->hCollateIcon == 0 ||
593 PrintStructures->hNoCollateIcon == 0) {
594 ERR("no icon in resourcefile\n");
595 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
596 EndDialog(hDlg, FALSE);
599 /* load Paper Orientation ICON */
600 /* FIXME: not implemented yet */
603 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
604 * must be registered and the Help button must be shown.
606 if (lppd->Flags & PD_SHOWHELP) {
607 if((PrintStructures->HelpMessageID =
608 RegisterWindowMessageA(HELPMSGSTRING)) == 0) {
609 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
610 return FALSE;
612 } else
613 PrintStructures->HelpMessageID = 0;
615 /* FIXME: I allow more freedom than either Win95 or WinNT,
616 * which do not agree to what errors should be thrown or not
617 * in case nToPage or nFromPage is out-of-range.
619 if (lppd->nMaxPage < lppd->nMinPage)
620 lppd->nMaxPage = lppd->nMinPage;
621 if (lppd->nMinPage == lppd->nMaxPage)
622 lppd->Flags |= PD_NOPAGENUMS;
623 if (lppd->nToPage < lppd->nMinPage)
624 lppd->nToPage = lppd->nMinPage;
625 if (lppd->nToPage > lppd->nMaxPage)
626 lppd->nToPage = lppd->nMaxPage;
627 if (lppd->nFromPage < lppd->nMinPage)
628 lppd->nFromPage = lppd->nMinPage;
629 if (lppd->nFromPage > lppd->nMaxPage)
630 lppd->nFromPage = lppd->nMaxPage;
632 /* Fill Combobox
634 pdn = GlobalLock(lppd->hDevNames);
635 pdm = GlobalLock(lppd->hDevMode);
636 if(pdn)
637 name = (char*)pdn + pdn->wDeviceOffset;
638 else if(pdm)
639 name = pdm->dmDeviceName;
640 PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name);
641 if(pdm) GlobalUnlock(lppd->hDevMode);
642 if(pdn) GlobalUnlock(lppd->hDevNames);
644 /* Now find selected printer and update rest of dlg */
645 name = HeapAlloc(GetProcessHeap(),0,256);
646 GetDlgItemTextA(hDlg, comboID, name, 255);
647 PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
648 HeapFree(GetProcessHeap(),0,name);
650 return TRUE;
653 /***********************************************************************
654 * PRINTDLG_WMCommand [internal]
656 static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam,
657 LPARAM lParam, PRINT_PTRA* PrintStructures)
659 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
660 UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
661 LPDEVMODEA lpdm = PrintStructures->lpDevMode;
663 switch (LOWORD(wParam)) {
664 case IDOK:
665 TRACE(" OK button was hit\n");
666 if (PRINTDLG_UpdatePrintDlg(hDlg, PrintStructures)!=TRUE)
667 return(FALSE);
668 EndDialog(hDlg, TRUE);
669 return(TRUE);
671 case IDCANCEL:
672 TRACE(" CANCEL button was hit\n");
673 EndDialog(hDlg, FALSE);
674 return(FALSE);
676 case pshHelp:
677 TRACE(" HELP button was hit\n");
678 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
679 (WPARAM) hDlg, (LPARAM) lppd);
680 break;
682 case chx2: /* collate pages checkbox */
683 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
684 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
685 (LPARAM)PrintStructures->hCollateIcon);
686 else
687 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
688 (LPARAM)PrintStructures->hNoCollateIcon);
689 break;
690 case edt1: /* from page nr editbox */
691 case edt2: /* to page nr editbox */
692 if (HIWORD(wParam)==EN_CHANGE) {
693 WORD nToPage;
694 WORD nFromPage;
695 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
696 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
697 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
698 CheckRadioButton(hDlg, rad1, rad3, rad3);
700 break;
701 case psh2: /* Properties button */
703 HANDLE hPrinter;
704 char PrinterName[256];
706 GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255);
707 if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) {
708 WARN(" Call to OpenPrinter did not succeed!\n");
709 break;
711 DocumentPropertiesA(hDlg, hPrinter, PrinterName,
712 PrintStructures->lpDevMode,
713 PrintStructures->lpDevMode,
714 DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
715 ClosePrinter(hPrinter);
716 break;
719 case cmb1:
720 case cmb4: /* Printer combobox */
721 if (HIWORD(wParam)==CBN_SELCHANGE) {
722 char PrinterName[256];
723 GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255);
724 PRINTDLG_ChangePrinter(hDlg, PrinterName, PrintStructures);
726 break;
728 case cmb2: /* Papersize */
730 DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
731 if(Sel != CB_ERR)
732 lpdm->u1.s1.dmPaperSize = SendDlgItemMessageA(hDlg, cmb2,
733 CB_GETITEMDATA,
734 Sel, 0);
736 break;
738 case cmb3: /* Bin */
740 DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0);
741 if(Sel != CB_ERR)
742 lpdm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3,
743 CB_GETITEMDATA, Sel,
746 break;
748 return FALSE;
751 /***********************************************************************
752 * PrintDlgProcA [internal]
754 BOOL WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
755 LPARAM lParam)
757 PRINT_PTRA* PrintStructures;
758 LRESULT res=FALSE;
760 if (uMsg!=WM_INITDIALOG) {
761 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
762 if (!PrintStructures)
763 return FALSE;
764 } else {
765 PrintStructures = (PRINT_PTRA*) lParam;
766 SetWindowLongA(hDlg, DWL_USER, lParam);
767 res = PRINTDLG_WMInitDialog(hDlg, wParam, PrintStructures);
769 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
770 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg,
771 wParam,
772 (LPARAM)PrintStructures->lpPrintDlg);
774 return res;
777 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
778 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam,
779 lParam);
780 if(res) return res;
783 switch (uMsg) {
784 case WM_COMMAND:
785 return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
787 case WM_DESTROY:
788 DestroyIcon(PrintStructures->hCollateIcon);
789 DestroyIcon(PrintStructures->hNoCollateIcon);
790 /* FIXME: don't forget to delete the paper orientation icons here! */
792 return FALSE;
794 return res;
797 /************************************************************
799 * PRINTDLG_GetDlgTemplate
802 static HGLOBAL PRINTDLG_GetDlgTemplate(PRINTDLGA *lppd)
804 HGLOBAL hDlgTmpl, hResInfo;
806 if (lppd->Flags & PD_PRINTSETUP) {
807 if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) {
808 hDlgTmpl = lppd->hSetupTemplate;
809 } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
810 hResInfo = FindResourceA(lppd->hInstance,
811 lppd->lpSetupTemplateName, RT_DIALOGA);
812 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
813 } else {
814 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP",
815 RT_DIALOGA);
816 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
818 } else {
819 if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) {
820 hDlgTmpl = lppd->hPrintTemplate;
821 } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) {
822 hResInfo = FindResourceA(lppd->hInstance,
823 lppd->lpPrintTemplateName,
824 RT_DIALOGA);
825 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
826 } else {
827 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32",
828 RT_DIALOGA);
829 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
832 return hDlgTmpl;
835 /***********************************************************************
837 * PRINTDLG_CreateDC
840 static BOOL PRINTDLG_CreateDC(LPPRINTDLGA lppd)
842 DEVNAMES *pdn = GlobalLock(lppd->hDevNames);
843 DEVMODEA *pdm = GlobalLock(lppd->hDevMode);
845 if(lppd->Flags & PD_RETURNDC) {
846 lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset,
847 (char*)pdn + pdn->wDeviceOffset,
848 (char*)pdn + pdn->wOutputOffset,
849 pdm );
850 } else if(lppd->Flags & PD_RETURNIC) {
851 lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset,
852 (char*)pdn + pdn->wDeviceOffset,
853 (char*)pdn + pdn->wOutputOffset,
854 pdm );
856 GlobalUnlock(lppd->hDevNames);
857 GlobalUnlock(lppd->hDevMode);
858 return lppd->hDC ? TRUE : FALSE;
861 /***********************************************************************
862 * PrintDlgA (COMDLG32.17)
864 * Displays the the PRINT dialog box, which enables the user to specify
865 * specific properties of the print job.
867 * RETURNS
868 * nonzero if the user pressed the OK button
869 * zero if the user cancelled the window or an error occurred
871 * BUGS
872 * PrintDlg:
873 * * The Collate Icons do not display, even though they are in the code.
874 * * The Properties Button(s) should call DocumentPropertiesA().
875 * PrintSetupDlg:
876 * * The Paper Orientation Icons are not implemented yet.
877 * * The Properties Button(s) should call DocumentPropertiesA().
878 * * Settings are not yet taken from a provided DevMode or
879 * default printer settings.
881 BOOL WINAPI PrintDlgA(
882 LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */
885 BOOL bRet = FALSE;
886 LPVOID ptr;
887 HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
889 if(TRACE_ON(commdlg)) {
890 char flagstr[1000] = "";
891 struct pd_flags *pflag = pd_flags;
892 for( ; pflag->name; pflag++) {
893 if(lppd->Flags & pflag->flag)
894 strcat(flagstr, pflag->name);
896 TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
897 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n"
898 "flags %08lx (%s)\n",
899 lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames,
900 lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage,
901 lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr);
904 if(lppd->lStructSize != sizeof(PRINTDLGA)) {
905 WARN("structure size failure !!!\n");
906 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
907 return FALSE;
910 if(lppd->Flags & PD_RETURNDEFAULT) {
911 PRINTER_INFO_2A *pbuf;
912 HANDLE hprn;
913 DWORD needed;
915 if(lppd->hDevMode || lppd->hDevNames) {
916 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
917 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
918 return FALSE;
920 if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
921 WARN("Can't find default printer\n");
922 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
923 return FALSE;
926 GetPrinterA(hprn, 2, NULL, 0, &needed);
927 pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
928 GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed);
929 ClosePrinter(hprn);
930 PRINTDLG_CreateDevNames(&(lppd->hDevNames), "winspool",
931 pbuf->pDevMode->dmDeviceName,
932 pbuf->pPortName);
933 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
934 pbuf->pDevMode->dmDriverExtra);
935 ptr = GlobalLock(lppd->hDevMode);
936 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
937 pbuf->pDevMode->dmDriverExtra);
938 GlobalUnlock(lppd->hDevMode);
939 HeapFree(GetProcessHeap(), 0, pbuf);
940 bRet = TRUE;
941 } else {
942 HGLOBAL hDlgTmpl;
943 PRINT_PTRA *PrintStructures;
945 /* load Dialog resources,
946 * depending on Flags indicates Print32 or Print32_setup dialog
948 hDlgTmpl = PRINTDLG_GetDlgTemplate(lppd);
949 if (!(hDlgTmpl) || !(ptr = LockResource( hDlgTmpl ))) {
950 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
951 return FALSE;
953 PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
954 sizeof(PRINT_PTRA));
955 PrintStructures->lpPrintDlg = lppd;
957 /* and create & process the dialog .
958 * -1 is failure, 0 is broken hwnd, everything else is ok.
960 bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner,
961 PrintDlgProcA,
962 (LPARAM)PrintStructures));
964 if(bRet) {
965 DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn;
966 PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo;
968 if (lppd->hDevMode == 0) {
969 TRACE(" No hDevMode yet... Need to create my own\n");
970 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE,
971 lpdm->dmSize + lpdm->dmDriverExtra);
972 } else {
973 WORD locks;
974 if((locks = (GlobalFlags(lppd->hDevMode) & GMEM_LOCKCOUNT))) {
975 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks);
976 while(locks--) {
977 GlobalUnlock(lppd->hDevMode);
978 TRACE("Now got %d locks\n", locks);
981 lppd->hDevMode = GlobalReAlloc(lppd->hDevMode,
982 lpdm->dmSize + lpdm->dmDriverExtra,
983 GMEM_MOVEABLE);
985 lpdmReturn = GlobalLock(lppd->hDevMode);
986 memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra);
988 if (lppd->hDevNames != 0) {
989 WORD locks;
990 if((locks = (GlobalFlags(lppd->hDevNames) & GMEM_LOCKCOUNT))) {
991 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks);
992 while(locks--)
993 GlobalUnlock(lppd->hDevNames);
996 PRINTDLG_CreateDevNames(&(lppd->hDevNames), "winspool",
997 lpdmReturn->dmDeviceName, pi->pPortName);
998 GlobalUnlock(lppd->hDevMode);
1000 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
1001 HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo);
1002 HeapFree(GetProcessHeap(), 0, PrintStructures);
1004 if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC))
1005 bRet = PRINTDLG_CreateDC(lppd);
1007 TRACE("exit! (%d)\n", bRet);
1008 return bRet;
1013 /***********************************************************************
1014 * PrintDlgW (COMDLG32.18)
1016 BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
1018 FIXME("A really empty stub\n" );
1019 return FALSE;
1022 /***********************************************************************
1024 * PageSetupDlg
1027 /***********************************************************************
1028 * PageSetupDlgA (COMDLG32.15)
1030 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
1031 FIXME("(%p), stub!\n",setupdlg);
1032 return FALSE;
1034 /***********************************************************************
1035 * PageSetupDlgW (COMDLG32.16)
1037 BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) {
1038 FIXME("(%p), stub!\n",setupdlg);
1039 return FALSE;
1042 /**********************************************************************
1044 * 16 bit commdlg
1047 /***********************************************************************
1048 * PrintDlgProc16 (COMMDLG.21)
1050 LRESULT WINAPI PrintDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1051 LPARAM lParam)
1053 switch (wMsg)
1055 case WM_INITDIALOG:
1056 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1057 ShowWindow(hWnd, SW_SHOWNORMAL);
1058 return (TRUE);
1059 case WM_COMMAND:
1060 switch (wParam)
1062 case IDOK:
1063 EndDialog(hWnd, TRUE);
1064 return(TRUE);
1065 case IDCANCEL:
1066 EndDialog(hWnd, FALSE);
1067 return(TRUE);
1069 return(FALSE);
1071 return FALSE;
1075 /***********************************************************************
1076 * PrintSetupDlgProc16 (COMMDLG.22)
1078 LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1079 LPARAM lParam)
1081 switch (wMsg)
1083 case WM_INITDIALOG:
1084 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1085 ShowWindow(hWnd, SW_SHOWNORMAL);
1086 return (TRUE);
1087 case WM_COMMAND:
1088 switch (wParam) {
1089 case IDOK:
1090 EndDialog(hWnd, TRUE);
1091 return(TRUE);
1092 case IDCANCEL:
1093 EndDialog(hWnd, FALSE);
1094 return(TRUE);
1096 return(FALSE);
1098 return FALSE;
1102 /***********************************************************************
1103 * PrintDlg16 (COMMDLG.20)
1105 * Displays the the PRINT dialog box, which enables the user to specify
1106 * specific properties of the print job.
1108 * RETURNS
1109 * nonzero if the user pressed the OK button
1110 * zero if the user cancelled the window or an error occurred
1112 * BUGS
1113 * * calls up to the 32-bit versions of the Dialogs, which look different
1114 * * Customizing is *not* implemented.
1116 BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lpPrint )
1118 PRINTDLGA Print32;
1119 BOOL16 ret;
1120 char *ptr, *ptr16;
1121 DWORD size;
1123 memset(&Print32, 0, sizeof(Print32));
1124 Print32.lStructSize = sizeof(Print32);
1125 Print32.hwndOwner = lpPrint->hwndOwner;
1126 if(lpPrint->hDevMode) {
1127 size = GlobalSize16(lpPrint->hDevMode);
1128 Print32.hDevMode = GlobalAlloc(GMEM_MOVEABLE, size);
1129 ptr = GlobalLock(Print32.hDevMode);
1130 ptr16 = GlobalLock16(lpPrint->hDevMode);
1131 memcpy(ptr, ptr16, size);
1132 GlobalFree16(lpPrint->hDevMode);
1133 GlobalUnlock(Print32.hDevMode);
1134 } else
1135 Print32.hDevMode = 0;
1136 if(lpPrint->hDevNames) {
1137 size = GlobalSize16(lpPrint->hDevNames);
1138 Print32.hDevNames = GlobalAlloc(GMEM_MOVEABLE, size);
1139 ptr = GlobalLock(Print32.hDevNames);
1140 ptr16 = GlobalLock16(lpPrint->hDevNames);
1141 memcpy(ptr, ptr16, size);
1142 GlobalFree16(lpPrint->hDevNames);
1143 GlobalUnlock(Print32.hDevNames);
1144 } else
1145 Print32.hDevNames = 0;
1146 Print32.Flags = lpPrint->Flags;
1147 Print32.nFromPage = lpPrint->nFromPage;
1148 Print32.nToPage = lpPrint->nToPage;
1149 Print32.nMinPage = lpPrint->nMinPage;
1150 Print32.nMaxPage = lpPrint->nMaxPage;
1151 Print32.nCopies = lpPrint->nCopies;
1152 Print32.hInstance = lpPrint->hInstance;
1153 Print32.lCustData = lpPrint->lCustData;
1154 if(lpPrint->lpfnPrintHook) {
1155 FIXME("Need to allocate thunk\n");
1156 /* Print32.lpfnPrintHook = lpPrint->lpfnPrintHook;*/
1158 if(lpPrint->lpfnSetupHook) {
1159 FIXME("Need to allocate thunk\n");
1160 /* Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
1162 Print32.lpPrintTemplateName = PTR_SEG_TO_LIN(lpPrint->lpPrintTemplateName);
1163 Print32.lpSetupTemplateName = PTR_SEG_TO_LIN(lpPrint->lpSetupTemplateName);
1164 Print32.hPrintTemplate = lpPrint->hPrintTemplate;
1165 Print32.hSetupTemplate = lpPrint->hSetupTemplate;
1167 ret = PrintDlgA(&Print32);
1169 if(Print32.hDevMode) {
1170 size = GlobalSize(Print32.hDevMode);
1171 lpPrint->hDevMode = GlobalAlloc16(GMEM_MOVEABLE, size);
1172 ptr16 = GlobalLock16(lpPrint->hDevMode);
1173 ptr = GlobalLock(Print32.hDevMode);
1174 memcpy(ptr16, ptr, size);
1175 GlobalFree(Print32.hDevMode);
1176 GlobalUnlock16(lpPrint->hDevMode);
1177 } else
1178 lpPrint->hDevMode = 0;
1179 if(Print32.hDevNames) {
1180 size = GlobalSize(Print32.hDevNames);
1181 lpPrint->hDevNames = GlobalAlloc16(GMEM_MOVEABLE, size);
1182 ptr16 = GlobalLock16(lpPrint->hDevNames);
1183 ptr = GlobalLock(Print32.hDevNames);
1184 memcpy(ptr16, ptr, size);
1185 GlobalFree(Print32.hDevNames);
1186 GlobalUnlock16(lpPrint->hDevNames);
1187 } else
1188 lpPrint->hDevNames = 0;
1189 lpPrint->hDC = Print32.hDC;
1190 lpPrint->Flags = Print32.Flags;
1191 lpPrint->nFromPage = Print32.nFromPage;
1192 lpPrint->nToPage = Print32.nToPage;
1193 lpPrint->nCopies = Print32.nCopies;
1195 return ret;
1198 /***********************************************************************
1199 * PrintDlgExA
1201 HRESULT WINAPI PrintDlgExA(LPVOID lpPrintDlgExA) /* [???] FIXME: LPPRINTDLGEXA */
1203 FIXME("stub\n");
1204 return E_NOTIMPL;
1206 /***********************************************************************
1207 * PrintDlgExW
1209 HRESULT WINAPI PrintDlgExW(LPVOID lpPrintDlgExW) /* [???] FIXME: LPPRINTDLGEXW */
1211 FIXME("stub\n");
1212 return E_NOTIMPL;