shell32: Add IShellFolderView::RemoveObject for IShellView.
[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 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "objbase.h"
30
31 #include "cderr.h"
32 #include "commdlg.h"
33
34 #include "wine/test.h"
35
36 /* ########################### */
37
38 static HMODULE  hcomdlg32;
39 static HRESULT (WINAPI * pPrintDlgExA)(LPPRINTDLGEXA);
40 static HRESULT (WINAPI * pPrintDlgExW)(LPPRINTDLGEXW);
41
42 /* ########################### */
43
44 static const CHAR emptyA[] = "";
45 static const CHAR PrinterPortsA[] = "PrinterPorts";
46
47 /* ########################### */
48
49 static LPCSTR load_functions(void)
50 {
51     LPCSTR  ptr;
52
53     ptr = "comdlg32.dll";
54     hcomdlg32 = GetModuleHandleA(ptr);
55
56     ptr = "PrintDlgExA";
57     pPrintDlgExA = (void *) GetProcAddress(hcomdlg32, ptr);
58     if (!pPrintDlgExA) return ptr;
59
60     ptr = "PrintDlgExW";
61     pPrintDlgExW = (void *) GetProcAddress(hcomdlg32, ptr);
62     if (!pPrintDlgExW) return ptr;
63
64     return NULL;
65
66 }
67
68 /* ########################### */
69
70 static void test_PageSetupDlgA(void)
71 {
72     LPPAGESETUPDLGA pDlg;
73     DWORD res;
74
75     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PAGESETUPDLGA)) * 2);
76     if (!pDlg) return;
77
78     SetLastError(0xdeadbeef);
79     res = PageSetupDlgA(NULL);
80     ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
81         "returned %u with %u and 0x%x (expected '0' and "
82         "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
83
84     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
85     pDlg->lStructSize = sizeof(PAGESETUPDLGA) -1;
86     SetLastError(0xdeadbeef);
87     res = PageSetupDlgA(pDlg);
88     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
89         "returned %u with %u and 0x%x (expected '0' and "
90         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
91
92     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
93     pDlg->lStructSize = sizeof(PAGESETUPDLGA) +1;
94     pDlg->Flags = PSD_RETURNDEFAULT;
95     SetLastError(0xdeadbeef);
96     res = PageSetupDlgA(pDlg);
97     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
98         "returned %u with %u and 0x%x (expected '0' and CDERR_STRUCTSIZE)\n",
99         res, GetLastError(), CommDlgExtendedError());
100
101
102     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
103     pDlg->lStructSize = sizeof(PAGESETUPDLGA);
104     pDlg->Flags = PSD_RETURNDEFAULT | PSD_NOWARNING;
105     SetLastError(0xdeadbeef);
106     res = PageSetupDlgA(pDlg);
107     ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
108         "returned %u with %u and 0x%x (expected '!= 0' or '0' and "
109         "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
110
111     if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
112         skip("No printer configured.\n");
113         HeapFree(GetProcessHeap(), 0, pDlg);
114         return;
115     }
116
117     ok( pDlg->hDevMode && pDlg->hDevNames,
118         "got %p and %p (expected '!= NULL' for both)\n",
119         pDlg->hDevMode, pDlg->hDevNames);
120
121     GlobalFree(pDlg->hDevMode);
122     GlobalFree(pDlg->hDevNames);
123
124     HeapFree(GetProcessHeap(), 0, pDlg);
125
126 }
127
128 /* ########################### */
129
130 static void test_PrintDlgA(void)
131 {
132     DWORD       res;
133     LPPRINTDLGA pDlg;
134     DEVNAMES    *pDevNames;
135     LPCSTR driver;
136     LPCSTR device;
137     LPCSTR port;
138     CHAR   buffer[MAX_PATH];
139     LPSTR  ptr;
140
141
142     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGA)) * 2);
143     if (!pDlg) return;
144
145
146     /* will crash with unpatched wine */
147     SetLastError(0xdeadbeef);
148     res = PrintDlgA(NULL);
149     ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
150         "returned %d with 0x%x and 0x%x (expected '0' and "
151         "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
152
153     ZeroMemory(pDlg, sizeof(PRINTDLGA));
154     pDlg->lStructSize = sizeof(PRINTDLGA) - 1;
155     SetLastError(0xdeadbeef);
156     res = PrintDlgA(pDlg);
157     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
158         "returned %d with 0x%x and 0x%x (expected '0' and "
159         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
160
161     ZeroMemory(pDlg, sizeof(PRINTDLGA));
162     pDlg->lStructSize = sizeof(PRINTDLGA) + 1;
163     pDlg->Flags = PD_RETURNDEFAULT;
164     SetLastError(0xdeadbeef);
165     res = PrintDlgA(pDlg);
166     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
167         "returned %u with %u and 0x%x (expected '0' and "
168         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
169
170
171     ZeroMemory(pDlg, sizeof(PRINTDLGA));
172     pDlg->lStructSize = sizeof(PRINTDLGA);
173     pDlg->Flags = PD_RETURNDEFAULT;
174     SetLastError(0xdeadbeef);
175     res = PrintDlgA(pDlg);
176     ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
177         "returned %d with 0x%x and 0x%x (expected '!= 0' or '0' and "
178         "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
179
180     if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
181         skip("No printer configured.\n");
182         HeapFree(GetProcessHeap(), 0, pDlg);
183         return;
184     }
185
186     ok(pDlg->hDevNames != NULL, "(expected '!= NULL')\n");
187     pDevNames = GlobalLock(pDlg->hDevNames);
188     ok(pDevNames != NULL, "(expected '!= NULL')\n");
189
190     if (pDevNames) {
191         ok(pDevNames->wDriverOffset, "(expected '!= 0' for wDriverOffset)\n");
192         ok(pDevNames->wDeviceOffset, "(expected '!= 0' for wDeviceOffset)\n");
193         ok(pDevNames->wOutputOffset, "(expected '!= 0' for wOutputOffset)\n");
194         ok(pDevNames->wDefault == DN_DEFAULTPRN, "got 0x%x (expected DN_DEFAULTPRN)\n", pDevNames->wDefault);
195
196         driver = (LPCSTR)pDevNames + pDevNames->wDriverOffset;
197         device = (LPCSTR)pDevNames + pDevNames->wDeviceOffset;
198         port = (LPCSTR)pDevNames + pDevNames->wOutputOffset;
199         trace("driver '%s' device '%s' port '%s'\n", driver, device, port);
200
201         /* The Driver Entry does not include a Path */
202         ptr = strrchr(driver, '\\');
203         todo_wine {
204         ok( ptr == NULL, "got %p for '%s' (expected NULL for a simple name)\n", ptr, driver);
205         }
206
207         /* The Driver Entry does not have an extension (fixed to ".drv") */
208         ptr = strrchr(driver, '.');
209         todo_wine {
210         ok( ptr == NULL, "got %p for '%s' (expected NULL for no extension)\n", ptr, driver);
211         }
212
213
214         buffer[0] = '\0';
215         SetLastError(0xdeadbeef);
216         res = GetProfileStringA(PrinterPortsA, device, emptyA, buffer, sizeof(buffer));
217         ptr = strchr(buffer, ',');
218         ok( (res > 1) && (ptr != NULL),
219             "got %u with %u and %p for '%s' (expected '>1' and '!= NULL')\n",
220             res, GetLastError(), ptr, buffer);
221
222         if (ptr) ptr[0] = '\0';
223         todo_wine {
224         ok( lstrcmpiA(driver, buffer) == 0,
225             "got driver '%s' (expected '%s')\n", driver, buffer);
226         }
227
228     }
229
230     GlobalUnlock(pDlg->hDevNames);
231
232     GlobalFree(pDlg->hDevMode);
233     GlobalFree(pDlg->hDevNames);
234     HeapFree(GetProcessHeap(), 0, pDlg);
235
236 }
237
238 /* ########################### */
239
240 static void test_PrintDlgExW(void)
241 {
242     LPPRINTDLGEXW pDlg;
243     HRESULT res;
244
245     /* Set CommDlgExtendedError != 0 */
246     PrintDlg(NULL);
247     SetLastError(0xdeadbeef);
248     res = pPrintDlgExW(NULL);
249     if(res == E_NOTIMPL)
250     {
251         win_skip("PrintDlgExW returns not implemented\n");
252         return;
253     }
254     ok( (res == E_INVALIDARG),
255         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
256         res, GetLastError(), CommDlgExtendedError());
257
258
259     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGEXW)) + 8);
260     if (!pDlg) return;
261
262     /* lStructSize must be exact */
263     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
264     pDlg->lStructSize = sizeof(PRINTDLGEXW) - 1;
265     PrintDlg(NULL);
266     SetLastError(0xdeadbeef);
267     res = pPrintDlgExW(pDlg);
268     ok( (res == E_INVALIDARG),
269         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
270         res, GetLastError(), CommDlgExtendedError());
271
272
273     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
274     pDlg->lStructSize = sizeof(PRINTDLGEXW) + 1;
275     PrintDlg(NULL);
276     SetLastError(0xdeadbeef);
277     res = pPrintDlgExW(pDlg);
278     ok( (res == E_INVALIDARG),
279         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
280         res, GetLastError(), CommDlgExtendedError());
281
282
283     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
284     pDlg->lStructSize = sizeof(PRINTDLGEXW);
285     SetLastError(0xdeadbeef);
286     res = pPrintDlgExW(pDlg);
287     ok( (res == E_HANDLE),
288         "got 0x%x with %u and %u (expected 'E_HANDLE')\n",
289         res, GetLastError(), CommDlgExtendedError());
290
291
292     HeapFree(GetProcessHeap(), 0, pDlg);
293     return;
294
295 }
296
297 static BOOL abort_proc_called = FALSE;
298 static BOOL CALLBACK abort_proc(HDC hdc, int error) { return abort_proc_called = TRUE; }
299 static void test_abort_proc(void)
300 {
301     HDC print_dc;
302     RECT rect = {0, 0, 100, 100};
303     DOCINFOA doc_info = {0};
304     PRINTDLGA pd = {0};
305     char filename[MAX_PATH];
306     int job_id;
307
308     if (!GetTempFileNameA(".", "prn", 0, filename))
309     {
310         skip("Failed to create a temporary file name\n");
311         return;
312     }
313
314     pd.lStructSize = sizeof(pd);
315     pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
316     pd.nFromPage = 1;
317     pd.nToPage = 1;
318     pd.nCopies = 1;
319
320     if (!PrintDlgA(&pd))
321     {
322         skip("No default printer available.\n");
323         ok(DeleteFileA(filename), "Failed to delete temporary file\n");
324         return;
325     }
326     GlobalFree(pd.hDevMode);
327     GlobalFree(pd.hDevNames);
328
329     ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
330     if (!(print_dc = pd.hDC))
331     {
332         ok(DeleteFileA(filename), "Failed to delete temporary file\n");
333         return;
334     }
335
336     ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n");
337     ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n");
338     abort_proc_called = FALSE;
339
340     doc_info.cbSize = sizeof(doc_info);
341     doc_info.lpszDocName = "Some document";
342     doc_info.lpszOutput = filename;
343
344     job_id = StartDocA(print_dc, &doc_info);
345
346     ok(job_id > 0 ||
347        GetLastError() == ERROR_SPL_NO_STARTDOC, /* Vista can fail with this error when using the XPS driver */
348        "StartDocA failed ret %d gle %d\n", job_id, GetLastError());
349
350     if(job_id <= 0)
351     {
352         skip("StartDoc failed\n");
353         goto end;
354     }
355
356     /* StartDoc may or may not call abort proc */
357
358     abort_proc_called = FALSE;
359     ok(StartPage(print_dc) > 0, "StartPage failed\n");
360     ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
361     abort_proc_called = FALSE;
362
363     /* following functions sometimes call abort proc too */
364     ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
365     ok(EndPage(print_dc) > 0, "EndPage failed\n");
366     ok(EndDoc(print_dc) > 0, "EndDoc failed\n");
367
368     abort_proc_called = FALSE;
369     ok(DeleteDC(print_dc), "DeleteDC failed\n");
370     ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
371     abort_proc_called = FALSE;
372
373 end:
374     ok(DeleteFileA(filename), "Failed to delete temporary file\n");
375 }
376
377 /* ########################### */
378
379 START_TEST(printdlg)
380 {
381     LPCSTR  ptr;
382
383     ptr = load_functions();
384
385     test_PageSetupDlgA();
386     test_PrintDlgA();
387     test_abort_proc();
388
389     /* PrintDlgEx not present before w2k */
390     if (ptr) {
391         win_skip("%s\n", ptr);
392         return;
393     }
394
395     test_PrintDlgExW();
396 }