Implemented _ultow() and export [Nt/Zw]QueryVolumeInformationFile().
[wine/dcerpc.git] / dlls / commdlg / printdlg.c
blobc321854b44b7b50cf3a72ee8e9f2d8f976cb2e34
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 "commdlg.h"
20 #include "dlgs.h"
21 #include "debugtools.h"
22 #include "cderr.h"
23 #include "winspool.h"
24 #include "winerror.h"
26 DEFAULT_DEBUG_CHANNEL(commdlg);
28 #include "cdlg.h"
31 /* This PRINTDLGA internal structure stores
32 * pointers to several throughout useful structures.
35 typedef struct
37 LPDEVMODEA lpDevMode;
38 LPPRINTDLGA lpPrintDlg;
39 LPPRINTER_INFO_2A lpPrinterInfo;
40 UINT HelpMessageID;
41 HICON hCollateIcon; /* PrintDlg only */
42 HICON hNoCollateIcon; /* PrintDlg only */
43 HICON hPortraitIcon; /* PrintSetupDlg only */
44 HICON hLandscapeIcon; /* PrintSetupDlg only */
45 } PRINT_PTRA;
47 /* Debugiging info */
48 static struct pd_flags {
49 DWORD flag;
50 LPSTR name;
51 } pd_flags[] = {
52 {PD_SELECTION, "PD_SELECTION "},
53 {PD_PAGENUMS, "PD_PAGENUMS "},
54 {PD_NOSELECTION, "PD_NOSELECTION "},
55 {PD_NOPAGENUMS, "PD_NOPAGENUMS "},
56 {PD_COLLATE, "PD_COLLATE "},
57 {PD_PRINTTOFILE, "PD_PRINTTOFILE "},
58 {PD_PRINTSETUP, "PD_PRINTSETUP "},
59 {PD_NOWARNING, "PD_NOWARNING "},
60 {PD_RETURNDC, "PD_RETURNDC "},
61 {PD_RETURNIC, "PD_RETURNIC "},
62 {PD_RETURNDEFAULT, "PD_RETURNDEFAULT "},
63 {PD_SHOWHELP, "PD_SHOWHELP "},
64 {PD_ENABLEPRINTHOOK, "PD_ENABLEPRINTHOOK "},
65 {PD_ENABLESETUPHOOK, "PD_ENABLESETUPHOOK "},
66 {PD_ENABLEPRINTTEMPLATE, "PD_ENABLEPRINTTEMPLATE "},
67 {PD_ENABLESETUPTEMPLATE, "PD_ENABLESETUPTEMPLATE "},
68 {PD_ENABLEPRINTTEMPLATEHANDLE, "PD_ENABLEPRINTTEMPLATEHANDLE "},
69 {PD_ENABLESETUPTEMPLATEHANDLE, "PD_ENABLESETUPTEMPLATEHANDLE "},
70 {PD_USEDEVMODECOPIES, "PD_USEDEVMODECOPIES[ANDCOLLATE] "},
71 {PD_DISABLEPRINTTOFILE, "PD_DISABLEPRINTTOFILE "},
72 {PD_HIDEPRINTTOFILE, "PD_HIDEPRINTTOFILE "},
73 {PD_NONETWORKBUTTON, "PD_NONETWORKBUTTON "},
74 {-1, NULL}
78 /***********************************************************************
79 * PRINTDLG_GetDefaultPrinterName
81 * Returns the default printer name in buf.
82 * Even under WinNT/2000 default printer is retrieved via GetProfileString -
83 * these entries are mapped somewhere in the registry rather than win.ini.
85 * Returns TRUE on success else FALSE
87 static BOOL PRINTDLG_GetDefaultPrinterName(LPSTR buf, DWORD len)
89 char *ptr;
91 if(!GetProfileStringA("windows", "device", "", buf, len))
92 return FALSE;
93 if((ptr = strchr(buf, ',')) == NULL)
94 return FALSE;
95 *ptr = '\0';
96 return TRUE;
99 /***********************************************************************
100 * PRINTDLG_OpenDefaultPrinter
102 * Returns a winspool printer handle to the default printer in *hprn
103 * Caller must call ClosePrinter on the handle
105 * Returns TRUE on success else FALSE
107 static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn)
109 char buf[260];
110 if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
111 return FALSE;
112 return OpenPrinterA(buf, hprn, NULL);
115 /***********************************************************************
116 * PRINTDLG_SetUpPrinterListCombo
118 * Initializes printer list combox.
119 * hDlg: HWND of dialog
120 * id: Control id of combo
121 * name: Name of printer to select
123 * Initializes combo with list of available printers. Selects printer 'name'
124 * If name is NULL or does not exist select the default printer.
126 * Returns number of printers added to list.
128 static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name)
130 DWORD needed, num;
131 INT i;
132 LPPRINTER_INFO_2A pi;
133 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num);
134 pi = HeapAlloc(GetProcessHeap(), 0, needed);
135 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed,
136 &num);
138 for(i = 0; i < num; i++) {
139 SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0,
140 (LPARAM)pi[i].pPrinterName );
142 HeapFree(GetProcessHeap(), 0, pi);
143 if(!name ||
144 (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1,
145 (LPARAM)name)) == CB_ERR) {
147 char buf[260];
148 TRACE("Can't find '%s' in printer list so trying to find default\n",
149 name);
150 if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
151 return num;
152 i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
153 if(i == CB_ERR)
154 TRACE("Can't find default printer in printer list\n");
156 SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0);
157 return num;
160 /***********************************************************************
161 * PRINTDLG_CreateDevNames [internal]
164 * creates a DevNames structure.
166 * (NB. when we handle unicode the offsets will be in wchars).
168 static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, char* DeviceDriverName,
169 char* DeviceName, char* OutputPort)
171 long size;
172 char* pDevNamesSpace;
173 char* pTempPtr;
174 LPDEVNAMES lpDevNames;
175 char buf[260];
177 size = strlen(DeviceDriverName) + 1
178 + strlen(DeviceName) + 1
179 + strlen(OutputPort) + 1
180 + sizeof(DEVNAMES);
182 if(*hmem)
183 *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE);
184 else
185 *hmem = GlobalAlloc(GMEM_MOVEABLE, size);
186 if (*hmem == 0)
187 return FALSE;
189 pDevNamesSpace = GlobalLock(*hmem);
190 lpDevNames = (LPDEVNAMES) pDevNamesSpace;
192 pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
193 strcpy(pTempPtr, DeviceDriverName);
194 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;
196 pTempPtr += strlen(DeviceDriverName) + 1;
197 strcpy(pTempPtr, DeviceName);
198 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
200 pTempPtr += strlen(DeviceName) + 1;
201 strcpy(pTempPtr, OutputPort);
202 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
204 PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf));
205 lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0;
206 GlobalUnlock(*hmem);
207 return TRUE;
210 /***********************************************************************
211 * PRINTDLG_UpdatePrintDlg [internal]
214 * updates the PrintDlg structure for returnvalues.
216 * RETURNS
217 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
218 * TRUE if succesful.
220 static BOOL PRINTDLG_UpdatePrintDlg(HWND hDlg,
221 PRINT_PTRA* PrintStructures)
223 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
224 PDEVMODEA lpdm = PrintStructures->lpDevMode;
225 LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo;
228 if(!lpdm) return FALSE;
231 if(!(lppd->Flags & PD_PRINTSETUP)) {
232 /* check whether nFromPage and nToPage are within range defined by
233 * nMinPage and nMaxPage
235 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
236 WORD nToPage;
237 WORD nFromPage;
238 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
239 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
240 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
241 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
242 char resourcestr[256];
243 char resultstr[256];
244 LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
245 resourcestr, 255);
246 sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
247 LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
248 resourcestr, 255);
249 MessageBoxA(hDlg, resultstr, resourcestr,
250 MB_OK | MB_ICONWARNING);
251 return FALSE;
253 lppd->nFromPage = nFromPage;
254 lppd->nToPage = nToPage;
257 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */
258 lppd->Flags |= PD_PRINTTOFILE;
259 pi->pPortName = "FILE:";
262 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */
263 FIXME("Collate lppd not yet implemented as output\n");
266 /* set PD_Collate and nCopies */
267 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
268 /* The application doesn't support multiple copies or collate...
270 lppd->Flags &= ~PD_COLLATE;
271 lppd->nCopies = 1;
272 /* if the printer driver supports it... store info there
273 * otherwise no collate & multiple copies !
275 if (lpdm->dmFields & DM_COLLATE)
276 lpdm->dmCollate =
277 (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED);
278 if (lpdm->dmFields & DM_COPIES)
279 lpdm->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
280 } else {
281 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
282 lppd->Flags |= PD_COLLATE;
283 else
284 lppd->Flags &= ~PD_COLLATE;
285 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
288 return TRUE;
292 /************************************************************************
293 * PRINTDLG_SetUpPaperComboBox
295 * Initialize either the papersize or inputslot combos of the Printer Setup
296 * dialog. We store the associated word (eg DMPAPER_A4) as the item data.
297 * We also try to re-select the old selection.
299 static BOOL PRINTDLG_SetUpPaperComboBox(HWND hDlg,
300 int nIDComboBox,
301 char* PrinterName,
302 char* PortName,
303 LPDEVMODEA dm)
305 int i;
306 DWORD NrOfEntries;
307 char* Names;
308 WORD* Words;
309 DWORD Sel;
310 WORD oldWord = 0;
311 int NamesSize;
312 int fwCapability_Names;
313 int fwCapability_Words;
315 TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
317 /* query the dialog box for the current selected value */
318 Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0);
319 if(Sel != CB_ERR) {
320 oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, Sel,
324 if (nIDComboBox == cmb2) {
325 NamesSize = 64;
326 fwCapability_Names = DC_PAPERNAMES;
327 fwCapability_Words = DC_PAPERS;
328 } else {
329 nIDComboBox = cmb3;
330 NamesSize = 24;
331 fwCapability_Names = DC_BINNAMES;
332 fwCapability_Words = DC_BINS;
335 /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
336 * paper settings. As Wine doesn't allow VXDs, this results in a crash.
338 WARN(" if your printer driver uses VXDs, expect a crash now!\n");
339 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
340 fwCapability_Names, NULL, dm);
341 if (NrOfEntries == 0)
342 WARN("no Name Entries found!\n");
344 if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm)
345 != NrOfEntries) {
346 ERR("Number of caps is different\n");
347 NrOfEntries = 0;
350 Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*NamesSize);
351 Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD));
352 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
353 fwCapability_Names, Names, dm);
354 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
355 fwCapability_Words, (LPSTR)Words, dm);
357 /* reset any current content in the combobox */
358 SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);
360 /* store new content */
361 for (i = 0; i < NrOfEntries; i++) {
362 DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
363 (LPARAM)(&Names[i*NamesSize]) );
364 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
365 Words[i]);
368 /* Look for old selection - can't do this is previous loop since
369 item order will change as more items are added */
370 Sel = 0;
371 for (i = 0; i < NrOfEntries; i++) {
372 if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) ==
373 oldWord) {
374 Sel = i;
375 break;
378 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0);
380 HeapFree(GetProcessHeap(),0,Words);
381 HeapFree(GetProcessHeap(),0,Names);
382 return TRUE;
385 /***********************************************************************
386 * PRINTDLG_UpdatePrinterInfoTexts [internal]
388 static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, LPPRINTER_INFO_2A pi)
390 char StatusMsg[256];
391 char ResourceString[256];
392 int i;
394 /* Status Message */
395 StatusMsg[0]='\0';
397 /* add all status messages */
398 for (i = 0; i < 25; i++) {
399 if (pi->Status & (1<<i)) {
400 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
401 ResourceString, 255);
402 strcat(StatusMsg,ResourceString);
405 /* append "ready" */
406 /* FIXME: status==ready must only be appended if really so.
407 but how to detect? */
408 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
409 ResourceString, 255);
410 strcat(StatusMsg,ResourceString);
412 SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
414 /* set all other printer info texts */
415 SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)pi->pDriverName);
416 if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
417 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation);
418 else
419 SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName);
420 SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)pi->pComment);
421 return;
425 /*******************************************************************
427 * PRINTDLG_ChangePrinter
430 static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name,
431 PRINT_PTRA *PrintStructures)
433 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
434 LPDEVMODEA lpdm = NULL;
435 LONG dmSize;
436 DWORD needed;
437 HANDLE hprn;
439 if(PrintStructures->lpPrinterInfo)
440 HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo);
441 if(!OpenPrinterA(name, &hprn, NULL)) {
442 ERR("Can't open printer %s\n", name);
443 return FALSE;
445 GetPrinterA(hprn, 2, NULL, 0, &needed);
446 PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed);
447 GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
448 &needed);
449 ClosePrinter(hprn);
451 PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures->lpPrinterInfo);
453 if(PrintStructures->lpDevMode) {
454 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
455 PrintStructures->lpDevMode = NULL;
458 dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0);
459 if(dmSize == -1) {
460 ERR("DocumentProperties fails on %s\n", debugstr_a(name));
461 return FALSE;
463 PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize);
464 dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL,
465 DM_OUT_BUFFER);
466 if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) &&
467 !strcmp(lpdm->dmDeviceName,
468 PrintStructures->lpDevMode->dmDeviceName)) {
469 /* Supplied devicemode matches current printer so try to use it */
470 DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm,
471 DM_OUT_BUFFER | DM_IN_BUFFER);
473 if(lpdm)
474 GlobalUnlock(lppd->hDevMode);
476 lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */
478 if(!(lppd->Flags & PD_PRINTSETUP)) {
479 /* Print range (All/Range/Selection) */
480 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
481 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);
482 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */
483 if (lppd->Flags & PD_NOSELECTION)
484 EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
485 else
486 if (lppd->Flags & PD_SELECTION)
487 CheckRadioButton(hDlg, rad1, rad3, rad2);
488 if (lppd->Flags & PD_NOPAGENUMS) {
489 EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
490 EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
491 EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
492 EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
493 EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
494 } else {
495 if (lppd->Flags & PD_PAGENUMS)
496 CheckRadioButton(hDlg, rad1, rad3, rad3);
498 /* "All xxx pages"... */
500 char resourcestr[64];
501 char result[64];
502 LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
503 resourcestr, 49);
504 sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
505 SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
508 /* Collate pages
510 * FIXME: The ico3 is not displayed for some reason. I don't know why.
512 if (lppd->Flags & PD_COLLATE) {
513 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
514 (LPARAM)PrintStructures->hCollateIcon);
515 CheckDlgButton(hDlg, chx2, 1);
516 } else {
517 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
518 (LPARAM)PrintStructures->hNoCollateIcon);
519 CheckDlgButton(hDlg, chx2, 0);
522 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
523 /* if printer doesn't support it: no Collate */
524 if (!(lpdm->dmFields & DM_COLLATE)) {
525 EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
526 EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
530 /* nCopies */
531 if (lppd->hDevMode == 0)
532 SetDlgItemInt(hDlg, edt3, lppd->nCopies, FALSE);
533 else
534 SetDlgItemInt(hDlg, edt3, lpdm->dmCopies, FALSE);
536 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
537 /* if printer doesn't support it: no nCopies */
538 if (!(lpdm->dmFields & DM_COPIES)) {
539 EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
540 EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
544 /* print to file */
545 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
546 if (lppd->Flags & PD_DISABLEPRINTTOFILE)
547 EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
548 if (lppd->Flags & PD_HIDEPRINTTOFILE)
549 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
551 } else { /* PD_PRINTSETUP */
552 PRINTDLG_SetUpPaperComboBox(hDlg, cmb2,
553 PrintStructures->lpPrinterInfo->pPrinterName,
554 PrintStructures->lpPrinterInfo->pPortName,
555 lpdm);
556 PRINTDLG_SetUpPaperComboBox(hDlg, cmb3,
557 PrintStructures->lpPrinterInfo->pPrinterName,
558 PrintStructures->lpPrinterInfo->pPortName,
559 lpdm);
560 CheckRadioButton(hDlg, rad1, rad2,
561 (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT) ?
562 rad1: rad2);
565 /* help button */
566 if ((lppd->Flags & PD_SHOWHELP)==0) {
567 /* hide if PD_SHOWHELP not specified */
568 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
571 return TRUE;
574 /***********************************************************************
575 * PRINTDLG_WMInitDialog [internal]
577 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam,
578 PRINT_PTRA* PrintStructures)
580 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
581 DEVNAMES *pdn;
582 DEVMODEA *pdm;
583 char *name = NULL;
584 UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
586 /* load Collate ICONs */
587 PrintStructures->hCollateIcon =
588 LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
589 PrintStructures->hNoCollateIcon =
590 LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
591 if(PrintStructures->hCollateIcon == 0 ||
592 PrintStructures->hNoCollateIcon == 0) {
593 ERR("no icon in resourcefile\n");
594 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
595 EndDialog(hDlg, FALSE);
598 /* load Paper Orientation ICON */
599 /* FIXME: not implemented yet */
602 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
603 * must be registered and the Help button must be shown.
605 if (lppd->Flags & PD_SHOWHELP) {
606 if((PrintStructures->HelpMessageID =
607 RegisterWindowMessageA(HELPMSGSTRING)) == 0) {
608 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
609 return FALSE;
611 } else
612 PrintStructures->HelpMessageID = 0;
614 /* FIXME: I allow more freedom than either Win95 or WinNT,
615 * which do not agree to what errors should be thrown or not
616 * in case nToPage or nFromPage is out-of-range.
618 if (lppd->nMaxPage < lppd->nMinPage)
619 lppd->nMaxPage = lppd->nMinPage;
620 if (lppd->nMinPage == lppd->nMaxPage)
621 lppd->Flags |= PD_NOPAGENUMS;
622 if (lppd->nToPage < lppd->nMinPage)
623 lppd->nToPage = lppd->nMinPage;
624 if (lppd->nToPage > lppd->nMaxPage)
625 lppd->nToPage = lppd->nMaxPage;
626 if (lppd->nFromPage < lppd->nMinPage)
627 lppd->nFromPage = lppd->nMinPage;
628 if (lppd->nFromPage > lppd->nMaxPage)
629 lppd->nFromPage = lppd->nMaxPage;
631 /* Fill Combobox
633 pdn = GlobalLock(lppd->hDevNames);
634 pdm = GlobalLock(lppd->hDevMode);
635 if(pdn)
636 name = (char*)pdn + pdn->wDeviceOffset;
637 else if(pdm)
638 name = pdm->dmDeviceName;
639 PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name);
640 if(pdm) GlobalUnlock(lppd->hDevMode);
641 if(pdn) GlobalUnlock(lppd->hDevNames);
643 /* Now find selected printer and update rest of dlg */
644 name = HeapAlloc(GetProcessHeap(),0,256);
645 GetDlgItemTextA(hDlg, comboID, name, 255);
646 PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
647 HeapFree(GetProcessHeap(),0,name);
649 return TRUE;
652 /***********************************************************************
653 * PRINTDLG_WMCommand [internal]
655 static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam,
656 LPARAM lParam, PRINT_PTRA* PrintStructures)
658 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
659 UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
660 LPDEVMODEA lpdm = PrintStructures->lpDevMode;
662 switch (LOWORD(wParam)) {
663 case IDOK:
664 TRACE(" OK button was hit\n");
665 if (PRINTDLG_UpdatePrintDlg(hDlg, PrintStructures)!=TRUE)
666 return(FALSE);
667 EndDialog(hDlg, TRUE);
668 return(TRUE);
670 case IDCANCEL:
671 TRACE(" CANCEL button was hit\n");
672 EndDialog(hDlg, FALSE);
673 return(FALSE);
675 case pshHelp:
676 TRACE(" HELP button was hit\n");
677 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
678 (WPARAM) hDlg, (LPARAM) lppd);
679 break;
681 case chx2: /* collate pages checkbox */
682 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
683 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
684 (LPARAM)PrintStructures->hCollateIcon);
685 else
686 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
687 (LPARAM)PrintStructures->hNoCollateIcon);
688 break;
689 case edt1: /* from page nr editbox */
690 case edt2: /* to page nr editbox */
691 if (HIWORD(wParam)==EN_CHANGE) {
692 WORD nToPage;
693 WORD nFromPage;
694 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
695 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
696 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
697 CheckRadioButton(hDlg, rad1, rad3, rad3);
699 break;
700 case psh2: /* Properties button */
702 HANDLE hPrinter;
703 char PrinterName[256];
705 GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255);
706 if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) {
707 WARN(" Call to OpenPrinter did not succeed!\n");
708 break;
710 DocumentPropertiesA(hDlg, hPrinter, PrinterName,
711 PrintStructures->lpDevMode,
712 PrintStructures->lpDevMode,
713 DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
714 ClosePrinter(hPrinter);
715 break;
718 case cmb1:
719 case cmb4: /* Printer combobox */
720 if (HIWORD(wParam)==CBN_SELCHANGE) {
721 char PrinterName[256];
722 GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255);
723 PRINTDLG_ChangePrinter(hDlg, PrinterName, PrintStructures);
725 break;
727 case cmb2: /* Papersize */
729 DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
730 if(Sel != CB_ERR)
731 lpdm->u1.s1.dmPaperSize = SendDlgItemMessageA(hDlg, cmb2,
732 CB_GETITEMDATA,
733 Sel, 0);
735 break;
737 case cmb3: /* Bin */
739 DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0);
740 if(Sel != CB_ERR)
741 lpdm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3,
742 CB_GETITEMDATA, Sel,
745 break;
747 return FALSE;
750 /***********************************************************************
751 * PrintDlgProcA [internal]
753 BOOL WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
754 LPARAM lParam)
756 PRINT_PTRA* PrintStructures;
757 LRESULT res=FALSE;
759 if (uMsg!=WM_INITDIALOG) {
760 PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);
761 if (!PrintStructures)
762 return FALSE;
763 } else {
764 PrintStructures = (PRINT_PTRA*) lParam;
765 SetWindowLongA(hDlg, DWL_USER, lParam);
766 res = PRINTDLG_WMInitDialog(hDlg, wParam, PrintStructures);
768 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
769 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg,
770 wParam,
771 (LPARAM)PrintStructures->lpPrintDlg);
773 return res;
776 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
777 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam,
778 lParam);
779 if(res) return res;
782 switch (uMsg) {
783 case WM_COMMAND:
784 return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
786 case WM_DESTROY:
787 DestroyIcon(PrintStructures->hCollateIcon);
788 DestroyIcon(PrintStructures->hNoCollateIcon);
789 /* FIXME: don't forget to delete the paper orientation icons here! */
791 return FALSE;
793 return res;
796 /************************************************************
798 * PRINTDLG_GetDlgTemplate
801 static HGLOBAL PRINTDLG_GetDlgTemplate(PRINTDLGA *lppd)
803 HGLOBAL hDlgTmpl, hResInfo;
805 if (lppd->Flags & PD_PRINTSETUP) {
806 if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) {
807 hDlgTmpl = lppd->hSetupTemplate;
808 } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
809 hResInfo = FindResourceA(lppd->hInstance,
810 lppd->lpSetupTemplateName, RT_DIALOGA);
811 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
812 } else {
813 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP",
814 RT_DIALOGA);
815 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
817 } else {
818 if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) {
819 hDlgTmpl = lppd->hPrintTemplate;
820 } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) {
821 hResInfo = FindResourceA(lppd->hInstance,
822 lppd->lpPrintTemplateName,
823 RT_DIALOGA);
824 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
825 } else {
826 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32",
827 RT_DIALOGA);
828 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
831 return hDlgTmpl;
834 /***********************************************************************
836 * PRINTDLG_CreateDC
839 static BOOL PRINTDLG_CreateDC(LPPRINTDLGA lppd)
841 DEVNAMES *pdn = GlobalLock(lppd->hDevNames);
842 DEVMODEA *pdm = GlobalLock(lppd->hDevMode);
844 if(lppd->Flags & PD_RETURNDC) {
845 lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset,
846 (char*)pdn + pdn->wDeviceOffset,
847 (char*)pdn + pdn->wOutputOffset,
848 pdm );
849 } else if(lppd->Flags & PD_RETURNIC) {
850 lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset,
851 (char*)pdn + pdn->wDeviceOffset,
852 (char*)pdn + pdn->wOutputOffset,
853 pdm );
855 GlobalUnlock(lppd->hDevNames);
856 GlobalUnlock(lppd->hDevMode);
857 return lppd->hDC ? TRUE : FALSE;
860 /***********************************************************************
861 * PrintDlgA (COMDLG32.17)
863 * Displays the the PRINT dialog box, which enables the user to specify
864 * specific properties of the print job.
866 * RETURNS
867 * nonzero if the user pressed the OK button
868 * zero if the user cancelled the window or an error occurred
870 * BUGS
871 * PrintDlg:
872 * * The Collate Icons do not display, even though they are in the code.
873 * * The Properties Button(s) should call DocumentPropertiesA().
874 * PrintSetupDlg:
875 * * The Paper Orientation Icons are not implemented yet.
876 * * The Properties Button(s) should call DocumentPropertiesA().
877 * * Settings are not yet taken from a provided DevMode or
878 * default printer settings.
880 BOOL WINAPI PrintDlgA(
881 LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */
884 BOOL bRet = FALSE;
885 LPVOID ptr;
886 HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
888 if(TRACE_ON(commdlg)) {
889 char flagstr[1000] = "";
890 struct pd_flags *pflag = pd_flags;
891 for( ; pflag->name; pflag++) {
892 if(lppd->Flags & pflag->flag)
893 strcat(flagstr, pflag->name);
895 TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
896 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n"
897 "flags %08lx (%s)\n",
898 lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames,
899 lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage,
900 lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr);
903 if(lppd->lStructSize != sizeof(PRINTDLGA)) {
904 WARN("structure size failure !!!\n");
905 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
906 return FALSE;
909 if(lppd->Flags & PD_RETURNDEFAULT) {
910 PRINTER_INFO_2A *pbuf;
911 HANDLE hprn;
912 DWORD needed;
914 if(lppd->hDevMode || lppd->hDevNames) {
915 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
916 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
917 return FALSE;
919 if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
920 WARN("Can't find default printer\n");
921 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
922 return FALSE;
925 GetPrinterA(hprn, 2, NULL, 0, &needed);
926 pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
927 GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed);
928 ClosePrinter(hprn);
929 PRINTDLG_CreateDevNames(&(lppd->hDevNames), "winspool",
930 pbuf->pDevMode->dmDeviceName,
931 pbuf->pPortName);
932 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
933 pbuf->pDevMode->dmDriverExtra);
934 ptr = GlobalLock(lppd->hDevMode);
935 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
936 pbuf->pDevMode->dmDriverExtra);
937 GlobalUnlock(lppd->hDevMode);
938 HeapFree(GetProcessHeap(), 0, pbuf);
939 bRet = TRUE;
940 } else {
941 HGLOBAL hDlgTmpl;
942 PRINT_PTRA *PrintStructures;
944 /* load Dialog resources,
945 * depending on Flags indicates Print32 or Print32_setup dialog
947 hDlgTmpl = PRINTDLG_GetDlgTemplate(lppd);
948 if (!(hDlgTmpl) || !(ptr = LockResource( hDlgTmpl ))) {
949 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
950 return FALSE;
952 PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
953 sizeof(PRINT_PTRA));
954 PrintStructures->lpPrintDlg = lppd;
956 /* and create & process the dialog .
957 * -1 is failure, 0 is broken hwnd, everything else is ok.
959 bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner,
960 PrintDlgProcA,
961 (LPARAM)PrintStructures));
963 if(bRet) {
964 DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn;
965 PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo;
967 if (lppd->hDevMode == 0) {
968 TRACE(" No hDevMode yet... Need to create my own\n");
969 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE,
970 lpdm->dmSize + lpdm->dmDriverExtra);
971 } else {
972 WORD locks;
973 if((locks = (GlobalFlags(lppd->hDevMode) & GMEM_LOCKCOUNT))) {
974 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks);
975 while(locks--) {
976 GlobalUnlock(lppd->hDevMode);
977 TRACE("Now got %d locks\n", locks);
980 lppd->hDevMode = GlobalReAlloc(lppd->hDevMode,
981 lpdm->dmSize + lpdm->dmDriverExtra,
982 GMEM_MOVEABLE);
984 lpdmReturn = GlobalLock(lppd->hDevMode);
985 memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra);
987 if (lppd->hDevNames != 0) {
988 WORD locks;
989 if((locks = (GlobalFlags(lppd->hDevNames) & GMEM_LOCKCOUNT))) {
990 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks);
991 while(locks--)
992 GlobalUnlock(lppd->hDevNames);
995 PRINTDLG_CreateDevNames(&(lppd->hDevNames), "winspool",
996 lpdmReturn->dmDeviceName, pi->pPortName);
997 GlobalUnlock(lppd->hDevMode);
999 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
1000 HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo);
1001 HeapFree(GetProcessHeap(), 0, PrintStructures);
1003 if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC))
1004 bRet = PRINTDLG_CreateDC(lppd);
1006 TRACE("exit! (%d)\n", bRet);
1007 return bRet;
1012 /***********************************************************************
1013 * PrintDlgW (COMDLG32.18)
1015 BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
1017 FIXME("A really empty stub\n" );
1018 return FALSE;
1021 /***********************************************************************
1023 * PageSetupDlg
1026 /***********************************************************************
1027 * PageSetupDlgA (COMDLG32.15)
1029 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) {
1030 FIXME("(%p), stub!\n",setupdlg);
1031 return FALSE;
1033 /***********************************************************************
1034 * PageSetupDlgW (COMDLG32.16)
1036 BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) {
1037 FIXME("(%p), stub!\n",setupdlg);
1038 return FALSE;
1041 /**********************************************************************
1043 * 16 bit commdlg
1046 /***********************************************************************
1047 * PrintDlgProc16 (COMMDLG.21)
1049 LRESULT WINAPI PrintDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1050 LPARAM lParam)
1052 switch (wMsg)
1054 case WM_INITDIALOG:
1055 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1056 ShowWindow(hWnd, SW_SHOWNORMAL);
1057 return (TRUE);
1058 case WM_COMMAND:
1059 switch (wParam)
1061 case IDOK:
1062 EndDialog(hWnd, TRUE);
1063 return(TRUE);
1064 case IDCANCEL:
1065 EndDialog(hWnd, FALSE);
1066 return(TRUE);
1068 return(FALSE);
1070 return FALSE;
1074 /***********************************************************************
1075 * PrintSetupDlgProc16 (COMMDLG.22)
1077 LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
1078 LPARAM lParam)
1080 switch (wMsg)
1082 case WM_INITDIALOG:
1083 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
1084 ShowWindow(hWnd, SW_SHOWNORMAL);
1085 return (TRUE);
1086 case WM_COMMAND:
1087 switch (wParam) {
1088 case IDOK:
1089 EndDialog(hWnd, TRUE);
1090 return(TRUE);
1091 case IDCANCEL:
1092 EndDialog(hWnd, FALSE);
1093 return(TRUE);
1095 return(FALSE);
1097 return FALSE;
1101 /***********************************************************************
1102 * PrintDlg16 (COMMDLG.20)
1104 * Displays the the PRINT dialog box, which enables the user to specify
1105 * specific properties of the print job.
1107 * RETURNS
1108 * nonzero if the user pressed the OK button
1109 * zero if the user cancelled the window or an error occurred
1111 * BUGS
1112 * * calls up to the 32-bit versions of the Dialogs, which look different
1113 * * Customizing is *not* implemented.
1115 BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lpPrint )
1117 PRINTDLGA Print32;
1118 BOOL16 ret;
1119 char *ptr, *ptr16;
1120 DWORD size;
1122 memset(&Print32, 0, sizeof(Print32));
1123 Print32.lStructSize = sizeof(Print32);
1124 Print32.hwndOwner = lpPrint->hwndOwner;
1125 if(lpPrint->hDevMode) {
1126 size = GlobalSize16(lpPrint->hDevMode);
1127 Print32.hDevMode = GlobalAlloc(GMEM_MOVEABLE, size);
1128 ptr = GlobalLock(Print32.hDevMode);
1129 ptr16 = GlobalLock16(lpPrint->hDevMode);
1130 memcpy(ptr, ptr16, size);
1131 GlobalFree16(lpPrint->hDevMode);
1132 GlobalUnlock(Print32.hDevMode);
1133 } else
1134 Print32.hDevMode = 0;
1135 if(lpPrint->hDevNames) {
1136 size = GlobalSize16(lpPrint->hDevNames);
1137 Print32.hDevNames = GlobalAlloc(GMEM_MOVEABLE, size);
1138 ptr = GlobalLock(Print32.hDevNames);
1139 ptr16 = GlobalLock16(lpPrint->hDevNames);
1140 memcpy(ptr, ptr16, size);
1141 GlobalFree16(lpPrint->hDevNames);
1142 GlobalUnlock(Print32.hDevNames);
1143 } else
1144 Print32.hDevNames = 0;
1145 Print32.Flags = lpPrint->Flags;
1146 Print32.nFromPage = lpPrint->nFromPage;
1147 Print32.nToPage = lpPrint->nToPage;
1148 Print32.nMinPage = lpPrint->nMinPage;
1149 Print32.nMaxPage = lpPrint->nMaxPage;
1150 Print32.nCopies = lpPrint->nCopies;
1151 Print32.hInstance = lpPrint->hInstance;
1152 Print32.lCustData = lpPrint->lCustData;
1153 if(lpPrint->lpfnPrintHook) {
1154 FIXME("Need to allocate thunk\n");
1155 /* Print32.lpfnPrintHook = lpPrint->lpfnPrintHook;*/
1157 if(lpPrint->lpfnSetupHook) {
1158 FIXME("Need to allocate thunk\n");
1159 /* Print32.lpfnSetupHook = lpPrint->lpfnSetupHook;*/
1161 Print32.lpPrintTemplateName = MapSL(lpPrint->lpPrintTemplateName);
1162 Print32.lpSetupTemplateName = MapSL(lpPrint->lpSetupTemplateName);
1163 Print32.hPrintTemplate = lpPrint->hPrintTemplate;
1164 Print32.hSetupTemplate = lpPrint->hSetupTemplate;
1166 ret = PrintDlgA(&Print32);
1168 if(Print32.hDevMode) {
1169 size = GlobalSize(Print32.hDevMode);
1170 lpPrint->hDevMode = GlobalAlloc16(GMEM_MOVEABLE, size);
1171 ptr16 = GlobalLock16(lpPrint->hDevMode);
1172 ptr = GlobalLock(Print32.hDevMode);
1173 memcpy(ptr16, ptr, size);
1174 GlobalFree(Print32.hDevMode);
1175 GlobalUnlock16(lpPrint->hDevMode);
1176 } else
1177 lpPrint->hDevMode = 0;
1178 if(Print32.hDevNames) {
1179 size = GlobalSize(Print32.hDevNames);
1180 lpPrint->hDevNames = GlobalAlloc16(GMEM_MOVEABLE, size);
1181 ptr16 = GlobalLock16(lpPrint->hDevNames);
1182 ptr = GlobalLock(Print32.hDevNames);
1183 memcpy(ptr16, ptr, size);
1184 GlobalFree(Print32.hDevNames);
1185 GlobalUnlock16(lpPrint->hDevNames);
1186 } else
1187 lpPrint->hDevNames = 0;
1188 lpPrint->hDC = Print32.hDC;
1189 lpPrint->Flags = Print32.Flags;
1190 lpPrint->nFromPage = Print32.nFromPage;
1191 lpPrint->nToPage = Print32.nToPage;
1192 lpPrint->nCopies = Print32.nCopies;
1194 return ret;
1197 /***********************************************************************
1198 * PrintDlgExA
1200 HRESULT WINAPI PrintDlgExA(LPVOID lpPrintDlgExA) /* [???] FIXME: LPPRINTDLGEXA */
1202 FIXME("stub\n");
1203 return E_NOTIMPL;
1205 /***********************************************************************
1206 * PrintDlgExW
1208 HRESULT WINAPI PrintDlgExW(LPVOID lpPrintDlgExW) /* [???] FIXME: LPPRINTDLGEXW */
1210 FIXME("stub\n");
1211 return E_NOTIMPL;