comdlg32: Add support for customizing control labels in the item dialog.
[wine] / dlls / comdlg32 / tests / itemdlg.c
1 /*
2  * Unit tests for the Common Item Dialog
3  *
4  * Copyright 2010,2011 David Hedberg
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 "shlobj.h"
26 #include "wine/test.h"
27
28 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
29 static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
30
31 static void init_function_pointers(void)
32 {
33     HMODULE hmod = GetModuleHandleA("shell32.dll");
34
35 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hmod, #f))
36     MAKEFUNC(SHCreateShellItem);
37     MAKEFUNC(SHGetIDListFromObject);
38 #undef MAKEFUNC
39 }
40
41 /**************************************************************************
42  * IFileDialogEvents implementation
43  */
44 typedef struct {
45     IFileDialogEvents IFileDialogEvents_iface;
46     LONG ref;
47 } IFileDialogEventsImpl;
48
49 static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface)
50 {
51     return CONTAINING_RECORD(iface, IFileDialogEventsImpl, IFileDialogEvents_iface);
52 }
53
54 static HRESULT WINAPI IFileDialogEvents_fnQueryInterface(IFileDialogEvents *iface, REFIID riid, void **ppv)
55 {
56     /* Not called. */
57     ok(0, "Unexpectedly called.\n");
58     return E_NOINTERFACE;
59 }
60
61 static ULONG WINAPI IFileDialogEvents_fnAddRef(IFileDialogEvents *iface)
62 {
63     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
64     return InterlockedIncrement(&This->ref);
65 }
66
67 static ULONG WINAPI IFileDialogEvents_fnRelease(IFileDialogEvents *iface)
68 {
69     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
70     LONG ref = InterlockedDecrement(&This->ref);
71
72     if(!ref)
73         HeapFree(GetProcessHeap(), 0, This);
74
75     return ref;
76 }
77
78 static HRESULT WINAPI IFileDialogEvents_fnOnFileOk(IFileDialogEvents *iface, IFileDialog *pfd)
79 {
80     ok(0, "Unexpectedly called.\n");
81     return S_OK;
82 }
83
84 static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *iface,
85                                                            IFileDialog *pfd,
86                                                            IShellItem *psiFolder)
87 {
88     ok(0, "Unexpectedly called.\n");
89     return S_OK;
90 }
91
92 static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd)
93 {
94     ok(0, "Unexpectedly called.\n");
95     return S_OK;
96 }
97
98 static HRESULT WINAPI IFileDialogEvents_fnOnSelectionChange(IFileDialogEvents *iface, IFileDialog *pfd)
99 {
100     ok(0, "Unexpectedly called.\n");
101     return S_OK;
102 }
103
104 static HRESULT WINAPI IFileDialogEvents_fnOnShareViolation(IFileDialogEvents *iface,
105                                                            IFileDialog *pfd,
106                                                            IShellItem *psi,
107                                                            FDE_SHAREVIOLATION_RESPONSE *pResponse)
108 {
109     ok(0, "Unexpectedly called.\n");
110     return S_OK;
111 }
112
113 static HRESULT WINAPI IFileDialogEvents_fnOnTypeChange(IFileDialogEvents *iface, IFileDialog *pfd)
114 {
115     ok(0, "Unexpectedly called.\n");
116     return S_OK;
117 }
118
119 static HRESULT WINAPI IFileDialogEvents_fnOnOverwrite(IFileDialogEvents *iface,
120                                                       IFileDialog *pfd,
121                                                       IShellItem *psi,
122                                                       FDE_OVERWRITE_RESPONSE *pResponse)
123 {
124     ok(0, "Unexpectedly called.\n");
125     return S_OK;
126 }
127
128 static const IFileDialogEventsVtbl vt_IFileDialogEvents = {
129     IFileDialogEvents_fnQueryInterface,
130     IFileDialogEvents_fnAddRef,
131     IFileDialogEvents_fnRelease,
132     IFileDialogEvents_fnOnFileOk,
133     IFileDialogEvents_fnOnFolderChanging,
134     IFileDialogEvents_fnOnFolderChange,
135     IFileDialogEvents_fnOnSelectionChange,
136     IFileDialogEvents_fnOnShareViolation,
137     IFileDialogEvents_fnOnTypeChange,
138     IFileDialogEvents_fnOnOverwrite
139 };
140
141 static IFileDialogEvents *IFileDialogEvents_Constructor(void)
142 {
143     IFileDialogEventsImpl *This;
144
145     This = HeapAlloc(GetProcessHeap(), 0, sizeof(IFileDialogEventsImpl));
146     This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents;
147     This->ref = 1;
148
149     return &This->IFileDialogEvents_iface;
150 }
151
152 static BOOL test_instantiation(void)
153 {
154     IFileDialog *pfd;
155     IFileOpenDialog *pfod;
156     IFileSaveDialog *pfsd;
157     IServiceProvider *psp;
158     IUnknown *punk;
159     HRESULT hr;
160
161     /* Instantiate FileOpenDialog */
162     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
163                           &IID_IFileOpenDialog, (void**)&pfod);
164     if(FAILED(hr))
165     {
166         skip("Could not instantiate the FileOpenDialog.\n");
167         return FALSE;
168     }
169     ok(hr == S_OK, "got 0x%08x.\n", hr);
170
171     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialog, (void**)&pfd);
172     ok(hr == S_OK, "got 0x%08x.\n", hr);
173     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
174
175     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfd);
176     todo_wine ok(hr == S_OK, "got 0x%08x.\n", hr);
177     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
178
179     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileSaveDialog, (void**)&pfsd);
180     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
181     if(SUCCEEDED(hr)) IFileOpenDialog_Release(pfsd);
182
183     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IServiceProvider, (void**)&psp);
184     ok(hr == S_OK, "got 0x%08x.\n", hr);
185     if(SUCCEEDED(hr))
186     {
187         IExplorerBrowser *peb;
188         IShellBrowser *psb;
189
190         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_IExplorerBrowser, (void**)&peb);
191         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
192         if(SUCCEEDED(hr)) IExplorerBrowser_Release(peb);
193         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&psb);
194         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
195         if(SUCCEEDED(hr)) IShellBrowser_Release(psb);
196         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_ICommDlgBrowser, (void**)&punk);
197         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
198         if(SUCCEEDED(hr)) IUnknown_Release(punk);
199         hr = IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser, (void**)&punk);
200         ok(hr == S_OK, "got 0x%08x.\n", hr);
201         if(SUCCEEDED(hr)) IUnknown_Release(punk);
202
203         IServiceProvider_Release(psp);
204     }
205
206     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogEvents, (void**)&pfd);
207     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
208     if(SUCCEEDED(hr)) IFileDialogEvents_Release(pfd);
209
210     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IExplorerBrowser, (void**)&punk);
211     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
212     if(SUCCEEDED(hr)) IUnknown_Release(punk);
213
214     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IExplorerBrowserEvents, (void**)&punk);
215     ok(hr == S_OK, "got 0x%08x.\n", hr);
216     if(SUCCEEDED(hr)) IUnknown_Release(punk);
217
218     hr = IFileOpenDialog_QueryInterface(pfod, &IID_ICommDlgBrowser3, (void**)&punk);
219     ok(hr == S_OK, "got 0x%08x.\n", hr);
220     if(SUCCEEDED(hr)) IUnknown_Release(punk);
221
222     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IShellBrowser, (void**)&punk);
223     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
224     if(SUCCEEDED(hr)) IUnknown_Release(punk);
225
226     IFileOpenDialog_Release(pfod);
227
228     /* Instantiate FileSaveDialog */
229     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
230                           &IID_IFileSaveDialog, (void**)&pfsd);
231     if(FAILED(hr))
232     {
233         skip("Could not instantiate the FileSaveDialog.\n");
234         return FALSE;
235     }
236     ok(hr == S_OK, "got 0x%08x.\n", hr);
237
238     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialog, (void**)&pfd);
239     ok(hr == S_OK, "got 0x%08x.\n", hr);
240     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
241
242     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialogCustomize, (void**)&pfd);
243     todo_wine ok(hr == S_OK, "got 0x%08x.\n", hr);
244     if(SUCCEEDED(hr)) IFileDialogCustomize_Release(pfd);
245
246     hr = IFileOpenDialog_QueryInterface(pfsd, &IID_IFileOpenDialog, (void**)&pfod);
247     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
248     if(SUCCEEDED(hr)) IFileOpenDialog_Release(pfod);
249
250     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialogEvents, (void**)&pfd);
251     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
252     if(SUCCEEDED(hr)) IFileDialogEvents_Release(pfd);
253
254     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IExplorerBrowser, (void**)&punk);
255     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
256     if(SUCCEEDED(hr)) IUnknown_Release(punk);
257
258     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IExplorerBrowserEvents, (void**)&punk);
259     ok(hr == S_OK, "got 0x%08x.\n", hr);
260     if(SUCCEEDED(hr)) IUnknown_Release(punk);
261
262     hr = IFileOpenDialog_QueryInterface(pfsd, &IID_ICommDlgBrowser3, (void**)&punk);
263     ok(hr == S_OK, "got 0x%08x.\n", hr);
264     if(SUCCEEDED(hr)) IUnknown_Release(punk);
265
266     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IShellBrowser, (void**)&punk);
267     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
268     if(SUCCEEDED(hr)) IUnknown_Release(punk);
269
270     IFileSaveDialog_Release(pfsd);
271     return TRUE;
272 }
273
274 static void test_basics(void)
275 {
276     IFileOpenDialog *pfod;
277     IFileSaveDialog *pfsd;
278     IFileDialog2 *pfd2;
279     FILEOPENDIALOGOPTIONS fdoptions;
280     IShellFolder *psfdesktop;
281     IShellItem *psi, *psidesktop, *psi_original;
282     IShellItemArray *psia;
283     IPropertyStore *pps;
284     LPITEMIDLIST pidl;
285     WCHAR *filename;
286     UINT filetype;
287     HRESULT hr;
288     const WCHAR txt[] = {'t','x','t', 0};
289     const WCHAR null[] = {0};
290     const WCHAR fname1[] = {'f','n','a','m','e','1', 0};
291     const WCHAR fspec1[] = {'*','.','t','x','t',0};
292     const WCHAR fname2[] = {'f','n','a','m','e','2', 0};
293     const WCHAR fspec2[] = {'*','.','e','x','e',0};
294     COMDLG_FILTERSPEC filterspec[2] = {{fname1, fspec1}, {fname2, fspec2}};
295
296     /* This should work on every platform with IFileDialog */
297     SHGetDesktopFolder(&psfdesktop);
298     hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl);
299     if(SUCCEEDED(hr))
300     {
301         hr = pSHCreateShellItem(NULL, NULL, pidl, &psidesktop);
302         ILFree(pidl);
303     }
304     IShellFolder_Release(psfdesktop);
305     if(FAILED(hr))
306     {
307         skip("Failed to get ShellItem from DesktopFolder, skipping tests.\n");
308         return;
309     }
310
311
312     /* Instantiate FileOpenDialog and FileSaveDialog */
313     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
314                           &IID_IFileOpenDialog, (void**)&pfod);
315     ok(hr == S_OK, "got 0x%08x.\n", hr);
316     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
317                           &IID_IFileSaveDialog, (void**)&pfsd);
318     ok(hr == S_OK, "got 0x%08x.\n", hr);
319
320     /* ClearClientData */
321     todo_wine
322     {
323     hr = IFileOpenDialog_ClearClientData(pfod);
324     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
325     hr = IFileSaveDialog_ClearClientData(pfsd);
326     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
327     }
328
329     /* GetOptions */
330     hr = IFileOpenDialog_GetOptions(pfod, NULL);
331     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
332     hr = IFileSaveDialog_GetOptions(pfsd, NULL);
333     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
334
335     /* Check default options */
336     hr = IFileOpenDialog_GetOptions(pfod, &fdoptions);
337     ok(hr == S_OK, "got 0x%08x.\n", hr);
338     ok(fdoptions == (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR),
339        "Unexpected default options: 0x%08x\n", fdoptions);
340     hr = IFileSaveDialog_GetOptions(pfsd, &fdoptions);
341     ok(hr == S_OK, "got 0x%08x.\n", hr);
342     ok(fdoptions == (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR),
343        "Unexpected default options: 0x%08x\n", fdoptions);
344
345     /* GetResult */
346     hr = IFileOpenDialog_GetResult(pfod, NULL);
347     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
348     hr = IFileSaveDialog_GetResult(pfsd, NULL);
349     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
350
351     psi = (void*)0xdeadbeef;
352     hr = IFileOpenDialog_GetResult(pfod, &psi);
353     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
354     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
355     psi = (void*)0xdeadbeef;
356     hr = IFileSaveDialog_GetResult(pfsd, &psi);
357     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
358     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
359
360     /* GetCurrentSelection */
361     if(0) {
362         /* Crashes on Vista/W2K8. Tests below passes on Windows 7 */
363         hr = IFileOpenDialog_GetCurrentSelection(pfod, NULL);
364         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
365         hr = IFileSaveDialog_GetCurrentSelection(pfsd, NULL);
366         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
367         hr = IFileOpenDialog_GetCurrentSelection(pfod, &psi);
368         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
369         hr = IFileSaveDialog_GetCurrentSelection(pfsd, &psi);
370         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
371     }
372
373     /* GetFileName */
374     hr = IFileOpenDialog_GetFileName(pfod, NULL);
375     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
376     filename = (void*)0xdeadbeef;
377     hr = IFileOpenDialog_GetFileName(pfod, &filename);
378     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
379     ok(filename == NULL, "got %p\n", filename);
380     hr = IFileSaveDialog_GetFileName(pfsd, NULL);
381     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
382     filename = (void*)0xdeadbeef;
383     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
384     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
385     ok(filename == NULL, "got %p\n", filename);
386
387     /* GetFileTypeIndex */
388     hr = IFileOpenDialog_GetFileTypeIndex(pfod, NULL);
389     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
390     filetype = 0x12345;
391     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
392     ok(hr == S_OK, "got 0x%08x.\n", hr);
393     ok(filetype == 0, "got %d.\n", filetype);
394     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, NULL);
395     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
396     filetype = 0x12345;
397     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
398     ok(hr == S_OK, "got 0x%08x.\n", hr);
399     ok(filetype == 0, "got %d.\n", filetype);
400
401     /* SetFileTypes / SetFileTypeIndex */
402     hr = IFileOpenDialog_SetFileTypes(pfod, 0, NULL);
403     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
404     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
405     ok(hr == S_OK, "got 0x%08x.\n", hr);
406
407     hr = IFileOpenDialog_SetFileTypeIndex(pfod, -1);
408     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
409     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
410     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
411     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 1);
412     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
413     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
414     ok(hr == S_OK, "got 0x%08x.\n", hr);
415     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
416     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
417     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
418     ok(hr == S_OK, "got 0x%08x.\n", hr);
419     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 100);
420     ok(hr == S_OK, "got 0x%08x.\n", hr);
421     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
422     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
423     hr = IFileOpenDialog_SetFileTypes(pfod, 1, &filterspec[1]);
424     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
425
426     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, -1);
427     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
428     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
429     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
430     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 1);
431     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
432     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, filterspec);
433     ok(hr == S_OK, "got 0x%08x.\n", hr);
434     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
435     ok(hr == S_OK, "got 0x%08x.\n", hr);
436     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 100);
437     ok(hr == S_OK, "got 0x%08x.\n", hr);
438     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, filterspec);
439     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
440     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, &filterspec[1]);
441     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
442
443     /* SetFilter */
444     todo_wine
445     {
446     hr = IFileOpenDialog_SetFilter(pfod, NULL);
447     ok(hr == S_OK, "got 0x%08x.\n", hr);
448     hr = IFileSaveDialog_SetFilter(pfsd, NULL);
449     ok(hr == S_OK, "got 0x%08x.\n", hr);
450     }
451
452     /* SetFolder */
453     hr = IFileOpenDialog_SetFolder(pfod, NULL);
454     ok(hr == S_OK, "got 0x%08x.\n", hr);
455     hr = IFileSaveDialog_SetFolder(pfsd, NULL);
456     ok(hr == S_OK, "got 0x%08x.\n", hr);
457
458     /* SetDefaultExtension */
459     todo_wine
460     {
461     hr = IFileOpenDialog_SetDefaultExtension(pfod, NULL);
462     ok(hr == S_OK, "got 0x%08x.\n", hr);
463     hr = IFileOpenDialog_SetDefaultExtension(pfod, txt);
464     ok(hr == S_OK, "got 0x%08x.\n", hr);
465     hr = IFileOpenDialog_SetDefaultExtension(pfod, null);
466     ok(hr == S_OK, "got 0x%08x.\n", hr);
467
468     hr = IFileSaveDialog_SetDefaultExtension(pfsd, NULL);
469     ok(hr == S_OK, "got 0x%08x.\n", hr);
470     hr = IFileSaveDialog_SetDefaultExtension(pfsd, txt);
471     ok(hr == S_OK, "got 0x%08x.\n", hr);
472     hr = IFileSaveDialog_SetDefaultExtension(pfsd, null);
473     ok(hr == S_OK, "got 0x%08x.\n", hr);
474     }
475
476     /* SetDefaultFolder */
477     hr = IFileOpenDialog_SetDefaultFolder(pfod, NULL);
478     ok(hr == S_OK, "got 0x%08x\n", hr);
479     hr = IFileSaveDialog_SetDefaultFolder(pfsd, NULL);
480     ok(hr == S_OK, "got 0x%08x\n", hr);
481
482     hr = IFileOpenDialog_SetDefaultFolder(pfod, psidesktop);
483     ok(hr == S_OK, "got 0x%08x\n", hr);
484     hr = IFileSaveDialog_SetDefaultFolder(pfsd, psidesktop);
485     ok(hr == S_OK, "got 0x%08x\n", hr);
486
487     if(0)
488     {
489         /* Crashes under Windows 7 */
490         IFileOpenDialog_SetDefaultFolder(pfod, (void*)0x1234);
491         IFileSaveDialog_SetDefaultFolder(pfsd, (void*)0x1234);
492     }
493
494     /* GetFolder / SetFolder */
495     hr = IFileOpenDialog_GetFolder(pfod, NULL);
496     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
497
498     hr = IFileOpenDialog_GetFolder(pfod, &psi_original);
499     ok(hr == S_OK, "got 0x%08x.\n", hr);
500     if(SUCCEEDED(hr))
501     {
502         hr = IFileOpenDialog_SetFolder(pfod, psidesktop);
503         ok(hr == S_OK, "got 0x%08x.\n", hr);
504         hr = IFileOpenDialog_SetFolder(pfod, psi_original);
505         ok(hr == S_OK, "got 0x%08x.\n", hr);
506         IShellItem_Release(psi_original);
507     }
508
509     hr = IFileSaveDialog_GetFolder(pfsd, &psi_original);
510     ok(hr == S_OK, "got 0x%08x.\n", hr);
511     if(SUCCEEDED(hr))
512     {
513         hr = IFileSaveDialog_SetFolder(pfsd, psidesktop);
514         ok(hr == S_OK, "got 0x%08x.\n", hr);
515         hr = IFileSaveDialog_SetFolder(pfsd, psi_original);
516         ok(hr == S_OK, "got 0x%08x.\n", hr);
517         IShellItem_Release(psi_original);
518     }
519
520     /* AddPlace */
521     if(0)
522     {
523         /* Crashes under Windows 7 */
524         IFileOpenDialog_AddPlace(pfod, NULL, 0);
525         IFileSaveDialog_AddPlace(pfsd, NULL, 0);
526     }
527
528     todo_wine
529     {
530     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP + 1);
531     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
532     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_BOTTOM);
533     ok(hr == S_OK, "got 0x%08x\n", hr);
534     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP);
535     ok(hr == S_OK, "got 0x%08x\n", hr);
536
537     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP + 1);
538     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
539     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_BOTTOM);
540     ok(hr == S_OK, "got 0x%08x\n", hr);
541     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP);
542     ok(hr == S_OK, "got 0x%08x\n", hr);
543     }
544
545     /* SetFileName */
546     hr = IFileOpenDialog_SetFileName(pfod, NULL);
547     ok(hr == S_OK, "got 0x%08x\n", hr);
548     hr = IFileOpenDialog_SetFileName(pfod, null);
549     ok(hr == S_OK, "got 0x%08x\n", hr);
550     hr = IFileOpenDialog_SetFileName(pfod, txt);
551     ok(hr == S_OK, "got 0x%08x\n", hr);
552     hr = IFileOpenDialog_GetFileName(pfod, &filename);
553     ok(hr == S_OK, "Got 0x%08x\n", hr);
554     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
555     CoTaskMemFree(filename);
556
557     hr = IFileSaveDialog_SetFileName(pfsd, NULL);
558     ok(hr == S_OK, "got 0x%08x\n", hr);
559     hr = IFileSaveDialog_SetFileName(pfsd, null);
560     ok(hr == S_OK, "got 0x%08x\n", hr);
561     hr = IFileSaveDialog_SetFileName(pfsd, txt);
562     ok(hr == S_OK, "got 0x%08x\n", hr);
563     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
564     ok(hr == S_OK, "Got 0x%08x\n", hr);
565     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
566     CoTaskMemFree(filename);
567
568     /* SetFileNameLabel */
569     hr = IFileOpenDialog_SetFileNameLabel(pfod, NULL);
570     ok(hr == S_OK, "got 0x%08x\n", hr);
571     hr = IFileOpenDialog_SetFileNameLabel(pfod, null);
572     ok(hr == S_OK, "got 0x%08x\n", hr);
573     hr = IFileOpenDialog_SetFileNameLabel(pfod, txt);
574     ok(hr == S_OK, "got 0x%08x\n", hr);
575
576     hr = IFileSaveDialog_SetFileNameLabel(pfsd, NULL);
577     ok(hr == S_OK, "got 0x%08x\n", hr);
578     hr = IFileSaveDialog_SetFileNameLabel(pfsd, null);
579     ok(hr == S_OK, "got 0x%08x\n", hr);
580     hr = IFileSaveDialog_SetFileNameLabel(pfsd, txt);
581     ok(hr == S_OK, "got 0x%08x\n", hr);
582
583     /* Close */
584     hr = IFileOpenDialog_Close(pfod, S_FALSE);
585     ok(hr == S_OK, "got 0x%08x\n", hr);
586     hr = IFileSaveDialog_Close(pfsd, S_FALSE);
587     ok(hr == S_OK, "got 0x%08x\n", hr);
588
589     /* SetOkButtonLabel */
590     hr = IFileOpenDialog_SetOkButtonLabel(pfod, NULL);
591     ok(hr == S_OK, "got 0x%08x\n", hr);
592     hr = IFileOpenDialog_SetOkButtonLabel(pfod, null);
593     ok(hr == S_OK, "got 0x%08x\n", hr);
594     hr = IFileOpenDialog_SetOkButtonLabel(pfod, txt);
595     ok(hr == S_OK, "got 0x%08x\n", hr);
596     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, NULL);
597     ok(hr == S_OK, "got 0x%08x\n", hr);
598     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, null);
599     ok(hr == S_OK, "got 0x%08x\n", hr);
600     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, txt);
601     ok(hr == S_OK, "got 0x%08x\n", hr);
602
603     /* SetTitle */
604     hr = IFileOpenDialog_SetTitle(pfod, NULL);
605     ok(hr == S_OK, "got 0x%08x\n", hr);
606     hr = IFileOpenDialog_SetTitle(pfod, null);
607     ok(hr == S_OK, "got 0x%08x\n", hr);
608     hr = IFileOpenDialog_SetTitle(pfod, txt);
609     ok(hr == S_OK, "got 0x%08x\n", hr);
610     hr = IFileSaveDialog_SetTitle(pfsd, NULL);
611     ok(hr == S_OK, "got 0x%08x\n", hr);
612     hr = IFileSaveDialog_SetTitle(pfsd, null);
613     ok(hr == S_OK, "got 0x%08x\n", hr);
614     hr = IFileSaveDialog_SetTitle(pfsd, txt);
615     ok(hr == S_OK, "got 0x%08x\n", hr);
616
617     /** IFileOpenDialog specific **/
618
619     /* GetResults */
620     if(0)
621     {
622         /* Crashes under Windows 7 */
623         IFileOpenDialog_GetResults(pfod, NULL);
624     }
625     psia = (void*)0xdeadbeef;
626     hr = IFileOpenDialog_GetResults(pfod, &psia);
627     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
628     ok(psia == NULL, "got %p.\n", psia);
629
630     /* GetSelectedItems */
631     if(0)
632     {
633         /* Crashes under W2K8 */
634         hr = IFileOpenDialog_GetSelectedItems(pfod, NULL);
635         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
636         psia = (void*)0xdeadbeef;
637         hr = IFileOpenDialog_GetSelectedItems(pfod, &psia);
638         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
639         ok(psia == (void*)0xdeadbeef, "got %p.\n", psia);
640     }
641
642     /** IFileSaveDialog specific **/
643
644     /* ApplyProperties */
645     if(0)
646     {
647         /* Crashes under windows 7 */
648         IFileSaveDialog_ApplyProperties(pfsd, NULL, NULL, NULL, NULL);
649         IFileSaveDialog_ApplyProperties(pfsd, psidesktop, NULL, NULL, NULL);
650     }
651
652     /* GetProperties */
653     hr = IFileSaveDialog_GetProperties(pfsd, NULL);
654     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
655     pps = (void*)0xdeadbeef;
656     hr = IFileSaveDialog_GetProperties(pfsd, &pps);
657     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
658     ok(pps == (void*)0xdeadbeef, "got %p\n", pps);
659
660     /* SetProperties */
661     if(0)
662     {
663         /* Crashes under W2K8 */
664         hr = IFileSaveDialog_SetProperties(pfsd, NULL);
665         ok(hr == S_OK, "got 0x%08x\n", hr);
666     }
667
668     /* SetCollectedProperties */
669     todo_wine
670     {
671     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, TRUE);
672     ok(hr == S_OK, "got 0x%08x\n", hr);
673     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, FALSE);
674     ok(hr == S_OK, "got 0x%08x\n", hr);
675     }
676
677     /* SetSaveAsItem */
678     todo_wine
679     {
680     hr = IFileSaveDialog_SetSaveAsItem(pfsd, NULL);
681     ok(hr == S_OK, "got 0x%08x\n", hr);
682     hr = IFileSaveDialog_SetSaveAsItem(pfsd, psidesktop);
683     ok(hr == MK_E_NOOBJECT, "got 0x%08x\n", hr);
684     }
685
686     /** IFileDialog2 **/
687
688     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialog2, (void**)&pfd2);
689     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
690     if(SUCCEEDED(hr))
691     {
692         /* SetCancelButtonLabel */
693         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
694         ok(hr == S_OK, "got 0x%08x\n", hr);
695         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
696         ok(hr == S_OK, "got 0x%08x\n", hr);
697         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
698         ok(hr == S_OK, "got 0x%08x\n", hr);
699
700         /* SetNavigationRoot */
701         todo_wine
702         {
703         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
704         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
705         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
706         ok(hr == S_OK, "got 0x%08x\n", hr);
707         }
708
709         IFileDialog2_Release(pfd2);
710     }
711
712     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialog2, (void**)&pfd2);
713     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
714     if(SUCCEEDED(hr))
715     {
716         /* SetCancelButtonLabel */
717         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
718         ok(hr == S_OK, "got 0x%08x\n", hr);
719         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
720         ok(hr == S_OK, "got 0x%08x\n", hr);
721         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
722         ok(hr == S_OK, "got 0x%08x\n", hr);
723
724         /* SetNavigationRoot */
725         todo_wine
726         {
727         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
728         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
729         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
730         ok(hr == S_OK, "got 0x%08x\n", hr);
731         }
732
733         IFileDialog2_Release(pfd2);
734     }
735
736     /* Cleanup */
737     IShellItem_Release(psidesktop);
738     IFileOpenDialog_Release(pfod);
739     IFileSaveDialog_Release(pfsd);
740 }
741
742 static void test_advise_helper(IFileDialog *pfd)
743 {
744     IFileDialogEventsImpl *pfdeimpl;
745     IFileDialogEvents *pfde;
746     DWORD cookie[10];
747     UINT i;
748     HRESULT hr;
749
750     pfde = IFileDialogEvents_Constructor();
751     pfdeimpl = impl_from_IFileDialogEvents(pfde);
752
753     hr = IFileDialog_Advise(pfd, NULL, NULL);
754     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
755     hr = IFileDialog_Advise(pfd, pfde, NULL);
756     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
757     hr = IFileDialog_Advise(pfd, NULL, &cookie[0]);
758     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
759     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
760
761     hr = IFileDialog_Unadvise(pfd, 0);
762     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
763     for(i = 0; i < 10; i++) {
764         hr = IFileDialog_Advise(pfd, pfde, &cookie[i]);
765         ok(hr == S_OK, "got 0x%08x\n", hr);
766         ok(cookie[i] == i+1, "Got cookie: %d\n", cookie[i]);
767     }
768     ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
769
770     for(i = 3; i < 7; i++) {
771         hr = IFileDialog_Unadvise(pfd, cookie[i]);
772         ok(hr == S_OK, "got 0x%08x\n", hr);
773     }
774     ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref);
775
776     for(i = 0; i < 3; i++) {
777         hr = IFileDialog_Unadvise(pfd, cookie[i]);
778         ok(hr == S_OK, "got 0x%08x\n", hr);
779     }
780     ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref);
781
782     for(i = 7; i < 10; i++) {
783         hr = IFileDialog_Unadvise(pfd, cookie[i]);
784         ok(hr == S_OK, "got 0x%08x\n", hr);
785     }
786     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
787
788     hr = IFileDialog_Unadvise(pfd, cookie[9]+1);
789     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
790     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
791
792     hr = IFileDialog_Advise(pfd, pfde, &cookie[0]);
793     ok(hr == S_OK, "got 0x%08x\n", hr);
794     todo_wine ok(cookie[0] == 1, "got cookie: %d\n", cookie[0]);
795     ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref);
796
797     hr = IFileDialog_Unadvise(pfd, cookie[0]);
798
799     if(0)
800     {
801         /* Unadvising already unadvised cookies crashes on
802            Windows 7. */
803         IFileDialog_Unadvise(pfd, cookie[0]);
804     }
805
806
807     IFileDialogEvents_Release(pfde);
808 }
809
810 static void test_advise(void)
811 {
812     IFileDialog *pfd;
813     HRESULT hr;
814
815     trace("Testing FileOpenDialog (advise)\n");
816     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
817                           &IID_IFileDialog, (void**)&pfd);
818     ok(hr == S_OK, "got 0x%08x.\n", hr);
819     test_advise_helper(pfd);
820     IFileDialog_Release(pfd);
821
822     trace("Testing FileSaveDialog (advise)\n");
823     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
824                           &IID_IFileDialog, (void**)&pfd);
825     ok(hr == S_OK, "got 0x%08x.\n", hr);
826     test_advise_helper(pfd);
827     IFileDialog_Release(pfd);
828 }
829
830 START_TEST(itemdlg)
831 {
832     OleInitialize(NULL);
833     init_function_pointers();
834
835     if(test_instantiation())
836     {
837         test_basics();
838         test_advise();
839     }
840     else
841         skip("Skipping all Item Dialog tests.\n");
842
843     OleUninitialize();
844 }