source: trunk/src/comdlg32/comdlg32.cpp@ 21630

Last change on this file since 21630 was 21630, checked in by dmik, 14 years ago

comdlg32: Made PrintDlg() use the native PM print dialog instead of the Win32 clone. This looks much more native and gives access to all printer settings. Note that PageSetupDlg() is a no-op now (always returns FALSE) but it's not really necessary since thew native dialog gives access to page settings as well.

File size: 16.7 KB
Line 
1/* $Id: comdlg32.cpp,v 1.32 2001-08-02 14:49:55 sandervl Exp $ */
2
3/*
4 * COMDLG32 implementation
5 *
6 * Copyright 1998 Sander van Leeuwen
7 * Copyright 1999 Patrick Haller
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13
14/****************************************************************************
15 * Includes *
16 ****************************************************************************/
17
18#include <os2win.h>
19#include <stdarg.h>
20#include <stdlib.h>
21#include <string.h>
22#include <misc.h>
23#include <odinwrap.h>
24#include <winuser32.h>
25#include <unicode.h>
26#include <wingdi32.h>
27#include <codepage.h>
28
29ODINDEBUGCHANNEL(COMDLG32-COMDLG32)
30
31
32#define COMDLG32_CHECKHOOK(a,b,c) \
33 if(a->Flags & b) \
34 { \
35 a->lpfnHook = 0; \
36 } \
37 a->hwndOwner = Win32ToOS2Handle(a->hwndOwner);
38
39#define COMDLG32_CHECKHOOK2(a,b,c,d) \
40 if(a->Flags & b) \
41 { \
42 a->d = 0; \
43 } \
44 a->hwndOwner = Win32ToOS2Handle(a->hwndOwner);
45
46// from gdi32/devcontext.cpp
47BOOL WIN32API GetPMQueueName(LPSTR pDeviceName, LPSTR lpszPMQueue, INT cbPMQueue);
48
49// USING_OPEN32 seems to be not necessary since the WGSS GlobalAlloc API appears
50// to be in line with the Odin32 GlobalAlloc API (and the current version of
51// WGSS doesn't export this API anyway)
52
53#ifdef USING_OPEN32
54
55#define FLAG_TO_OPEN32 0
56#define FLAG_FROM_OPEN32 1
57
58static HGLOBAL GlobalCopy(HGLOBAL hDest, HGLOBAL hSource, BOOL fToOpen32)
59{
60 LPVOID src;
61 LPVOID dest;
62 ULONG size;
63
64 if (fToOpen32 == FLAG_TO_OPEN32)
65 {
66 src = GlobalLock(hSource);
67 if (src)
68 {
69 size = GlobalSize(hSource);
70 if(hDest == NULL)
71 {
72 hDest = O32_GlobalAlloc(GHND, size);
73 }
74 dest = O32_GlobalLock(hDest);
75 memcpy(dest, src, size);
76 O32_GlobalUnlock(hDest);
77 }
78 GlobalUnlock(hSource);
79 }
80 else
81 {
82 src = O32_GlobalLock(hSource);
83 if (src)
84 {
85 size = O32_GlobalSize(hSource);
86 if(hDest == NULL)
87 {
88 hDest = GlobalAlloc(GHND, size);
89 }
90 dest = GlobalLock(hDest);
91 memcpy(dest, src, size);
92 GlobalUnlock(hDest);
93 }
94 O32_GlobalUnlock(hSource);
95 }
96 return hDest;
97}
98
99#define MyGlobalAlloc O32_GlobalAlloc
100#define MyGlobalLock O32_GlobalLock
101#define MyGlobalUnlock O32_GlobalUnlock
102#define MyGlobalFree O32_GlobalFree
103#define MyGlobalSize O32_GlobalSize
104
105#else
106
107#define MyGlobalAlloc GlobalAlloc
108#define MyGlobalLock GlobalLock
109#define MyGlobalUnlock GlobalUnlock
110#define MyGlobalFree GlobalFree
111#define MyGlobalSize GlobalSize
112
113#endif
114
115/*****************************************************************************
116 * Name :
117 * Purpose :
118 * Parameters:
119 * Variables :
120 * Result :
121 * Remark :
122 * Status :
123 *
124 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
125 *****************************************************************************/
126
127ODINFUNCTION1(BOOL, PrintDlgA,
128 LPPRINTDLGA, lppd)
129{
130 BOOL ret;
131#ifdef USING_OPEN32
132 HGLOBAL hOrgDevMode = 0, hOrgDevNames = 0;
133#endif
134 LPSTR origDevice = NULL;
135
136 COMDLG32_CHECKHOOK2(lppd, PD_ENABLEPRINTHOOK, LPPRINTHOOKPROC,lpfnPrintHook)
137 COMDLG32_CHECKHOOK2(lppd, PD_ENABLESETUPHOOK, LPSETUPHOOKPROC,lpfnSetupHook)
138
139#ifdef USING_OPEN32
140 if (lppd->hDevMode)
141 {
142 hOrgDevMode = lppd->hDevMode;
143 lppd->hDevMode = GlobalCopy(NULL, hOrgDevMode, FLAG_TO_OPEN32);
144 }
145 if (lppd->hDevNames)
146 {
147 hOrgDevNames = lppd->hDevNames;
148 lppd->hDevNames = GlobalCopy(NULL, hOrgDevNames, FLAG_TO_OPEN32);
149 }
150#endif
151
152 if (lppd->hDevNames)
153 {
154 LPDEVNAMES devNames = (LPDEVNAMES)MyGlobalLock(lppd->hDevNames);
155
156 LPSTR driver = (LPSTR)devNames + devNames->wDriverOffset;
157 LPSTR device = (LPSTR)devNames + devNames->wDeviceOffset;
158 LPSTR output = (LPSTR)devNames + devNames->wOutputOffset;
159 int driverLen = lstrlenA(driver) + 1;
160 int deviceLen = lstrlenA(device) + 1;
161 int outputLen = lstrlenA(output) + 1;
162
163 // get the PM queue name for the device (which is usually the full
164 // PM printer's WPS object name): WGSS expects it and will correctly
165 // pre-select the printer specified in hDevNames. Note that we don't
166 // perform the opposite conversion from the PM queue to the device name
167 // after calling O32_PrintDlg() since this seems to work as it is:
168 // the dialog returns the correct DC when OK is pressed despite the name
169 // mismatch
170
171 CHAR queue[256];
172 if (GetPMQueueName(device, queue, sizeof(queue)))
173 {
174 dprintf(("PrintDlgA: renamed device {%s} to PM queue {%s}",
175 device, queue));
176 device = queue;
177 deviceLen = lstrlenA(device) + 1;
178
179 HGLOBAL hDevNames2 =
180 MyGlobalAlloc(GHND, MyGlobalSize(lppd->hDevNames) +
181 lstrlenA(queue) - (deviceLen - 1));
182
183 LPDEVNAMES devNames2 = (LPDEVNAMES)MyGlobalLock(hDevNames2);
184
185 devNames2->wDriverOffset = sizeof(DEVNAMES);
186 memcpy((LPSTR)devNames2 + devNames2->wDriverOffset, driver, driverLen);
187 devNames2->wDeviceOffset = devNames2->wDriverOffset + driverLen;
188 memcpy((LPSTR)devNames2 + devNames2->wDeviceOffset, device, deviceLen);
189 devNames2->wOutputOffset = devNames2->wDeviceOffset + deviceLen;
190 memcpy((LPSTR)devNames2 + devNames2->wOutputOffset, output, outputLen);
191 devNames2->wDefault = devNames->wDefault;
192
193 MyGlobalUnlock(hDevNames2);
194
195 MyGlobalUnlock(lppd->hDevNames);
196 MyGlobalFree(lppd->hDevNames);
197 lppd->hDevNames = hDevNames2;
198 }
199 else
200 MyGlobalUnlock(lppd->hDevNames);
201 }
202
203 HWND hwndOwner = lppd->hwndOwner;
204 if (lppd->hwndOwner)
205 {
206 lppd->hwndOwner = Win32ToOS2Handle(lppd->hwndOwner);
207 }
208
209 ret = O32_PrintDlg(lppd);
210
211 lppd->hwndOwner = hwndOwner;
212
213#ifdef USING_OPEN32
214 if (ret == TRUE)
215 {
216 if (lppd->hDevMode)
217 {
218 HGLOBAL hDevMode = lppd->hDevMode;
219 lppd->hDevMode = GlobalCopy(hOrgDevMode, lppd->hDevMode,
220 FLAG_FROM_OPEN32);
221 O32_GlobalFree(hDevMode);
222 }
223 if (lppd->hDevNames)
224 {
225 HGLOBAL hDevNames = lppd->hDevNames;
226 lppd->hDevNames = GlobalCopy(hOrgDevNames, lppd->hDevNames,
227 FLAG_FROM_OPEN32);
228 O32_GlobalFree(hDevNames);
229 }
230 }
231 else
232 {
233 if (lppd->hDevMode)
234 {
235 O32_GlobalFree(lppd->hDevMode);
236 lppd->hDevMode = hOrgDevMode;
237 }
238 if (lppd->hDevNames)
239 {
240 O32_GlobalFree(lppd->hDevNames);
241 lppd->hDevNames = hOrgDevNames;
242 }
243 }
244#endif
245
246 if(lppd->hDC)
247 {
248 OSLibGpiSetCp(lppd->hDC, GetDisplayCodepage());
249 }
250
251 return ret;
252}
253
254
255/*****************************************************************************
256 * Name :
257 * Purpose :
258 * Parameters:
259 * Variables :
260 * Result :
261 * Remark :
262 * Status :
263 *
264 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
265 *****************************************************************************/
266
267ODINFUNCTION1(BOOL, PrintDlgW,
268 LPPRINTDLGW, lppd)
269{
270 PRINTDLGA pd;
271 BOOL bResult;
272
273 memcpy(&pd, // make binary copy first to save all the fields
274 lppd,
275 sizeof(pd));
276
277 if (lppd->hwndOwner)
278 {
279 pd.hwndOwner = Win32ToOS2Handle(lppd->hwndOwner);
280 }
281
282 if (lppd->hDevMode)
283 {
284 LPDEVMODEW devMode = (LPDEVMODEW)GlobalLock(lppd->hDevMode);
285
286 dprintf(("PrintDlgW: in devMode{%.*ls,%.*ls}",
287 CCHDEVICENAME, devMode->dmDeviceName,
288 CCHFORMNAME, devMode->dmFormName));
289
290 pd.hDevMode = MyGlobalAlloc(GHND, sizeof(DEVMODEA));
291
292 LPDEVMODEA devModeA = (LPDEVMODEA)MyGlobalLock(pd.hDevMode);
293
294 // convert to ASCII string
295 UnicodeToAsciiN((LPWSTR)devMode->dmDeviceName, (LPSTR)devModeA->dmDeviceName,
296 CCHDEVICENAME);
297 UnicodeToAsciiN((LPWSTR)devMode->dmFormName, (LPSTR)devModeA->dmFormName,
298 CCHFORMNAME);
299
300 MyGlobalLock(pd.hDevMode);
301 GlobalLock(lppd->hDevMode);
302 }
303
304 if (lppd->hDevNames)
305 {
306 LPDEVNAMES devNames = (LPDEVNAMES)GlobalLock(lppd->hDevNames);
307
308 dprintf(("PrintDlgW: in devNames{%ls,%ls,%ls}",
309 (LPCWSTR)devNames + devNames->wDriverOffset,
310 (LPCWSTR)devNames + devNames->wDeviceOffset,
311 (LPCWSTR)devNames + devNames->wOutputOffset));
312
313 // convert to ASCII string
314 LPSTR driver = UnicodeToAsciiString((LPCWSTR)devNames + devNames->wDriverOffset);
315 LPSTR device = UnicodeToAsciiString((LPCWSTR)devNames + devNames->wDeviceOffset);
316 LPSTR output = UnicodeToAsciiString((LPCWSTR)devNames + devNames->wOutputOffset);
317 int driverLen = lstrlenA(driver) + 1;
318 int deviceLen = lstrlenA(device) + 1;
319 int outputLen = lstrlenA(output) + 1;
320
321 // get the PM queue name for the device (which is usually the full
322 // PM printer's WPS object name): WGSS expects it and will correctly
323 // pre-select the printer specified in hDevNames. Note that we don't
324 // perform the opposite conversion from the PM queue to the device name
325 // after calling O32_PrintDlg() since this seems to work as it is:
326 // the dialog returns the correct DC when OK is pressed despite the name
327 // mismatch
328
329 CHAR queue[256];
330 if (GetPMQueueName(device, queue, sizeof(queue)))
331 {
332 dprintf(("PrintDlgW: renamed device {%s} to PM queue {%s}",
333 device, queue));
334 device = queue;
335 deviceLen = lstrlenA(device) + 1;
336 }
337
338 pd.hDevNames = MyGlobalAlloc(GHND, sizeof(DEVNAMES) +
339 driverLen + deviceLen + outputLen);
340
341 LPDEVNAMES devNamesA = (LPDEVNAMES)MyGlobalLock(pd.hDevNames);
342
343 devNamesA->wDriverOffset = sizeof(DEVNAMES);
344 memcpy((LPSTR)devNamesA + devNamesA->wDriverOffset, driver, driverLen);
345 devNamesA->wDeviceOffset = devNamesA->wDriverOffset + driverLen;
346 memcpy((LPSTR)devNamesA + devNamesA->wDeviceOffset, device, deviceLen);
347 devNamesA->wOutputOffset = devNamesA->wDeviceOffset + deviceLen;
348 memcpy((LPSTR)devNamesA + devNamesA->wOutputOffset, output, outputLen);
349 devNamesA->wDefault = devNames->wDefault;
350
351 FreeAsciiString(output);
352 if (device != queue)
353 FreeAsciiString(device);
354 FreeAsciiString(driver);
355
356 MyGlobalUnlock(pd.hDevNames);
357 GlobalUnlock(lppd->hDevNames);
358 }
359
360 // convert to ASCII string
361 if ((lppd->Flags & PD_ENABLEPRINTTEMPLATE) &&
362 (lppd->lpPrintTemplateName != NULL))
363 pd.lpPrintTemplateName = UnicodeToAsciiString((WCHAR*)lppd->lpPrintTemplateName);
364 else
365 pd.lpPrintTemplateName = NULL;
366
367 if ((lppd->Flags & PD_ENABLESETUPTEMPLATE) &&
368 (lppd->lpSetupTemplateName != NULL))
369 pd.lpSetupTemplateName = UnicodeToAsciiString((WCHAR*)lppd->lpSetupTemplateName);
370 else
371 pd.lpSetupTemplateName = NULL;
372
373 COMDLG32_CHECKHOOK2((&pd), PD_ENABLEPRINTHOOK, LPPRINTHOOKPROC, lpfnPrintHook)
374 COMDLG32_CHECKHOOK2((&pd), PD_ENABLESETUPHOOK, LPSETUPHOOKPROC, lpfnSetupHook)
375
376 bResult = O32_PrintDlg(&pd); // call ASCII API
377
378 if (pd.lpPrintTemplateName != NULL)
379 FreeAsciiString((char*)pd.lpPrintTemplateName);
380 if (pd.lpSetupTemplateName != NULL)
381 FreeAsciiString((char*)pd.lpSetupTemplateName);
382
383 if (pd.hDevNames)
384 {
385 LPDEVNAMES devNames = (LPDEVNAMES)MyGlobalLock(pd.hDevNames);
386
387 dprintf(("PrintDlgW: out devNames{%s,%s,%s}",
388 (LPCSTR)devNames + devNames->wDriverOffset,
389 (LPCSTR)devNames + devNames->wDeviceOffset,
390 (LPCSTR)devNames + devNames->wOutputOffset));
391
392 LPSTR realDevice = (LPSTR)devNames + devNames->wDeviceOffset;
393
394 // convert from ASCII string
395 LPWSTR driver = AsciiToUnicodeString((LPCSTR)devNames + devNames->wDriverOffset);
396 LPWSTR device = AsciiToUnicodeString(realDevice);
397 LPWSTR output = AsciiToUnicodeString((LPCSTR)devNames + devNames->wOutputOffset);
398 int driverLen = (lstrlenW(driver) + 1) * sizeof(WCHAR);
399 int deviceLen = (lstrlenW(device) + 1) * sizeof(WCHAR);
400 int outputLen = (lstrlenW(output) + 1) * sizeof(WCHAR);
401
402 if (lppd->hDevNames)
403 lppd->hDevNames = GlobalReAlloc(lppd->hDevNames,
404 sizeof(DEVNAMES) +
405 driverLen + deviceLen + outputLen,
406 GHND);
407 else
408 lppd->hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) +
409 driverLen + deviceLen + outputLen);
410
411 LPDEVNAMES devNamesW = (LPDEVNAMES)GlobalLock(lppd->hDevNames);
412
413 devNamesW->wDriverOffset = sizeof(DEVNAMES) / sizeof(WCHAR);
414 memcpy((LPWSTR)devNamesW + devNamesW->wDriverOffset, driver, driverLen);
415 devNamesW->wDeviceOffset = devNamesW->wDriverOffset + (driverLen / sizeof(WCHAR));
416 memcpy((LPWSTR)devNamesW + devNamesW->wDeviceOffset, device, deviceLen);
417 devNamesW->wOutputOffset = devNamesW->wDeviceOffset + (deviceLen / sizeof(WCHAR));
418 memcpy((LPWSTR)devNamesW + devNamesW->wOutputOffset, output, outputLen);
419 devNamesW->wDefault = devNames->wDefault;
420
421 FreeAsciiString(output);
422 FreeAsciiString(device);
423 FreeAsciiString(driver);
424
425 GlobalUnlock(lppd->hDevNames);
426 MyGlobalUnlock(pd.hDevNames);
427
428 MyGlobalFree(pd.hDevNames);
429 }
430 else
431 {
432 if (lppd->hDevNames)
433 MyGlobalFree(lppd->hDevNames);
434 lppd->hDevNames = NULL;
435 }
436
437 if (pd.hDevMode)
438 {
439 LPDEVMODEA devMode = (LPDEVMODEA)MyGlobalLock(pd.hDevMode);
440
441 dprintf(("PrintDlgW: out devMode{%.*s,%.*s}",
442 CCHDEVICENAME, devMode->dmDeviceName,
443 CCHFORMNAME, devMode->dmFormName));
444
445 if (!lppd->hDevMode)
446 lppd->hDevMode = GlobalAlloc(GHND, sizeof(DEVMODEW));
447
448 LPDEVMODEW devModeW = (LPDEVMODEW)GlobalLock(lppd->hDevMode);
449
450 // convert from ASCII string
451 AsciiToUnicodeN((LPSTR)devMode->dmDeviceName, (LPWSTR)devModeW->dmDeviceName,
452 CCHDEVICENAME);
453 AsciiToUnicodeN((LPSTR)devMode->dmFormName, (LPWSTR)devModeW->dmFormName,
454 CCHFORMNAME);
455
456 memcpy(&devModeW->dmSpecVersion, &devMode->dmSpecVersion,
457 offsetof(DEVMODEW, dmFormName) - offsetof(DEVMODEW, dmSpecVersion));
458 memcpy(&devModeW->dmLogPixels, &devMode->dmLogPixels,
459 sizeof(DEVMODEW) - offsetof(DEVMODEW, dmLogPixels));
460
461 GlobalUnlock(lppd->hDevMode);
462 MyGlobalUnlock(pd.hDevMode);
463
464 MyGlobalFree(pd.hDevMode);
465 }
466 else
467 {
468 if (lppd->hDevNames)
469 MyGlobalFree(lppd->hDevNames);
470 lppd->hDevNames = NULL;
471 }
472
473 // copy back the rest
474 lppd->hDC = pd.hDC;
475 lppd->Flags = pd.Flags;
476 lppd->nFromPage = pd.nFromPage;
477 lppd->nToPage = pd.nToPage;
478 lppd->nMinPage = pd.nMinPage;
479 lppd->nMaxPage = pd.nMaxPage;
480 lppd->nCopies = pd.nCopies;
481
482 if (lppd->hDC)
483 {
484 OSLibGpiSetCp(lppd->hDC, GetDisplayCodepage());
485 }
486
487 return bResult;
488}
489
490
491/*****************************************************************************
492 * Name :
493 * Purpose :
494 * Parameters:
495 * Variables :
496 * Result :
497 * Remark :
498 * Status :
499 *
500 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
501 *****************************************************************************/
502
503ODINFUNCTION1(BOOL, PageSetupDlgA,
504 LPPAGESETUPDLGA, lppsd)
505{
506
507 dprintf(("COMDLG32: PageSetupDlgA not implemented.\n"));
508
509 //COMDLG32_CHECKHOOK2(lppsd, PSD_ENABLESETUPHOOK, LPPAGESETUPHOOK, lpfnPageSetupHook)
510
511 return(FALSE);
512}
513
514
515/*****************************************************************************
516 * Name :
517 * Purpose :
518 * Parameters:
519 * Variables :
520 * Result :
521 * Remark :
522 * Status :
523 *
524 * Author : Patrick Haller [Tue, 1998/02/10 01:55]
525 *****************************************************************************/
526
527ODINFUNCTION1(BOOL, PageSetupDlgW,
528 LPPAGESETUPDLGW, lppsd)
529{
530
531 dprintf(("COMDLG32: PageSetupDlgW(%08xh) not implemented.\n"));
532
533 //COMDLG32_CHECKHOOK2(lppsd, PSD_ENABLESETUPHOOK, LPPAGESETUPHOOK, lpfnPageSetupHook)
534
535 return(FALSE);
536}
537
Note: See TracBrowser for help on using the repository browser.