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