[COMDLG32_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / comdlg32 / printdlg.c
1 /*
2 * Unit test suite for comdlg32 API functions: printer dialogs
3 *
4 * Copyright 2006-2007 Detlef Riekenberg
5 * Copyright 2013 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23 #include "precomp.h"
24
25 /* ########################### */
26
27 extern const IID IID_IObjectWithSite;
28
29 static HMODULE hcomdlg32;
30 static HRESULT (WINAPI * pPrintDlgExW)(LPPRINTDLGEXW);
31
32 /* ########################### */
33
34 static const CHAR emptyA[] = "";
35 static const CHAR PrinterPortsA[] = "PrinterPorts";
36
37 /* ########################### */
38
39 static void test_PageSetupDlgA(void)
40 {
41 LPPAGESETUPDLGA pDlg;
42 DWORD res;
43
44 pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PAGESETUPDLGA)) * 2);
45 if (!pDlg) return;
46
47 SetLastError(0xdeadbeef);
48 res = PageSetupDlgA(NULL);
49 ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
50 "returned %u with %u and 0x%x (expected '0' and "
51 "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
52
53 ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
54 pDlg->lStructSize = sizeof(PAGESETUPDLGA) -1;
55 SetLastError(0xdeadbeef);
56 res = PageSetupDlgA(pDlg);
57 ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
58 "returned %u with %u and 0x%x (expected '0' and "
59 "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
60
61 ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
62 pDlg->lStructSize = sizeof(PAGESETUPDLGA) +1;
63 pDlg->Flags = PSD_RETURNDEFAULT;
64 SetLastError(0xdeadbeef);
65 res = PageSetupDlgA(pDlg);
66 ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
67 "returned %u with %u and 0x%x (expected '0' and CDERR_STRUCTSIZE)\n",
68 res, GetLastError(), CommDlgExtendedError());
69
70
71 ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
72 pDlg->lStructSize = sizeof(PAGESETUPDLGA);
73 pDlg->Flags = PSD_RETURNDEFAULT | PSD_NOWARNING;
74 SetLastError(0xdeadbeef);
75 res = PageSetupDlgA(pDlg);
76 ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
77 "returned %u with %u and 0x%x (expected '!= 0' or '0' and "
78 "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
79
80 if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
81 skip("No printer configured.\n");
82 HeapFree(GetProcessHeap(), 0, pDlg);
83 return;
84 }
85
86 ok( pDlg->hDevMode && pDlg->hDevNames,
87 "got %p and %p (expected '!= NULL' for both)\n",
88 pDlg->hDevMode, pDlg->hDevNames);
89
90 GlobalFree(pDlg->hDevMode);
91 GlobalFree(pDlg->hDevNames);
92
93 HeapFree(GetProcessHeap(), 0, pDlg);
94
95 }
96
97 /* ########################### */
98
99 static UINT_PTR CALLBACK print_hook_proc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
100 {
101 if (msg == WM_INITDIALOG)
102 {
103 /* some driver popup a dialog and hung the test or silently limit the number of copies,
104 when trying to set more than 999 copies */
105 SetDlgItemInt(hdlg, edt3, 123, FALSE);
106 PostMessageA(hdlg, WM_COMMAND, IDOK, FALSE);
107 }
108 return 0;
109 }
110
111 static void test_PrintDlgA(void)
112 {
113 DWORD res, n_copies = 0;
114 LPPRINTDLGA pDlg;
115 DEVNAMES *pDevNames;
116 LPCSTR driver;
117 LPCSTR device;
118 LPCSTR port;
119 CHAR buffer[MAX_PATH];
120 LPSTR ptr;
121 DEVMODEA *dm;
122
123 pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGA)) * 2);
124 if (!pDlg) return;
125
126
127 /* will crash with unpatched wine */
128 SetLastError(0xdeadbeef);
129 res = PrintDlgA(NULL);
130 ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
131 "returned %d with 0x%x and 0x%x (expected '0' and "
132 "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
133
134 ZeroMemory(pDlg, sizeof(PRINTDLGA));
135 pDlg->lStructSize = sizeof(PRINTDLGA) - 1;
136 SetLastError(0xdeadbeef);
137 res = PrintDlgA(pDlg);
138 ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
139 "returned %d with 0x%x and 0x%x (expected '0' and "
140 "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
141
142 ZeroMemory(pDlg, sizeof(PRINTDLGA));
143 pDlg->lStructSize = sizeof(PRINTDLGA) + 1;
144 pDlg->Flags = PD_RETURNDEFAULT;
145 SetLastError(0xdeadbeef);
146 res = PrintDlgA(pDlg);
147 ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
148 "returned %u with %u and 0x%x (expected '0' and "
149 "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
150
151
152 ZeroMemory(pDlg, sizeof(PRINTDLGA));
153 pDlg->lStructSize = sizeof(PRINTDLGA);
154 pDlg->Flags = PD_RETURNDEFAULT;
155 SetLastError(0xdeadbeef);
156 res = PrintDlgA(pDlg);
157 ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
158 "returned %d with 0x%x and 0x%x (expected '!= 0' or '0' and "
159 "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
160
161 if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
162 skip("No printer configured.\n");
163 HeapFree(GetProcessHeap(), 0, pDlg);
164 return;
165 }
166
167 ok(pDlg->hDevNames != NULL, "(expected '!= NULL')\n");
168 pDevNames = GlobalLock(pDlg->hDevNames);
169 ok(pDevNames != NULL, "(expected '!= NULL')\n");
170
171 if (pDevNames) {
172 ok(pDevNames->wDriverOffset, "(expected '!= 0' for wDriverOffset)\n");
173 ok(pDevNames->wDeviceOffset, "(expected '!= 0' for wDeviceOffset)\n");
174 ok(pDevNames->wOutputOffset, "(expected '!= 0' for wOutputOffset)\n");
175 ok(pDevNames->wDefault == DN_DEFAULTPRN, "got 0x%x (expected DN_DEFAULTPRN)\n", pDevNames->wDefault);
176
177 driver = (LPCSTR)pDevNames + pDevNames->wDriverOffset;
178 device = (LPCSTR)pDevNames + pDevNames->wDeviceOffset;
179 port = (LPCSTR)pDevNames + pDevNames->wOutputOffset;
180 trace("driver '%s' device '%s' port '%s'\n", driver, device, port);
181
182 /* The Driver Entry does not include a Path */
183 ptr = strrchr(driver, '\\');
184 ok( ptr == NULL, "got %p for '%s' (expected NULL for a simple name)\n", ptr, driver);
185
186 /* The Driver Entry does not have an extension (fixed to ".drv") */
187 ptr = strrchr(driver, '.');
188 todo_wine {
189 ok( ptr == NULL, "got %p for '%s' (expected NULL for no extension)\n", ptr, driver);
190 }
191
192
193 buffer[0] = '\0';
194 SetLastError(0xdeadbeef);
195 res = GetProfileStringA(PrinterPortsA, device, emptyA, buffer, sizeof(buffer));
196 ptr = strchr(buffer, ',');
197 ok( (res > 1) && (ptr != NULL),
198 "got %u with %u and %p for '%s' (expected '>1' and '!= NULL')\n",
199 res, GetLastError(), ptr, buffer);
200
201 if (ptr) ptr[0] = '\0';
202 ok( lstrcmpiA(driver, buffer) == 0,
203 "got driver '%s' (expected '%s')\n", driver, buffer);
204
205 n_copies = DeviceCapabilitiesA(device, port, DC_COPIES, NULL, NULL);
206 ok(n_copies > 0, "DeviceCapabilities(DC_COPIES) failed\n");
207 }
208
209 GlobalUnlock(pDlg->hDevNames);
210 GlobalFree(pDlg->hDevMode);
211 GlobalFree(pDlg->hDevNames);
212
213 /* if device doesn't support printing of multiple copies then
214 * an attempt to set number of copies > 1 in print dialog would
215 * cause the PrintDlg under Windows display the MessageBox and
216 * the test will hang waiting for user response.
217 */
218 if (n_copies > 1)
219 {
220 ZeroMemory(pDlg, sizeof(*pDlg));
221 pDlg->lStructSize = sizeof(*pDlg);
222 pDlg->Flags = PD_ENABLEPRINTHOOK;
223 pDlg->lpfnPrintHook = print_hook_proc;
224 res = PrintDlgA(pDlg);
225 ok(res, "PrintDlg error %#x\n", CommDlgExtendedError());
226 /* Version of Microsoft XPS Document Writer driver shipped before Win7
227 * reports that it can print multiple copies, but returns 1.
228 */
229 ok(pDlg->nCopies == 123 || broken(pDlg->nCopies == 1), "expected nCopies 123, got %d\n", pDlg->nCopies);
230 ok(pDlg->hDevMode != 0, "hDevMode should not be 0\n");
231 dm = GlobalLock(pDlg->hDevMode);
232 /* some broken drivers use always PD_USEDEVMODECOPIES */
233 ok((S1(U1(*dm)).dmCopies == 1) || broken(S1(U1(*dm)).dmCopies == 123),
234 "expected dm->dmCopies 1, got %d\n", S1(U1(*dm)).dmCopies);
235 GlobalUnlock(pDlg->hDevMode);
236 GlobalFree(pDlg->hDevMode);
237 GlobalFree(pDlg->hDevNames);
238
239 ZeroMemory(pDlg, sizeof(*pDlg));
240 pDlg->lStructSize = sizeof(*pDlg);
241 pDlg->Flags = PD_ENABLEPRINTHOOK | PD_USEDEVMODECOPIES;
242 pDlg->lpfnPrintHook = print_hook_proc;
243 res = PrintDlgA(pDlg);
244 ok(res, "PrintDlg error %#x\n", CommDlgExtendedError());
245 ok(pDlg->nCopies == 1, "expected nCopies 1, got %d\n", pDlg->nCopies);
246 ok(pDlg->hDevMode != 0, "hDevMode should not be 0\n");
247 dm = GlobalLock(pDlg->hDevMode);
248 ok(S1(U1(*dm)).dmCopies == 123, "expected dm->dmCopies 123, got %d\n", S1(U1(*dm)).dmCopies);
249 GlobalUnlock(pDlg->hDevMode);
250 GlobalFree(pDlg->hDevMode);
251 GlobalFree(pDlg->hDevNames);
252 }
253
254 HeapFree(GetProcessHeap(), 0, pDlg);
255 }
256
257 /* ########################### */
258
259 static HRESULT WINAPI callback_QueryInterface(IPrintDialogCallback *iface,
260 REFIID riid, void **ppv)
261 {
262 ok(0, "callback_QueryInterface(%s): unexpected call\n", wine_dbgstr_guid(riid));
263 return E_NOINTERFACE;
264 }
265
266 static ULONG WINAPI callback_AddRef(IPrintDialogCallback *iface)
267 {
268 trace("callback_AddRef\n");
269 return 2;
270 }
271
272 static ULONG WINAPI callback_Release(IPrintDialogCallback *iface)
273 {
274 trace("callback_Release\n");
275 return 1;
276 }
277
278 static HRESULT WINAPI callback_InitDone(IPrintDialogCallback *iface)
279 {
280 trace("callback_InitDone\n");
281 return S_OK;
282 }
283
284 static HRESULT WINAPI callback_SelectionChange(IPrintDialogCallback *iface)
285 {
286 trace("callback_SelectionChange\n");
287 return S_OK;
288 }
289
290 static HRESULT WINAPI callback_HandleMessage(IPrintDialogCallback *iface,
291 HWND hdlg, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res)
292 {
293 trace("callback_HandleMessage %p,%04x,%lx,%lx,%p\n", hdlg, msg, wp, lp, res);
294 /* *res = PD_RESULT_PRINT; */
295 return S_OK;
296 }
297
298 static const IPrintDialogCallbackVtbl callback_Vtbl =
299 {
300 callback_QueryInterface,
301 callback_AddRef,
302 callback_Release,
303 callback_InitDone,
304 callback_SelectionChange,
305 callback_HandleMessage
306 };
307
308 static IPrintDialogCallback callback = { &callback_Vtbl };
309
310 static HRESULT WINAPI unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
311 {
312 trace("unknown_QueryInterface %s\n", wine_dbgstr_guid(riid));
313
314 if (IsEqualGUID(riid, &IID_IPrintDialogCallback))
315 {
316 *ppv = &callback;
317 return S_OK;
318 }
319 else if (IsEqualGUID(riid, &IID_IObjectWithSite))
320 {
321 *ppv = NULL;
322 return E_NOINTERFACE;
323 }
324
325 ok(0, "unexpected IID %s\n", wine_dbgstr_guid(riid));
326 *ppv = NULL;
327 return E_NOINTERFACE;
328 }
329
330 static ULONG WINAPI unknown_AddRef(IUnknown *iface)
331 {
332 trace("unknown_AddRef\n");
333 return 2;
334 }
335
336 static ULONG WINAPI unknown_Release(IUnknown *iface)
337 {
338 trace("unknown_Release\n");
339 return 1;
340 }
341
342 static const IUnknownVtbl unknown_Vtbl =
343 {
344 unknown_QueryInterface,
345 unknown_AddRef,
346 unknown_Release
347 };
348
349 static IUnknown unknown = { &unknown_Vtbl };
350
351 static void test_PrintDlgExW(void)
352 {
353 PRINTPAGERANGE pagerange[2];
354 LPPRINTDLGEXW pDlg;
355 DEVNAMES *dn;
356 HRESULT res;
357
358 /* PrintDlgEx not present before w2k */
359 if (!pPrintDlgExW) {
360 skip("PrintDlgExW not available\n");
361 return;
362 }
363
364 if (0) /* Crashes on Win10 */
365 {
366 /* Set CommDlgExtendedError != 0 */
367 PrintDlgA(NULL);
368 SetLastError(0xdeadbeef);
369 res = pPrintDlgExW(NULL);
370 ok( (res == E_INVALIDARG),
371 "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
372 res, GetLastError(), CommDlgExtendedError() );
373 }
374
375 pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGEXW)) + 8);
376 if (!pDlg) return;
377
378 /* lStructSize must be exact */
379 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
380 pDlg->lStructSize = sizeof(PRINTDLGEXW) - 1;
381 PrintDlgA(NULL);
382 SetLastError(0xdeadbeef);
383 res = pPrintDlgExW(pDlg);
384 ok( (res == E_INVALIDARG),
385 "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
386 res, GetLastError(), CommDlgExtendedError());
387
388
389 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
390 pDlg->lStructSize = sizeof(PRINTDLGEXW) + 1;
391 PrintDlgA(NULL);
392 SetLastError(0xdeadbeef);
393 res = pPrintDlgExW(pDlg);
394 ok( (res == E_INVALIDARG),
395 "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
396 res, GetLastError(), CommDlgExtendedError());
397
398
399 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
400 pDlg->lStructSize = sizeof(PRINTDLGEXW);
401 SetLastError(0xdeadbeef);
402 res = pPrintDlgExW(pDlg);
403 ok( (res == E_HANDLE),
404 "got 0x%x with %u and %u (expected 'E_HANDLE')\n",
405 res, GetLastError(), CommDlgExtendedError());
406
407 /* nStartPage must be START_PAGE_GENERAL for the general page or a valid property sheet index */
408 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
409 pDlg->lStructSize = sizeof(PRINTDLGEXW);
410 pDlg->hwndOwner = GetDesktopWindow();
411 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING | PD_NOPAGENUMS;
412 res = pPrintDlgExW(pDlg);
413 ok((res == E_INVALIDARG), "got 0x%x (expected 'E_INVALIDARG')\n", res);
414
415 /* Use PD_NOPAGENUMS or set nMaxPageRanges and lpPageRanges */
416 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
417 pDlg->lStructSize = sizeof(PRINTDLGEXW);
418 pDlg->hwndOwner = GetDesktopWindow();
419 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING;
420 pDlg->nStartPage = START_PAGE_GENERAL;
421 res = pPrintDlgExW(pDlg);
422 ok((res == E_INVALIDARG), "got 0x%x (expected 'E_INVALIDARG')\n", res);
423
424 /* this is invalid: a valid lpPageRanges with 0 for nMaxPageRanges */
425 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
426 pDlg->lStructSize = sizeof(PRINTDLGEXW);
427 pDlg->hwndOwner = GetDesktopWindow();
428 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING;
429 pDlg->lpPageRanges = pagerange;
430 pDlg->nStartPage = START_PAGE_GENERAL;
431 res = pPrintDlgExW(pDlg);
432 ok((res == E_INVALIDARG), "got 0x%x (expected 'E_INVALIDARG')\n", res);
433
434 /* this is invalid: NULL for lpPageRanges with a valid nMaxPageRanges */
435 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
436 pDlg->lStructSize = sizeof(PRINTDLGEXW);
437 pDlg->hwndOwner = GetDesktopWindow();
438 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING;
439 pDlg->nMaxPageRanges = 1;
440 pDlg->nStartPage = START_PAGE_GENERAL;
441 res = pPrintDlgExW(pDlg);
442 ok((res == E_INVALIDARG), "got 0x%x (expected 'E_INVALIDARG')\n", res);
443
444 /* this works: lpPageRanges with a valid nMaxPageRanges */
445 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
446 pDlg->lStructSize = sizeof(PRINTDLGEXW);
447 pDlg->hwndOwner = GetDesktopWindow();
448 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING;
449 pDlg->nMaxPageRanges = 1;
450 pDlg->lpPageRanges = pagerange;
451 pDlg->nStartPage = START_PAGE_GENERAL;
452 res = pPrintDlgExW(pDlg);
453 if (res == E_FAIL)
454 {
455 skip("No printer configured.\n");
456 HeapFree(GetProcessHeap(), 0, pDlg);
457 return;
458 }
459
460 ok(res == S_OK, "got 0x%x (expected S_OK)\n", res);
461
462 dn = GlobalLock(pDlg->hDevNames);
463 ok(dn != NULL, "expected '!= NULL' for GlobalLock(%p)\n",pDlg->hDevNames);
464 if (dn)
465 {
466 ok(dn->wDriverOffset, "(expected '!= 0' for wDriverOffset)\n");
467 ok(dn->wDeviceOffset, "(expected '!= 0' for wDeviceOffset)\n");
468 ok(dn->wOutputOffset, "(expected '!= 0' for wOutputOffset)\n");
469 ok(dn->wDefault == DN_DEFAULTPRN, "got 0x%x (expected DN_DEFAULTPRN)\n", dn->wDefault);
470
471 GlobalUnlock(pDlg->hDevNames);
472 }
473 GlobalFree(pDlg->hDevMode);
474 GlobalFree(pDlg->hDevNames);
475
476 /* this works also: PD_NOPAGENUMS */
477 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
478 pDlg->lStructSize = sizeof(PRINTDLGEXW);
479 pDlg->hwndOwner = GetDesktopWindow();
480 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING | PD_NOPAGENUMS;
481 pDlg->nStartPage = START_PAGE_GENERAL;
482 res = pPrintDlgExW(pDlg);
483 ok(res == S_OK, "got 0x%x (expected S_OK)\n", res);
484 GlobalFree(pDlg->hDevMode);
485 GlobalFree(pDlg->hDevNames);
486
487 /* this works: PD_RETURNDC with PD_RETURNDEFAULT */
488 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
489 pDlg->lStructSize = sizeof(PRINTDLGEXW);
490 pDlg->hwndOwner = GetDesktopWindow();
491 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING | PD_NOPAGENUMS | PD_RETURNDC;
492 pDlg->nStartPage = START_PAGE_GENERAL;
493 res = pPrintDlgExW(pDlg);
494 ok(res == S_OK, "got 0x%x (expected S_OK)\n", res);
495 ok(pDlg->hDC != NULL, "HDC missing for PD_RETURNDC\n");
496 GlobalFree(pDlg->hDevMode);
497 GlobalFree(pDlg->hDevNames);
498 DeleteDC(pDlg->hDC);
499
500 /* this works: PD_RETURNIC with PD_RETURNDEFAULT */
501 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
502 pDlg->lStructSize = sizeof(PRINTDLGEXW);
503 pDlg->hwndOwner = GetDesktopWindow();
504 pDlg->Flags = PD_RETURNDEFAULT | PD_NOWARNING | PD_NOPAGENUMS | PD_RETURNIC;
505 pDlg->nStartPage = START_PAGE_GENERAL;
506 res = pPrintDlgExW(pDlg);
507 ok(res == S_OK, "got 0x%x (expected S_OK)\n", res);
508 ok(pDlg->hDC != NULL, "HDC missing for PD_RETURNIC\n");
509 GlobalFree(pDlg->hDevMode);
510 GlobalFree(pDlg->hDevNames);
511 DeleteDC(pDlg->hDC);
512
513 /* interactive PrintDlgEx tests */
514
515 if (!winetest_interactive)
516 {
517 skip("interactive PrintDlgEx tests (set WINETEST_INTERACTIVE=1)\n");
518 HeapFree(GetProcessHeap(), 0, pDlg);
519 return;
520 }
521
522 ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
523 pDlg->lStructSize = sizeof(PRINTDLGEXW);
524 pDlg->hwndOwner = GetDesktopWindow();
525 pDlg->Flags = PD_NOPAGENUMS | PD_RETURNIC;
526 pDlg->nStartPage = START_PAGE_GENERAL;
527 pDlg->lpCallback = &unknown;
528 pDlg->dwResultAction = S_OK;
529 res = pPrintDlgExW(pDlg);
530 ok(res == S_OK, "got 0x%x (expected S_OK)\n", res);
531 ok(pDlg->dwResultAction == PD_RESULT_PRINT, "expected PD_RESULT_PRINT, got %#x\n", pDlg->dwResultAction);
532 ok(pDlg->hDC != NULL, "HDC missing for PD_RETURNIC\n");
533 GlobalFree(pDlg->hDevMode);
534 GlobalFree(pDlg->hDevNames);
535 DeleteDC(pDlg->hDC);
536
537 HeapFree(GetProcessHeap(), 0, pDlg);
538 }
539
540 static BOOL abort_proc_called = FALSE;
541 static BOOL CALLBACK abort_proc(HDC hdc, int error) { return abort_proc_called = TRUE; }
542 static void test_abort_proc(void)
543 {
544 HDC print_dc;
545 RECT rect = {0, 0, 100, 100};
546 DOCINFOA doc_info = {0};
547 PRINTDLGA pd = {0};
548 char filename[MAX_PATH];
549 int job_id;
550
551 if (!GetTempFileNameA(".", "prn", 0, filename))
552 {
553 skip("Failed to create a temporary file name\n");
554 return;
555 }
556
557 pd.lStructSize = sizeof(pd);
558 pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
559 pd.nFromPage = 1;
560 pd.nToPage = 1;
561 pd.nCopies = 1;
562
563 if (!PrintDlgA(&pd))
564 {
565 skip("No default printer available.\n");
566 goto end;
567 }
568 GlobalFree(pd.hDevMode);
569 GlobalFree(pd.hDevNames);
570
571 ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
572 if (!(print_dc = pd.hDC))
573 goto end;
574
575 ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n");
576 ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n");
577 abort_proc_called = FALSE;
578
579 doc_info.cbSize = sizeof(doc_info);
580 doc_info.lpszDocName = "Some document";
581 doc_info.lpszOutput = filename;
582
583 job_id = StartDocA(print_dc, &doc_info);
584
585 ok(job_id > 0 ||
586 GetLastError() == ERROR_SPL_NO_STARTDOC, /* Vista can fail with this error when using the XPS driver */
587 "StartDocA failed ret %d gle %d\n", job_id, GetLastError());
588
589 if(job_id <= 0)
590 {
591 skip("StartDoc failed\n");
592 goto end;
593 }
594
595 /* StartDoc may or may not call abort proc */
596
597 abort_proc_called = FALSE;
598 ok(StartPage(print_dc) > 0, "StartPage failed\n");
599 ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
600 abort_proc_called = FALSE;
601
602 /* following functions sometimes call abort proc too */
603 ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
604 ok(EndPage(print_dc) > 0, "EndPage failed\n");
605 ok(EndDoc(print_dc) > 0, "EndDoc failed\n");
606
607 abort_proc_called = FALSE;
608 ok(DeleteDC(print_dc), "DeleteDC failed\n");
609 ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
610 abort_proc_called = FALSE;
611
612 end:
613 SetLastError(0xdeadbeef);
614 if(!DeleteFileA(filename))
615 trace("Failed to delete temporary file (err = %x)\n", GetLastError());
616 }
617
618 /* ########################### */
619
620 START_TEST(printdlg)
621 {
622 hcomdlg32 = GetModuleHandleA("comdlg32.dll");
623 pPrintDlgExW = (void *) GetProcAddress(hcomdlg32, "PrintDlgExW");
624
625 test_PageSetupDlgA();
626 test_PrintDlgA();
627 test_PrintDlgExW();
628 test_abort_proc();
629 }