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 #define IDT_CHANGEFILETYPE 500
29 #define IDT_CLOSEDIALOG    501
30 
31 typedef enum {
32     IFDEVENT_TEST_NONE = 0,
33     IFDEVENT_TEST1     = 0x1,
34     IFDEVENT_TEST2     = 0x2,
35     IFDEVENT_TEST3     = 0x3
36 } FileDialogEventsTest;
37 
38 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
39 static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
40 static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**);
41 
42 static void init_function_pointers(void)
43 {
44     HMODULE hmod = GetModuleHandleA("shell32.dll");
45 
46 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hmod, #f))
47     MAKEFUNC(SHCreateShellItem);
48     MAKEFUNC(SHGetIDListFromObject);
49     MAKEFUNC(SHCreateItemFromParsingName);
50 #undef MAKEFUNC
51 }
52 
53 #include <initguid.h>
54 DEFINE_GUID(IID_IFileDialogCustomizeAlt, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);
55 
56 struct fw_arg {
57     LPCWSTR class, text;
58     HWND hwnd_res;
59 };
60 
61 static BOOL CALLBACK find_window_callback(HWND hwnd, LPARAM lparam)
62 {
63     struct fw_arg *arg = (struct fw_arg*)lparam;
64     WCHAR buf[1024];
65 
66     if(arg->class)
67     {
68         GetClassNameW(hwnd, buf, 1024);
69         if(lstrcmpW(buf, arg->class))
70             return TRUE;
71     }
72 
73     if(arg->text)
74     {
75         GetWindowTextW(hwnd, buf, 1024);
76         if(lstrcmpW(buf, arg->text))
77             return TRUE;
78     }
79 
80     arg->hwnd_res = hwnd;
81     return FALSE;
82 }
83 
84 static HWND find_window(HWND parent, LPCWSTR class, LPCWSTR text)
85 {
86     struct fw_arg arg = {class, text, NULL};
87 
88     EnumChildWindows(parent, find_window_callback, (LPARAM)&arg);
89     return arg.hwnd_res;
90 }
91 
92 static HWND get_hwnd_from_ifiledialog(IFileDialog *pfd)
93 {
94     IOleWindow *pow;
95     HWND dlg_hwnd;
96     HRESULT hr;
97 
98     hr = IFileDialog_QueryInterface(pfd, &IID_IOleWindow, (void**)&pow);
99     ok(hr == S_OK, "Got 0x%08x\n", hr);
100 
101     hr = IOleWindow_GetWindow(pow, &dlg_hwnd);
102     ok(hr == S_OK, "Got 0x%08x\n", hr);
103 
104     IOleWindow_Release(pow);
105 
106     return dlg_hwnd;
107 }
108 
109 static void test_customize_onfolderchange(IFileDialog *pfd);
110 static void filedialog_change_filetype(IFileDialog *pfd, HWND dlg_hwnd);
111 
112 /**************************************************************************
113  * IFileDialogEvents implementation
114  */
115 typedef struct {
116     IFileDialogEvents IFileDialogEvents_iface;
117     LONG ref;
118     LONG QueryInterface;
119     LONG OnFileOk, OnFolderChanging, OnFolderChange;
120     LONG OnSelectionChange, OnShareViolation, OnTypeChange;
121     LONG OnOverwrite;
122     LPCWSTR set_filename;
123     BOOL set_filename_tried;
124     FileDialogEventsTest events_test;
125 } IFileDialogEventsImpl;
126 
127 static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface)
128 {
129     return CONTAINING_RECORD(iface, IFileDialogEventsImpl, IFileDialogEvents_iface);
130 }
131 
132 static HRESULT WINAPI IFileDialogEvents_fnQueryInterface(IFileDialogEvents *iface, REFIID riid, void **ppv)
133 {
134     /* Not called. */
135     ok(0, "Unexpectedly called.\n");
136     return E_NOINTERFACE;
137 }
138 
139 static ULONG WINAPI IFileDialogEvents_fnAddRef(IFileDialogEvents *iface)
140 {
141     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
142     return InterlockedIncrement(&This->ref);
143 }
144 
145 static ULONG WINAPI IFileDialogEvents_fnRelease(IFileDialogEvents *iface)
146 {
147     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
148     LONG ref = InterlockedDecrement(&This->ref);
149 
150     if(!ref)
151         HeapFree(GetProcessHeap(), 0, This);
152 
153     return ref;
154 }
155 
156 static HRESULT WINAPI IFileDialogEvents_fnOnFileOk(IFileDialogEvents *iface, IFileDialog *pfd)
157 {
158     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
159     This->OnFileOk++;
160     return S_OK;
161 }
162 
163 static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *iface,
164                                                            IFileDialog *pfd,
165                                                            IShellItem *psiFolder)
166 {
167     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
168     This->OnFolderChanging++;
169     return S_OK;
170 }
171 
172 static LRESULT CALLBACK test_customize_dlgproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
173 {
174     WNDPROC oldwndproc = GetPropA(hwnd, "WT_OLDWC");
175     IFileDialog *pfd = GetPropA(hwnd, "WT_PFD");
176     BOOL br;
177 
178     switch(message)
179     {
180     case WM_USER+0x1234:
181         test_customize_onfolderchange(pfd);
182         break;
183     case WM_TIMER:
184         switch(wparam)
185         {
186         case IDT_CHANGEFILETYPE:
187             filedialog_change_filetype(pfd, hwnd);
188             KillTimer(hwnd, IDT_CHANGEFILETYPE);
189             SetTimer(hwnd, IDT_CLOSEDIALOG, 100, 0);
190             return TRUE;
191         case IDT_CLOSEDIALOG:
192             /* Calling IFileDialog_Close here does not work */
193             br = PostMessageW(hwnd, WM_COMMAND, IDCANCEL, 0);
194             ok(br, "Failed\n");
195             return TRUE;
196         }
197     }
198 
199     return CallWindowProcW(oldwndproc, hwnd, message, wparam, lparam);
200 }
201 
202 static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd)
203 {
204     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
205     HWND dlg_hwnd;
206     HRESULT hr;
207     BOOL br;
208     This->OnFolderChange++;
209 
210     if(This->set_filename)
211     {
212         dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
213         ok(dlg_hwnd != NULL, "Got NULL.\n");
214 
215         hr = IFileDialog_SetFileName(pfd, This->set_filename);
216         ok(hr == S_OK, "Got 0x%08x\n", hr);
217 
218         if(!This->set_filename_tried)
219         {
220             br = PostMessageW(dlg_hwnd, WM_COMMAND, IDOK, 0);
221             ok(br, "Failed\n");
222             This->set_filename_tried = TRUE;
223         }
224     }
225 
226     if(This->events_test)
227     {
228         WNDPROC oldwndproc;
229 
230         dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
231 
232         /* On Vista, the custom control area of the dialog is not
233          * fully set up when the first OnFolderChange event is
234          * issued. */
235         oldwndproc = (WNDPROC)GetWindowLongPtrW(dlg_hwnd, GWLP_WNDPROC);
236         SetPropA(dlg_hwnd, "WT_OLDWC", (HANDLE)oldwndproc);
237         SetPropA(dlg_hwnd, "WT_PFD", (HANDLE)pfd);
238         SetWindowLongPtrW(dlg_hwnd, GWLP_WNDPROC, (LPARAM)test_customize_dlgproc);
239 
240         switch(This->events_test)
241         {
242         case IFDEVENT_TEST1:
243             br = PostMessageW(dlg_hwnd, WM_USER+0x1234, 0, 0);
244             ok(br, "Failed\n");
245             break;
246         case IFDEVENT_TEST2:
247             SetTimer(dlg_hwnd, IDT_CLOSEDIALOG, 100, 0);
248             break;
249         case IFDEVENT_TEST3:
250             SetTimer(dlg_hwnd, IDT_CHANGEFILETYPE, 100, 0);
251             break;
252         default:
253             ok(FALSE, "Should not happen (%d)\n", This->events_test);
254         }
255     }
256 
257     return S_OK;
258 }
259 
260 static HRESULT WINAPI IFileDialogEvents_fnOnSelectionChange(IFileDialogEvents *iface, IFileDialog *pfd)
261 {
262     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
263     This->OnSelectionChange++;
264     return S_OK;
265 }
266 
267 static HRESULT WINAPI IFileDialogEvents_fnOnShareViolation(IFileDialogEvents *iface,
268                                                            IFileDialog *pfd,
269                                                            IShellItem *psi,
270                                                            FDE_SHAREVIOLATION_RESPONSE *pResponse)
271 {
272     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
273     This->OnShareViolation++;
274     return S_OK;
275 }
276 
277 static HRESULT WINAPI IFileDialogEvents_fnOnTypeChange(IFileDialogEvents *iface, IFileDialog *pfd)
278 {
279     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
280     This->OnTypeChange++;
281     return S_OK;
282 }
283 
284 static HRESULT WINAPI IFileDialogEvents_fnOnOverwrite(IFileDialogEvents *iface,
285                                                       IFileDialog *pfd,
286                                                       IShellItem *psi,
287                                                       FDE_OVERWRITE_RESPONSE *pResponse)
288 {
289     IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
290     This->OnOverwrite++;
291     ok(*pResponse == FDEOR_DEFAULT, "overwrite response %u\n", *pResponse);
292     *pResponse = FDEOR_ACCEPT;
293     ok(!This->OnFileOk, "OnFileOk already called %u times\n", This->OnFileOk);
294     return S_OK;
295 }
296 
297 static const IFileDialogEventsVtbl vt_IFileDialogEvents = {
298     IFileDialogEvents_fnQueryInterface,
299     IFileDialogEvents_fnAddRef,
300     IFileDialogEvents_fnRelease,
301     IFileDialogEvents_fnOnFileOk,
302     IFileDialogEvents_fnOnFolderChanging,
303     IFileDialogEvents_fnOnFolderChange,
304     IFileDialogEvents_fnOnSelectionChange,
305     IFileDialogEvents_fnOnShareViolation,
306     IFileDialogEvents_fnOnTypeChange,
307     IFileDialogEvents_fnOnOverwrite
308 };
309 
310 static IFileDialogEvents *IFileDialogEvents_Constructor(void)
311 {
312     IFileDialogEventsImpl *This;
313 
314     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileDialogEventsImpl));
315     This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents;
316     This->ref = 1;
317 
318     return &This->IFileDialogEvents_iface;
319 }
320 
321 static BOOL test_instantiation(void)
322 {
323     IFileDialog *pfd;
324     IFileOpenDialog *pfod;
325     IFileSaveDialog *pfsd;
326     IServiceProvider *psp;
327     IOleWindow *pow;
328     IUnknown *punk, *unk2;
329     HRESULT hr;
330     LONG ref;
331 
332     /* Instantiate FileOpenDialog */
333     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
334                           &IID_IFileOpenDialog, (void**)&pfod);
335     if(FAILED(hr))
336     {
337         win_skip("Could not instantiate the FileOpenDialog.\n");
338         return FALSE;
339     }
340     ok(hr == S_OK, "got 0x%08x.\n", hr);
341 
342     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialog, (void**)&pfd);
343     ok(hr == S_OK, "got 0x%08x.\n", hr);
344     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
345 
346     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&punk);
347     ok(hr == S_OK, "got 0x%08x.\n", hr);
348 
349     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogCustomizeAlt, (void**)&unk2);
350     ok(hr == S_OK, "got 0x%08x.\n", hr);
351     ok(punk == unk2, "got %p, %p\n", punk, unk2);
352     IUnknown_Release(punk);
353     IUnknown_Release(unk2);
354 
355     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileSaveDialog, (void**)&pfsd);
356     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
357     if(SUCCEEDED(hr)) IFileSaveDialog_Release(pfsd);
358 
359     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IServiceProvider, (void**)&psp);
360     ok(hr == S_OK, "got 0x%08x.\n", hr);
361     if(SUCCEEDED(hr))
362     {
363         IExplorerBrowser *peb;
364         IShellBrowser *psb;
365 
366         hr = IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser, (void**)&punk);
367         ok(hr == S_OK, "got 0x%08x.\n", hr);
368         if(SUCCEEDED(hr)) IUnknown_Release(punk);
369 
370         /* since win8, the result is E_NOTIMPL for all other services */
371         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_IExplorerBrowser, (void**)&peb);
372         ok(hr == E_NOTIMPL || broken(hr == E_FAIL), "got 0x%08x (expected E_NOTIMPL)\n", hr);
373         if(SUCCEEDED(hr)) IExplorerBrowser_Release(peb);
374         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&psb);
375         ok(hr == E_NOTIMPL || broken(hr == E_FAIL), "got 0x%08x (expected E_NOTIMPL)\n", hr);
376         if(SUCCEEDED(hr)) IShellBrowser_Release(psb);
377         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_ICommDlgBrowser, (void**)&punk);
378         ok(hr == E_NOTIMPL || broken(hr == E_FAIL), "got 0x%08x (expected E_NOTIMPL)\n", hr);
379         if(SUCCEEDED(hr)) IUnknown_Release(punk);
380 
381         hr = IServiceProvider_QueryService(psp, &SID_STopLevelBrowser, &IID_IUnknown, (void**)&punk);
382         ok(hr == E_NOTIMPL || broken(hr == E_FAIL), "got 0x%08x (expected E_NOTIMPL)\n", hr);
383         if(SUCCEEDED(hr)) IUnknown_Release(punk);
384         hr = IServiceProvider_QueryService(psp, &IID_IUnknown, &IID_IUnknown, (void**)&punk);
385         ok(hr == E_NOTIMPL || broken(hr == E_FAIL), "got 0x%08x (expected E_NOTIMPL)\n", hr);
386         if(SUCCEEDED(hr)) IUnknown_Release(punk);
387 
388         IServiceProvider_Release(psp);
389     }
390 
391     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogEvents, (void**)&punk);
392     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
393     if(SUCCEEDED(hr)) IUnknown_Release(punk);
394 
395     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IExplorerBrowser, (void**)&punk);
396     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
397     if(SUCCEEDED(hr)) IUnknown_Release(punk);
398 
399     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IExplorerBrowserEvents, (void**)&punk);
400     ok(hr == S_OK, "got 0x%08x.\n", hr);
401     if(SUCCEEDED(hr)) IUnknown_Release(punk);
402 
403     hr = IFileOpenDialog_QueryInterface(pfod, &IID_ICommDlgBrowser3, (void**)&punk);
404     ok(hr == S_OK, "got 0x%08x.\n", hr);
405     if(SUCCEEDED(hr)) IUnknown_Release(punk);
406 
407     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IShellBrowser, (void**)&punk);
408     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
409     if(SUCCEEDED(hr)) IUnknown_Release(punk);
410 
411     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IOleWindow, (void**)&pow);
412     ok(hr == S_OK, "got 0x%08x.\n", hr);
413     if(SUCCEEDED(hr))
414     {
415         HWND hwnd;
416 
417         hr = IOleWindow_ContextSensitiveHelp(pow, TRUE);
418         todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
419 
420         hr = IOleWindow_ContextSensitiveHelp(pow, FALSE);
421         todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
422 
423         if(0)
424         {
425             /* Crashes on win7 */
426             IOleWindow_GetWindow(pow, NULL);
427         }
428 
429         hr = IOleWindow_GetWindow(pow, &hwnd);
430         ok(hr == S_OK, "Got 0x%08x\n", hr);
431         ok(hwnd == NULL, "Got %p\n", hwnd);
432 
433         IOleWindow_Release(pow);
434     }
435 
436     ref = IFileOpenDialog_Release(pfod);
437     ok(!ref, "Got refcount %d, should have been released.\n", ref);
438 
439     /* Instantiate FileSaveDialog */
440     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
441                           &IID_IFileSaveDialog, (void**)&pfsd);
442     if(FAILED(hr))
443     {
444         skip("Could not instantiate the FileSaveDialog.\n");
445         return FALSE;
446     }
447     ok(hr == S_OK, "got 0x%08x.\n", hr);
448 
449     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialog, (void**)&pfd);
450     ok(hr == S_OK, "got 0x%08x.\n", hr);
451     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
452 
453     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialogCustomize, (void**)&punk);
454     ok(hr == S_OK, "got 0x%08x.\n", hr);
455 
456     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialogCustomizeAlt, (void**)&unk2);
457     ok(hr == S_OK, "got 0x%08x.\n", hr);
458     ok(punk == unk2, "got %p, %p\n", punk, unk2);
459     IUnknown_Release(punk);
460     IUnknown_Release(unk2);
461 
462     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileOpenDialog, (void**)&pfod);
463     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
464     if(SUCCEEDED(hr)) IFileOpenDialog_Release(pfod);
465 
466     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialogEvents, (void**)&punk);
467     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
468     if(SUCCEEDED(hr)) IFileDialog_Release(pfd);
469 
470     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IExplorerBrowser, (void**)&punk);
471     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
472     if(SUCCEEDED(hr)) IUnknown_Release(punk);
473 
474     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IExplorerBrowserEvents, (void**)&punk);
475     ok(hr == S_OK, "got 0x%08x.\n", hr);
476     if(SUCCEEDED(hr)) IUnknown_Release(punk);
477 
478     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_ICommDlgBrowser3, (void**)&punk);
479     ok(hr == S_OK, "got 0x%08x.\n", hr);
480     if(SUCCEEDED(hr)) IUnknown_Release(punk);
481 
482     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IShellBrowser, (void**)&punk);
483     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
484     if(SUCCEEDED(hr)) IUnknown_Release(punk);
485 
486     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IOleWindow, (void**)&pow);
487     ok(hr == S_OK, "got 0x%08x.\n", hr);
488     if(SUCCEEDED(hr))
489     {
490         HWND hwnd;
491 
492         hr = IOleWindow_ContextSensitiveHelp(pow, TRUE);
493         todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
494 
495         hr = IOleWindow_ContextSensitiveHelp(pow, FALSE);
496         todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
497 
498         if(0)
499         {
500             /* Crashes on win7 */
501             IOleWindow_GetWindow(pow, NULL);
502         }
503 
504         hr = IOleWindow_GetWindow(pow, &hwnd);
505         ok(hr == S_OK, "Got 0x%08x\n", hr);
506         ok(hwnd == NULL, "Got %p\n", hwnd);
507 
508         IOleWindow_Release(pow);
509     }
510 
511 
512     ref = IFileSaveDialog_Release(pfsd);
513     ok(!ref, "Got refcount %d, should have been released.\n", ref);
514     return TRUE;
515 }
516 
517 static void test_basics(void)
518 {
519     IFileOpenDialog *pfod;
520     IFileSaveDialog *pfsd;
521     IFileDialog2 *pfd2;
522     FILEOPENDIALOGOPTIONS fdoptions;
523     IShellFolder *psfdesktop;
524     IShellItem *psi, *psidesktop, *psi_original;
525     IShellItemArray *psia;
526     IPropertyStore *pps;
527     LPITEMIDLIST pidl;
528     WCHAR *filename;
529     UINT filetype;
530     LONG ref;
531     HRESULT hr;
532     const WCHAR txt[] = {'t','x','t', 0};
533     const WCHAR null[] = {0};
534     const WCHAR fname1[] = {'f','n','a','m','e','1', 0};
535     const WCHAR fspec1[] = {'*','.','t','x','t',0};
536     const WCHAR fname2[] = {'f','n','a','m','e','2', 0};
537     const WCHAR fspec2[] = {'*','.','e','x','e',0};
538     COMDLG_FILTERSPEC filterspec[2] = {{fname1, fspec1}, {fname2, fspec2}};
539     const DWORD invalid_fos[] = {0x1, 0x10, 0x400, 0x80000, 0x400000, 0x800000, 0x1000000, 0x4000000, 0x8000000};
540     INT i;
541 
542     /* This should work on every platform with IFileDialog */
543     SHGetDesktopFolder(&psfdesktop);
544     hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl);
545     if(SUCCEEDED(hr))
546     {
547         hr = pSHCreateShellItem(NULL, NULL, pidl, &psidesktop);
548         ILFree(pidl);
549     }
550     IShellFolder_Release(psfdesktop);
551     if(FAILED(hr))
552     {
553         skip("Failed to get ShellItem from DesktopFolder, skipping tests.\n");
554         return;
555     }
556 
557 
558     /* Instantiate FileOpenDialog and FileSaveDialog */
559     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
560                           &IID_IFileOpenDialog, (void**)&pfod);
561     ok(hr == S_OK, "got 0x%08x.\n", hr);
562     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
563                           &IID_IFileSaveDialog, (void**)&pfsd);
564     ok(hr == S_OK, "got 0x%08x.\n", hr);
565 
566     /* ClearClientData */
567     todo_wine
568     {
569     hr = IFileOpenDialog_ClearClientData(pfod);
570     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
571     hr = IFileSaveDialog_ClearClientData(pfsd);
572     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
573     }
574 
575     /* GetOptions */
576     hr = IFileOpenDialog_GetOptions(pfod, NULL);
577     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
578     hr = IFileSaveDialog_GetOptions(pfsd, NULL);
579     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
580 
581     /* Check default options */
582     hr = IFileOpenDialog_GetOptions(pfod, &fdoptions);
583     ok(hr == S_OK, "got 0x%08x.\n", hr);
584     ok(fdoptions == (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR),
585        "Unexpected default options: 0x%08x\n", fdoptions);
586     hr = IFileSaveDialog_GetOptions(pfsd, &fdoptions);
587     ok(hr == S_OK, "got 0x%08x.\n", hr);
588     ok(fdoptions == (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR),
589        "Unexpected default options: 0x%08x\n", fdoptions);
590 
591     /* Check SetOptions invalid options handling */
592     for (i = 0; i < ARRAY_SIZE(invalid_fos); i++)
593     {
594         hr = IFileOpenDialog_SetOptions(pfod, invalid_fos[i]);
595         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
596         hr = IFileOpenDialog_GetOptions(pfod, &fdoptions);
597         ok(hr == S_OK, "got 0x%08x.\n", hr);
598         ok(fdoptions == (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR), "got %08x\n", fdoptions);
599 
600         hr = IFileSaveDialog_SetOptions(pfsd, invalid_fos[i]);
601         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
602         hr = IFileSaveDialog_GetOptions(pfsd, &fdoptions);
603         ok(hr == S_OK, "got 0x%08x.\n", hr);
604         ok(fdoptions == (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR),
605            "got %08x\n", fdoptions);
606     }
607 
608     /* GetResult */
609     hr = IFileOpenDialog_GetResult(pfod, NULL);
610     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
611     hr = IFileSaveDialog_GetResult(pfsd, NULL);
612     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
613 
614     psi = (void*)0xdeadbeef;
615     hr = IFileOpenDialog_GetResult(pfod, &psi);
616     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
617     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
618     psi = (void*)0xdeadbeef;
619     hr = IFileSaveDialog_GetResult(pfsd, &psi);
620     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
621     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
622 
623     /* GetCurrentSelection */
624     if(0) {
625         /* Crashes on Vista/W2K8. Tests below passes on Windows 7 */
626         hr = IFileOpenDialog_GetCurrentSelection(pfod, NULL);
627         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
628         hr = IFileSaveDialog_GetCurrentSelection(pfsd, NULL);
629         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
630         hr = IFileOpenDialog_GetCurrentSelection(pfod, &psi);
631         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
632         hr = IFileSaveDialog_GetCurrentSelection(pfsd, &psi);
633         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
634     }
635 
636     /* GetFileName */
637     hr = IFileOpenDialog_GetFileName(pfod, NULL);
638     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
639     filename = (void*)0xdeadbeef;
640     hr = IFileOpenDialog_GetFileName(pfod, &filename);
641     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
642     ok(filename == NULL, "got %p\n", filename);
643     hr = IFileSaveDialog_GetFileName(pfsd, NULL);
644     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
645     filename = (void*)0xdeadbeef;
646     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
647     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
648     ok(filename == NULL, "got %p\n", filename);
649 
650     /* GetFileTypeIndex */
651     hr = IFileOpenDialog_GetFileTypeIndex(pfod, NULL);
652     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
653     filetype = 0x12345;
654     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
655     ok(hr == S_OK, "got 0x%08x.\n", hr);
656     ok(filetype == 0, "got %d.\n", filetype);
657     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, NULL);
658     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
659     filetype = 0x12345;
660     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
661     ok(hr == S_OK, "got 0x%08x.\n", hr);
662     ok(filetype == 0, "got %d.\n", filetype);
663 
664     /* SetFileTypes / SetFileTypeIndex */
665     hr = IFileOpenDialog_SetFileTypes(pfod, 0, NULL);
666     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
667     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
668     ok(hr == S_OK, "got 0x%08x.\n", hr);
669 
670     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
671     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
672     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 1);
673     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
674     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
675     ok(hr == S_OK, "got 0x%08x.\n", hr);
676     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
677     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
678     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
679     ok(hr == S_OK, "got 0x%08x.\n", hr);
680     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
681     ok(hr == S_OK, "got 0x%08x.\n", hr);
682     ok(filetype == 1, "got %d\n", filetype);
683     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 100);
684     ok(hr == S_OK, "got 0x%08x.\n", hr);
685     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
686     ok(hr == S_OK, "got 0x%08x.\n", hr);
687     ok(filetype == 1, "got %d\n", filetype);
688     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
689     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
690     hr = IFileOpenDialog_SetFileTypes(pfod, 1, &filterspec[1]);
691     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
692 
693     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
694     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
695     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 1);
696     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
697     hr = IFileSaveDialog_SetFileTypes(pfsd, 2, filterspec);
698     ok(hr == S_OK, "got 0x%08x.\n", hr);
699     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
700     ok(hr == S_OK, "got 0x%08x.\n", hr);
701     /* I hope no one relies on this one */
702     todo_wine ok(filetype == 0, "got %d\n", filetype);
703     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
704     ok(hr == S_OK, "got 0x%08x.\n", hr);
705     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
706     ok(hr == S_OK, "got 0x%08x.\n", hr);
707     ok(filetype == 1, "got %d\n", filetype);
708     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 100);
709     ok(hr == S_OK, "got 0x%08x.\n", hr);
710     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
711     ok(hr == S_OK, "got 0x%08x.\n", hr);
712     ok(filetype == 2, "got %d\n", filetype);
713     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, filterspec);
714     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
715     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, &filterspec[1]);
716     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
717 
718     /* SetFilter */
719     todo_wine
720     {
721     hr = IFileOpenDialog_SetFilter(pfod, NULL);
722     ok(hr == S_OK, "got 0x%08x.\n", hr);
723     hr = IFileSaveDialog_SetFilter(pfsd, NULL);
724     ok(hr == S_OK, "got 0x%08x.\n", hr);
725     }
726 
727     /* SetFolder */
728     hr = IFileOpenDialog_SetFolder(pfod, NULL);
729     ok(hr == S_OK, "got 0x%08x.\n", hr);
730     hr = IFileSaveDialog_SetFolder(pfsd, NULL);
731     ok(hr == S_OK, "got 0x%08x.\n", hr);
732 
733     /* SetDefaultExtension */
734     hr = IFileOpenDialog_SetDefaultExtension(pfod, NULL);
735     ok(hr == S_OK, "got 0x%08x.\n", hr);
736     hr = IFileOpenDialog_SetDefaultExtension(pfod, txt);
737     ok(hr == S_OK, "got 0x%08x.\n", hr);
738     hr = IFileOpenDialog_SetDefaultExtension(pfod, null);
739     ok(hr == S_OK, "got 0x%08x.\n", hr);
740 
741     hr = IFileSaveDialog_SetDefaultExtension(pfsd, NULL);
742     ok(hr == S_OK, "got 0x%08x.\n", hr);
743     hr = IFileSaveDialog_SetDefaultExtension(pfsd, txt);
744     ok(hr == S_OK, "got 0x%08x.\n", hr);
745     hr = IFileSaveDialog_SetDefaultExtension(pfsd, null);
746     ok(hr == S_OK, "got 0x%08x.\n", hr);
747 
748     /* SetDefaultFolder */
749     hr = IFileOpenDialog_SetDefaultFolder(pfod, NULL);
750     ok(hr == S_OK, "got 0x%08x\n", hr);
751     hr = IFileSaveDialog_SetDefaultFolder(pfsd, NULL);
752     ok(hr == S_OK, "got 0x%08x\n", hr);
753 
754     hr = IFileOpenDialog_SetDefaultFolder(pfod, psidesktop);
755     ok(hr == S_OK, "got 0x%08x\n", hr);
756     hr = IFileSaveDialog_SetDefaultFolder(pfsd, psidesktop);
757     ok(hr == S_OK, "got 0x%08x\n", hr);
758 
759     if(0)
760     {
761         /* Crashes under Windows 7 */
762         IFileOpenDialog_SetDefaultFolder(pfod, (void*)0x1234);
763         IFileSaveDialog_SetDefaultFolder(pfsd, (void*)0x1234);
764     }
765 
766     /* GetFolder / SetFolder */
767     hr = IFileOpenDialog_GetFolder(pfod, NULL);
768     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
769 
770     hr = IFileOpenDialog_GetFolder(pfod, &psi_original);
771     ok(hr == S_OK, "got 0x%08x.\n", hr);
772     if(SUCCEEDED(hr))
773     {
774         hr = IFileOpenDialog_SetFolder(pfod, psidesktop);
775         ok(hr == S_OK, "got 0x%08x.\n", hr);
776         hr = IFileOpenDialog_SetFolder(pfod, psi_original);
777         ok(hr == S_OK, "got 0x%08x.\n", hr);
778         IShellItem_Release(psi_original);
779     }
780 
781     hr = IFileSaveDialog_GetFolder(pfsd, &psi_original);
782     ok(hr == S_OK, "got 0x%08x.\n", hr);
783     if(SUCCEEDED(hr))
784     {
785         hr = IFileSaveDialog_SetFolder(pfsd, psidesktop);
786         ok(hr == S_OK, "got 0x%08x.\n", hr);
787         hr = IFileSaveDialog_SetFolder(pfsd, psi_original);
788         ok(hr == S_OK, "got 0x%08x.\n", hr);
789         IShellItem_Release(psi_original);
790     }
791 
792     /* AddPlace */
793     if(0)
794     {
795         /* Crashes under Windows 7 */
796         IFileOpenDialog_AddPlace(pfod, NULL, 0);
797         IFileSaveDialog_AddPlace(pfsd, NULL, 0);
798     }
799 
800     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP + 1);
801     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
802     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_BOTTOM);
803     ok(hr == S_OK, "got 0x%08x\n", hr);
804     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP);
805     ok(hr == S_OK, "got 0x%08x\n", hr);
806 
807     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP + 1);
808     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
809     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_BOTTOM);
810     ok(hr == S_OK, "got 0x%08x\n", hr);
811     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP);
812     ok(hr == S_OK, "got 0x%08x\n", hr);
813 
814     /* SetFileName */
815     hr = IFileOpenDialog_SetFileName(pfod, NULL);
816     ok(hr == S_OK, "got 0x%08x\n", hr);
817     hr = IFileOpenDialog_SetFileName(pfod, null);
818     ok(hr == S_OK, "got 0x%08x\n", hr);
819 
820     filename = NULL;
821     hr = IFileOpenDialog_GetFileName(pfod, &filename);
822     ok(hr == S_OK, "Got 0x%08x\n", hr);
823     ok(!lstrcmpW(filename, null), "Strings do not match.\n");
824     CoTaskMemFree(filename);
825 
826     hr = IFileOpenDialog_SetFileName(pfod, NULL);
827     ok(hr == S_OK, "got 0x%08x\n", hr);
828 
829     filename = (void*)0xdeadbeef;
830     hr = IFileOpenDialog_GetFileName(pfod, &filename);
831     ok(hr == E_FAIL, "Got 0x%08x\n", hr);
832     ok(filename == NULL, "got %p.\n", filename);
833 
834     hr = IFileOpenDialog_SetFileName(pfod, txt);
835     ok(hr == S_OK, "got 0x%08x\n", hr);
836     hr = IFileOpenDialog_GetFileName(pfod, &filename);
837     ok(hr == S_OK, "Got 0x%08x\n", hr);
838     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
839     CoTaskMemFree(filename);
840 
841     hr = IFileSaveDialog_SetFileName(pfsd, NULL);
842     ok(hr == S_OK, "got 0x%08x\n", hr);
843     hr = IFileSaveDialog_SetFileName(pfsd, null);
844     ok(hr == S_OK, "got 0x%08x\n", hr);
845     hr = IFileSaveDialog_SetFileName(pfsd, txt);
846     ok(hr == S_OK, "got 0x%08x\n", hr);
847     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
848     ok(hr == S_OK, "Got 0x%08x\n", hr);
849     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
850     CoTaskMemFree(filename);
851 
852     /* SetFileNameLabel */
853     hr = IFileOpenDialog_SetFileNameLabel(pfod, NULL);
854     ok(hr == S_OK, "got 0x%08x\n", hr);
855     hr = IFileOpenDialog_SetFileNameLabel(pfod, null);
856     ok(hr == S_OK, "got 0x%08x\n", hr);
857     hr = IFileOpenDialog_SetFileNameLabel(pfod, txt);
858     ok(hr == S_OK, "got 0x%08x\n", hr);
859 
860     hr = IFileSaveDialog_SetFileNameLabel(pfsd, NULL);
861     ok(hr == S_OK, "got 0x%08x\n", hr);
862     hr = IFileSaveDialog_SetFileNameLabel(pfsd, null);
863     ok(hr == S_OK, "got 0x%08x\n", hr);
864     hr = IFileSaveDialog_SetFileNameLabel(pfsd, txt);
865     ok(hr == S_OK, "got 0x%08x\n", hr);
866 
867     /* Close */
868     hr = IFileOpenDialog_Close(pfod, S_FALSE);
869     ok(hr == S_OK, "got 0x%08x\n", hr);
870     hr = IFileSaveDialog_Close(pfsd, S_FALSE);
871     ok(hr == S_OK, "got 0x%08x\n", hr);
872 
873     /* SetOkButtonLabel */
874     hr = IFileOpenDialog_SetOkButtonLabel(pfod, NULL);
875     ok(hr == S_OK, "got 0x%08x\n", hr);
876     hr = IFileOpenDialog_SetOkButtonLabel(pfod, null);
877     ok(hr == S_OK, "got 0x%08x\n", hr);
878     hr = IFileOpenDialog_SetOkButtonLabel(pfod, txt);
879     ok(hr == S_OK, "got 0x%08x\n", hr);
880     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, NULL);
881     ok(hr == S_OK, "got 0x%08x\n", hr);
882     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, null);
883     ok(hr == S_OK, "got 0x%08x\n", hr);
884     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, txt);
885     ok(hr == S_OK, "got 0x%08x\n", hr);
886 
887     /* SetTitle */
888     hr = IFileOpenDialog_SetTitle(pfod, NULL);
889     ok(hr == S_OK, "got 0x%08x\n", hr);
890     hr = IFileOpenDialog_SetTitle(pfod, null);
891     ok(hr == S_OK, "got 0x%08x\n", hr);
892     hr = IFileOpenDialog_SetTitle(pfod, txt);
893     ok(hr == S_OK, "got 0x%08x\n", hr);
894     hr = IFileSaveDialog_SetTitle(pfsd, NULL);
895     ok(hr == S_OK, "got 0x%08x\n", hr);
896     hr = IFileSaveDialog_SetTitle(pfsd, null);
897     ok(hr == S_OK, "got 0x%08x\n", hr);
898     hr = IFileSaveDialog_SetTitle(pfsd, txt);
899     ok(hr == S_OK, "got 0x%08x\n", hr);
900 
901     /** IFileOpenDialog specific **/
902 
903     /* GetResults */
904     if(0)
905     {
906         /* Crashes under Windows 7 */
907         IFileOpenDialog_GetResults(pfod, NULL);
908     }
909     psia = (void*)0xdeadbeef;
910     hr = IFileOpenDialog_GetResults(pfod, &psia);
911     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
912     ok(psia == NULL, "got %p.\n", psia);
913 
914     /* GetSelectedItems */
915     if(0)
916     {
917         /* Crashes under W2K8 */
918         hr = IFileOpenDialog_GetSelectedItems(pfod, NULL);
919         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
920         psia = (void*)0xdeadbeef;
921         hr = IFileOpenDialog_GetSelectedItems(pfod, &psia);
922         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
923         ok(psia == (void*)0xdeadbeef, "got %p.\n", psia);
924     }
925 
926     /** IFileSaveDialog specific **/
927 
928     /* ApplyProperties */
929     if(0)
930     {
931         /* Crashes under windows 7 */
932         IFileSaveDialog_ApplyProperties(pfsd, NULL, NULL, NULL, NULL);
933         IFileSaveDialog_ApplyProperties(pfsd, psidesktop, NULL, NULL, NULL);
934     }
935 
936     /* GetProperties */
937     hr = IFileSaveDialog_GetProperties(pfsd, NULL);
938     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
939     pps = (void*)0xdeadbeef;
940     hr = IFileSaveDialog_GetProperties(pfsd, &pps);
941     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
942     ok(pps == (void*)0xdeadbeef, "got %p\n", pps);
943 
944     /* SetProperties */
945     if(0)
946     {
947         /* Crashes under W2K8 */
948         hr = IFileSaveDialog_SetProperties(pfsd, NULL);
949         ok(hr == S_OK, "got 0x%08x\n", hr);
950     }
951 
952     /* SetCollectedProperties */
953     todo_wine
954     {
955     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, TRUE);
956     ok(hr == S_OK, "got 0x%08x\n", hr);
957     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, FALSE);
958     ok(hr == S_OK, "got 0x%08x\n", hr);
959     }
960 
961     /* SetSaveAsItem */
962     todo_wine
963     {
964     hr = IFileSaveDialog_SetSaveAsItem(pfsd, NULL);
965     ok(hr == S_OK, "got 0x%08x\n", hr);
966     hr = IFileSaveDialog_SetSaveAsItem(pfsd, psidesktop);
967     ok(hr == MK_E_NOOBJECT, "got 0x%08x\n", hr);
968     }
969 
970     /** IFileDialog2 **/
971 
972     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialog2, (void**)&pfd2);
973     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
974     if(SUCCEEDED(hr))
975     {
976         /* SetCancelButtonLabel */
977         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
978         ok(hr == S_OK, "got 0x%08x\n", hr);
979         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
980         ok(hr == S_OK, "got 0x%08x\n", hr);
981         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
982         ok(hr == S_OK, "got 0x%08x\n", hr);
983 
984         /* SetNavigationRoot */
985         todo_wine
986         {
987         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
988         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
989         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
990         ok(hr == S_OK, "got 0x%08x\n", hr);
991         }
992 
993         IFileDialog2_Release(pfd2);
994     }
995 
996     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialog2, (void**)&pfd2);
997     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
998     if(SUCCEEDED(hr))
999     {
1000         /* SetCancelButtonLabel */
1001         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
1002         ok(hr == S_OK, "got 0x%08x\n", hr);
1003         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
1004         ok(hr == S_OK, "got 0x%08x\n", hr);
1005         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
1006         ok(hr == S_OK, "got 0x%08x\n", hr);
1007 
1008         /* SetNavigationRoot */
1009         todo_wine
1010         {
1011         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
1012         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1013         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
1014         ok(hr == S_OK, "got 0x%08x\n", hr);
1015         }
1016 
1017         IFileDialog2_Release(pfd2);
1018     }
1019 
1020     /* Cleanup */
1021     IShellItem_Release(psidesktop);
1022     ref = IFileOpenDialog_Release(pfod);
1023     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1024     ref = IFileSaveDialog_Release(pfsd);
1025     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1026 }
1027 
1028 static void ensure_zero_events_(const char *file, int line, IFileDialogEventsImpl *impl)
1029 {
1030     ok_(file, line)(!impl->OnFileOk, "OnFileOk: %d\n", impl->OnFileOk);
1031     ok_(file, line)(!impl->OnFolderChanging, "OnFolderChanging: %d\n", impl->OnFolderChanging);
1032     ok_(file, line)(!impl->OnFolderChange, "OnFolderChange: %d\n", impl->OnFolderChange);
1033     ok_(file, line)(!impl->OnSelectionChange, "OnSelectionChange: %d\n", impl->OnSelectionChange);
1034     ok_(file, line)(!impl->OnShareViolation, "OnShareViolation: %d\n", impl->OnShareViolation);
1035     ok_(file, line)(!impl->OnTypeChange, "OnTypeChange: %d\n", impl->OnTypeChange);
1036     ok_(file, line)(!impl->OnOverwrite, "OnOverwrite: %d\n", impl->OnOverwrite);
1037     impl->OnFileOk = impl->OnFolderChanging = impl->OnFolderChange = 0;
1038     impl->OnSelectionChange = impl->OnShareViolation = impl->OnTypeChange = 0;
1039     impl->OnOverwrite = 0;
1040 }
1041 #define ensure_zero_events(impl) ensure_zero_events_(__FILE__, __LINE__, impl)
1042 
1043 static void test_advise_helper(IFileDialog *pfd)
1044 {
1045     IFileDialogEventsImpl *pfdeimpl;
1046     IFileDialogEvents *pfde;
1047     DWORD cookie[10];
1048     UINT i;
1049     HRESULT hr;
1050 
1051     pfde = IFileDialogEvents_Constructor();
1052     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1053 
1054     /* Null pointer tests crash on Windows 10 16299 or newer */
1055     if (0)
1056     {
1057         hr = IFileDialog_Advise(pfd, NULL, NULL);
1058         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1059         hr = IFileDialog_Advise(pfd, pfde, NULL);
1060         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1061     }
1062     hr = IFileDialog_Advise(pfd, NULL, &cookie[0]);
1063     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1064     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1065     ensure_zero_events(pfdeimpl);
1066 
1067     hr = IFileDialog_Unadvise(pfd, 0);
1068     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1069     for(i = 0; i < 10; i++) {
1070         hr = IFileDialog_Advise(pfd, pfde, &cookie[i]);
1071         ok(hr == S_OK, "got 0x%08x\n", hr);
1072         ok(cookie[i] == i+cookie[0], "Got cookie: %d\n", cookie[i]);
1073     }
1074     ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
1075     ensure_zero_events(pfdeimpl);
1076 
1077     for(i = 3; i < 7; i++) {
1078         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1079         ok(hr == S_OK, "got 0x%08x\n", hr);
1080     }
1081     ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref);
1082     ensure_zero_events(pfdeimpl);
1083 
1084     for(i = 0; i < 3; i++) {
1085         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1086         ok(hr == S_OK, "got 0x%08x\n", hr);
1087     }
1088     ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref);
1089     ensure_zero_events(pfdeimpl);
1090 
1091     for(i = 7; i < 10; i++) {
1092         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1093         ok(hr == S_OK, "got 0x%08x\n", hr);
1094     }
1095     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1096     ensure_zero_events(pfdeimpl);
1097 
1098     hr = IFileDialog_Unadvise(pfd, cookie[9]+1);
1099     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1100     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1101     ensure_zero_events(pfdeimpl);
1102 
1103     hr = IFileDialog_Advise(pfd, pfde, &cookie[0]);
1104     ok(hr == S_OK, "got 0x%08x\n", hr);
1105     ok(cookie[0] >= 1, "got cookie: %d\n", cookie[0]);
1106     ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref);
1107     ensure_zero_events(pfdeimpl);
1108 
1109     hr = IFileDialog_Unadvise(pfd, cookie[0]);
1110 
1111     if(0)
1112     {
1113         /* Unadvising already unadvised cookies crashes on
1114            Windows 7. */
1115         IFileDialog_Unadvise(pfd, cookie[0]);
1116     }
1117 
1118 
1119     IFileDialogEvents_Release(pfde);
1120 }
1121 
1122 static void test_advise(void)
1123 {
1124     IFileDialog *pfd;
1125     HRESULT hr;
1126     LONG ref;
1127 
1128     trace("Testing FileOpenDialog (advise)\n");
1129     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1130                           &IID_IFileDialog, (void**)&pfd);
1131     ok(hr == S_OK, "got 0x%08x.\n", hr);
1132     test_advise_helper(pfd);
1133     ref = IFileDialog_Release(pfd);
1134     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1135 
1136     trace("Testing FileSaveDialog (advise)\n");
1137     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
1138                           &IID_IFileDialog, (void**)&pfd);
1139     ok(hr == S_OK, "got 0x%08x.\n", hr);
1140     test_advise_helper(pfd);
1141     ref = IFileDialog_Release(pfd);
1142     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1143 }
1144 
1145 static void filedialog_change_filetype(IFileDialog *pfd, HWND dlg_hwnd)
1146 {
1147     HWND cb_filetype;
1148     const WCHAR filetype1[] = {'f','n','a','m','e','1',0};
1149     const WCHAR filetype1_broken[] = {'f','n','a','m','e','1',' ', '(','*','.','t','x','t',')',0};
1150 
1151     cb_filetype = find_window(dlg_hwnd, NULL, filetype1);
1152     ok(cb_filetype != NULL || broken(cb_filetype == NULL), "Could not find combobox on first attempt\n");
1153 
1154     if(!cb_filetype)
1155     {
1156         /* Not sure when this happens. Some specific version?
1157          * Seen on 32-bit English Vista */
1158         trace("Didn't find combobox on first attempt, trying broken string..\n");
1159         cb_filetype = find_window(dlg_hwnd, NULL, filetype1_broken);
1160         ok(broken(cb_filetype != NULL), "Failed to find combobox on second attempt\n");
1161         if(!cb_filetype)
1162             return;
1163     }
1164 
1165     /* Making the combobox send a CBN_SELCHANGE */
1166     SendMessageW( cb_filetype, CB_SHOWDROPDOWN, 1, 0 );
1167     SendMessageW( cb_filetype, CB_SETCURSEL, 1, 0 );
1168     SendMessageW( cb_filetype, WM_LBUTTONDOWN, 0, -1 );
1169     SendMessageW( cb_filetype, WM_LBUTTONUP, 0, -1 );
1170 }
1171 
1172 static void test_events(void)
1173 {
1174     IFileDialog *pfd;
1175     IFileDialogEventsImpl *pfdeimpl;
1176     IFileDialogEvents *pfde;
1177     DWORD cookie;
1178     ULONG ref;
1179     HRESULT hr;
1180     const WCHAR fname1[] = {'f','n','a','m','e','1', 0};
1181     const WCHAR fspec1[] = {'*','.','t','x','t',0};
1182     const WCHAR fname2[] = {'f','n','a','m','e','2', 0};
1183     const WCHAR fspec2[] = {'*','.','e','x','e',0};
1184     COMDLG_FILTERSPEC filterspec[3] = {{fname1, fspec1}, {fname2, fspec2}};
1185 
1186 
1187     /*
1188      * 1. Show the dialog with no filetypes added
1189      */
1190     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1191                           &IID_IFileDialog, (void**)&pfd);
1192     ok(hr == S_OK, "got 0x%08x.\n", hr);
1193 
1194     pfde = IFileDialogEvents_Constructor();
1195     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1196     pfdeimpl->events_test = IFDEVENT_TEST2;
1197 
1198     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1199     ok(hr == S_OK, "got 0x%08x.\n", hr);
1200 
1201     hr = IFileDialog_Show(pfd, NULL);
1202     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1203 
1204     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1205     pfdeimpl->OnFolderChanging = 0;
1206     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1207     pfdeimpl->OnFolderChange = 0;
1208     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1209     pfdeimpl->OnSelectionChange = 0;
1210     ok(pfdeimpl->OnTypeChange == 0, "Got %d\n", pfdeimpl->OnTypeChange);
1211     pfdeimpl->OnTypeChange = 0;
1212 
1213     ensure_zero_events(pfdeimpl);
1214 
1215     hr = IFileDialog_Unadvise(pfd, cookie);
1216     ok(hr == S_OK, "got 0x%08x.\n", hr);
1217 
1218     IFileDialogEvents_Release(pfde);
1219     ref = IFileDialog_Release(pfd);
1220     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1221 
1222 
1223     /*
1224      * 2. Show the dialog with filetypes added
1225      */
1226     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1227                           &IID_IFileDialog, (void**)&pfd);
1228     ok(hr == S_OK, "got 0x%08x.\n", hr);
1229 
1230     pfde = IFileDialogEvents_Constructor();
1231     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1232     pfdeimpl->events_test = IFDEVENT_TEST2;
1233 
1234     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1235     ok(hr == S_OK, "got 0x%08x.\n", hr);
1236 
1237     hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
1238     ok(hr == S_OK, "got 0x%08x.\n", hr);
1239 
1240     ensure_zero_events(pfdeimpl);
1241 
1242     hr = IFileDialog_Show(pfd, NULL);
1243     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1244 
1245     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1246     pfdeimpl->OnFolderChanging = 0;
1247     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1248     pfdeimpl->OnFolderChange = 0;
1249     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1250     pfdeimpl->OnSelectionChange = 0;
1251     /* Called once just by showing the dialog */
1252     ok(pfdeimpl->OnTypeChange == 1, "Got %d\n", pfdeimpl->OnTypeChange);
1253     pfdeimpl->OnTypeChange = 0;
1254 
1255     ensure_zero_events(pfdeimpl);
1256 
1257     hr = IFileDialog_Unadvise(pfd, cookie);
1258     ok(hr == S_OK, "got 0x%08x.\n", hr);
1259 
1260     IFileDialogEvents_Release(pfde);
1261     ref = IFileDialog_Release(pfd);
1262     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1263 
1264 
1265     /*
1266      * 3. Show the dialog with filetypes added and simulate manual change of filetype
1267      */
1268     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1269                           &IID_IFileDialog, (void**)&pfd);
1270     ok(hr == S_OK, "got 0x%08x.\n", hr);
1271 
1272     pfde = IFileDialogEvents_Constructor();
1273     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1274     pfdeimpl->events_test = IFDEVENT_TEST3;
1275 
1276     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1277     ok(hr == S_OK, "got 0x%08x.\n", hr);
1278 
1279     hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
1280     ok(hr == S_OK, "got 0x%08x.\n", hr);
1281 
1282     ensure_zero_events(pfdeimpl);
1283 
1284     hr = IFileDialog_Show(pfd, NULL);
1285     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1286 
1287     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1288     pfdeimpl->OnFolderChanging = 0;
1289     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1290     pfdeimpl->OnFolderChange = 0;
1291     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1292     pfdeimpl->OnSelectionChange = 0;
1293     /* Called once by showing the dialog and once again when changing the filetype */
1294     todo_wine ok(pfdeimpl->OnTypeChange == 2, "Got %d\n", pfdeimpl->OnTypeChange);
1295     pfdeimpl->OnTypeChange = 0;
1296 
1297     ensure_zero_events(pfdeimpl);
1298 
1299     hr = IFileDialog_Unadvise(pfd, cookie);
1300     ok(hr == S_OK, "got 0x%08x.\n", hr);
1301 
1302     IFileDialogEvents_Release(pfde);
1303     ref = IFileDialog_Release(pfd);
1304     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1305 }
1306 
1307 static void touch_file(LPCWSTR filename)
1308 {
1309     HANDLE file;
1310     file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1311     ok(file != INVALID_HANDLE_VALUE, "Failed to create file.\n");
1312     CloseHandle(file);
1313 }
1314 
1315 static void test_filename_savedlg_(LPCWSTR set_filename, LPCWSTR defext,
1316                                    const COMDLG_FILTERSPEC *filterspec, UINT fs_count,
1317                                    LPCWSTR exp_filename, const char *file, int line)
1318 {
1319     IFileSaveDialog *pfsd;
1320     IFileDialogEventsImpl *pfdeimpl;
1321     IFileDialogEvents *pfde;
1322     DWORD cookie;
1323     LPWSTR filename;
1324     IShellItem *psi;
1325     LONG ref;
1326     HRESULT hr;
1327 
1328     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
1329                           &IID_IFileSaveDialog, (void**)&pfsd);
1330     ok_(file,line)(hr == S_OK, "Got 0x%08x\n", hr);
1331 
1332     if(fs_count)
1333     {
1334         hr = IFileSaveDialog_SetFileTypes(pfsd, fs_count, filterspec);
1335         ok_(file,line)(hr == S_OK, "SetFileTypes failed: Got 0x%08x\n", hr);
1336     }
1337 
1338     if(defext)
1339     {
1340         hr = IFileSaveDialog_SetDefaultExtension(pfsd, defext);
1341         ok_(file,line)(hr == S_OK, "SetDefaultExtensions failed: Got 0x%08x\n", hr);
1342     }
1343 
1344     pfde = IFileDialogEvents_Constructor();
1345     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1346     pfdeimpl->set_filename = set_filename;
1347     hr = IFileSaveDialog_Advise(pfsd, pfde, &cookie);
1348     ok_(file,line)(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
1349 
1350     hr = IFileSaveDialog_Show(pfsd, NULL);
1351     ok_(file,line)(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
1352 
1353     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
1354     ok_(file,line)(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
1355     ok_(file,line)(!lstrcmpW(filename, set_filename), "Got %s\n", wine_dbgstr_w(filename));
1356     CoTaskMemFree(filename);
1357 
1358     hr = IFileSaveDialog_GetResult(pfsd, &psi);
1359     ok_(file,line)(hr == S_OK, "GetResult failed: Got 0x%08x\n", hr);
1360 
1361     hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1362     ok_(file,line)(hr == S_OK, "GetDisplayName failed: Got 0x%08x\n", hr);
1363     ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetDisplayName) Got %s\n", wine_dbgstr_w(filename));
1364     CoTaskMemFree(filename);
1365     IShellItem_Release(psi);
1366 
1367     hr = IFileSaveDialog_Unadvise(pfsd, cookie);
1368     ok_(file,line)(hr == S_OK, "Unadvise failed: Got 0x%08x\n", hr);
1369 
1370     ref = IFileSaveDialog_Release(pfsd);
1371     ok_(file,line)(!ref, "Got refcount %d, should have been released.\n", ref);
1372 
1373     IFileDialogEvents_Release(pfde);
1374 }
1375 #define test_filename_savedlg(set_filename, defext, filterspec, fs_count, exp_filename) \
1376     test_filename_savedlg_(set_filename, defext, filterspec, fs_count, exp_filename, __FILE__, __LINE__)
1377 
1378 static void test_filename_opendlg_(LPCWSTR set_filename, IShellItem *psi_current, LPCWSTR defext,
1379                                    const COMDLG_FILTERSPEC *filterspec, UINT fs_count,
1380                                    LPCWSTR exp_filename, const char *file, int line)
1381 {
1382     IFileOpenDialog *pfod;
1383     IFileDialogEventsImpl *pfdeimpl;
1384     IFileDialogEvents *pfde;
1385     DWORD cookie;
1386     LPWSTR filename;
1387     IShellItemArray *psia;
1388     IShellItem *psi;
1389     LONG ref;
1390     HRESULT hr;
1391 
1392     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1393                           &IID_IFileOpenDialog, (void**)&pfod);
1394     ok_(file,line)(hr == S_OK, "CoCreateInstance failed: Got 0x%08x\n", hr);
1395 
1396     if(defext)
1397     {
1398         hr = IFileOpenDialog_SetDefaultExtension(pfod, defext);
1399         ok_(file,line)(hr == S_OK, "SetDefaultExtensions failed: Got 0x%08x\n", hr);
1400     }
1401 
1402     if(fs_count)
1403     {
1404         hr = IFileOpenDialog_SetFileTypes(pfod, 2, filterspec);
1405         ok_(file,line)(hr == S_OK, "SetFileTypes failed: Got 0x%08x\n", hr);
1406     }
1407 
1408     hr = IFileOpenDialog_SetFolder(pfod, psi_current);
1409     ok_(file,line)(hr == S_OK, "SetFolder failed: Got 0x%08x\n", hr);
1410 
1411     pfde = IFileDialogEvents_Constructor();
1412     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1413     pfdeimpl->set_filename = set_filename;
1414     pfdeimpl->set_filename_tried = FALSE;
1415     hr = IFileOpenDialog_Advise(pfod, pfde, &cookie);
1416     ok_(file,line)(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
1417 
1418     hr = IFileOpenDialog_Show(pfod, NULL);
1419     ok_(file,line)(hr == S_OK || (!exp_filename && hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)),
1420                    "Show failed: Got 0x%08x\n", hr);
1421     if(hr == S_OK)
1422     {
1423         hr = IFileOpenDialog_GetResult(pfod, &psi);
1424         ok_(file,line)(hr == S_OK, "GetResult failed: Got 0x%08x\n", hr);
1425 
1426         hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1427         ok_(file,line)(hr == S_OK, "GetDisplayName(Result) failed: Got 0x%08x\n", hr);
1428         ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetResult) Got %s\n", wine_dbgstr_w(filename));
1429         CoTaskMemFree(filename);
1430         IShellItem_Release(psi);
1431 
1432         hr = IFileOpenDialog_GetResults(pfod, &psia);
1433         ok_(file,line)(hr == S_OK, "GetResults failed: Got 0x%08x\n", hr);
1434         hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1435         ok_(file,line)(hr == S_OK, "GetItemAt failed: Got 0x%08x\n", hr);
1436 
1437         hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1438         ok_(file,line)(hr == S_OK, "GetDisplayName(Results) failed: Got 0x%08x\n", hr);
1439         ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetResults) Got %s\n", wine_dbgstr_w(filename));
1440         CoTaskMemFree(filename);
1441 
1442         IShellItem_Release(psi);
1443         IShellItemArray_Release(psia);
1444     }
1445     else
1446     {
1447         hr = IFileOpenDialog_GetResult(pfod, &psi);
1448         ok_(file,line)(hr == E_UNEXPECTED, "GetResult: Got 0x%08x\n", hr);
1449 
1450         hr = IFileOpenDialog_GetResults(pfod, &psia);
1451         ok_(file,line)(hr == E_FAIL, "GetResults: Got 0x%08x\n", hr);
1452     }
1453 
1454     hr = IFileOpenDialog_GetFileName(pfod, &filename);
1455     ok_(file,line)(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
1456     ok_(file,line)(!lstrcmpW(filename, set_filename), "(GetFileName) Got %s\n", wine_dbgstr_w(filename));
1457     CoTaskMemFree(filename);
1458 
1459 
1460     hr = IFileOpenDialog_Unadvise(pfod, cookie);
1461     ok_(file,line)(hr == S_OK, "Unadvise failed: Got 0x%08x\n", hr);
1462 
1463     ref = IFileOpenDialog_Release(pfod);
1464     ok_(file,line)(!ref, "Got refcount %d, should have been released.\n", ref);
1465 
1466     IFileDialogEvents_Release(pfde);
1467 }
1468 #define test_filename_opendlg(set_filename, psi, defext, filterspec, fs_count, exp_filename) \
1469     test_filename_opendlg_(set_filename, psi, defext, filterspec, fs_count, exp_filename, __FILE__, __LINE__)
1470 
1471 static void test_filename(void)
1472 {
1473     IShellItem *psi_current;
1474     HRESULT hr;
1475     WCHAR buf[MAX_PATH];
1476 
1477     static const WCHAR filename_noextW[] = {'w','i','n','e','t','e','s','t',0};
1478     static const WCHAR filename_dotextW[] = {'w','i','n','e','t','e','s','t','.',0};
1479     static const WCHAR filename_dotanddefW[] = {'w','i','n','e','t','e','s','t','.','.','w','t','e',0};
1480     static const WCHAR filename_defextW[] = {'w','i','n','e','t','e','s','t','.','w','t','e',0};
1481     static const WCHAR filename_ext1W[] = {'w','i','n','e','t','e','s','t','.','w','t','1',0};
1482     static const WCHAR filename_ext2W[] = {'w','i','n','e','t','e','s','t','.','w','t','2',0};
1483     static const WCHAR filename_ext1anddefW[] =
1484         {'w','i','n','e','t','e','s','t','.','w','t','1','.','w','t','e',0};
1485     static const WCHAR defextW[] = {'w','t','e',0};
1486     static const WCHAR desc1[] = {'d','e','s','c','r','i','p','t','i','o','n','1',0};
1487     static const WCHAR desc2[] = {'d','e','s','c','r','i','p','t','i','o','n','2',0};
1488     static const WCHAR descdef[] = {'d','e','f','a','u','l','t',' ','d','e','s','c',0};
1489     static const WCHAR ext1[] = {'*','.','w','t','1',0};
1490     static const WCHAR ext2[] = {'*','.','w','t','2',0};
1491     static const WCHAR extdef[] = {'*','.','w','t','e',0};
1492     static const WCHAR complexext[] = {'*','.','w','t','2',';','*','.','w','t','1',0};
1493 
1494     static const COMDLG_FILTERSPEC filterspec[] = {
1495         { desc1, ext1 }, { desc2, ext2 }, { descdef, extdef }
1496     };
1497     static const COMDLG_FILTERSPEC filterspec2[] = {
1498         { desc1, complexext }
1499     };
1500 
1501     /* No extension */
1502     test_filename_savedlg(filename_noextW, NULL, NULL, 0, filename_noextW);
1503     /* Default extension */
1504     test_filename_savedlg(filename_noextW, defextW, NULL, 0, filename_defextW);
1505     /* Default extension on filename ending with a . */
1506     test_filename_savedlg(filename_dotextW, defextW, NULL, 0, filename_dotanddefW);
1507     /* Default extension on filename with default extension */
1508     test_filename_savedlg(filename_defextW, defextW, NULL, 0, filename_defextW);
1509     /* Default extension on filename with another extension */
1510     test_filename_savedlg(filename_ext1W, defextW, NULL, 0, filename_ext1anddefW);
1511     /* Default extension, filterspec without default extension */
1512     test_filename_savedlg(filename_noextW, defextW, filterspec, 2, filename_ext1W);
1513     /* Default extension, filterspec with default extension */
1514     test_filename_savedlg(filename_noextW, defextW, filterspec, 3, filename_ext1W);
1515     /* Default extension, filterspec with "complex" extension */
1516     test_filename_savedlg(filename_noextW, defextW, filterspec2, 1, filename_ext2W);
1517 
1518     GetCurrentDirectoryW(MAX_PATH, buf);
1519     ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
1520     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
1521     ok(hr == S_OK, "Got 0x%08x\n", hr);
1522 
1523     touch_file(filename_noextW);
1524     touch_file(filename_defextW);
1525     touch_file(filename_ext2W);
1526 
1527     /* IFileOpenDialog, default extension */
1528     test_filename_opendlg(filename_noextW, psi_current, defextW, NULL, 0, filename_noextW);
1529     /* IFileOpenDialog, default extension and filterspec */
1530     test_filename_opendlg(filename_noextW, psi_current, defextW, filterspec, 2, filename_noextW);
1531 
1532     DeleteFileW(filename_noextW);
1533     /* IFileOpenDialog, default extension, noextW deleted */
1534     test_filename_opendlg(filename_noextW, psi_current, defextW, NULL, 0, filename_defextW);
1535     if(0) /* Interactive */
1536     {
1537     /* IFileOpenDialog, filterspec, no default extension, noextW deleted */
1538     test_filename_opendlg(filename_noextW, psi_current, NULL, filterspec, 2, NULL);
1539     }
1540 
1541     IShellItem_Release(psi_current);
1542     DeleteFileW(filename_defextW);
1543     DeleteFileW(filename_ext2W);
1544 }
1545 
1546 static const WCHAR label[] = {'l','a','b','e','l',0};
1547 static const WCHAR label2[] = {'t','e','s','t',0};
1548 static const WCHAR menuW[] = {'m','e','n','u','_','i','t','e','m',0};
1549 static const WCHAR pushbutton1W[] = {'p','u','s','h','b','u','t','t','o','n','_','i','t','e','m',0};
1550 static const WCHAR pushbutton2W[] = {'p','u','s','h','b','u','t','t','o','n','2','_','i','t','e','m',0};
1551 static const WCHAR comboboxitem1W[] = {'c','o','m','b','o','b','o','x','1','_','i','t','e','m',0};
1552 static const WCHAR comboboxitem2W[] = {'c','o','m','b','o','b','o','x','2','_','i','t','e','m',0};
1553 static const WCHAR radiobutton1W[] = {'r','a','d','i','o','b','u','t','t','o','n','1','_','i','t','e','m',0};
1554 static const WCHAR radiobutton2W[] = {'r','a','d','i','o','b','u','t','t','o','n','2','_','i','t','e','m',0};
1555 static const WCHAR checkbutton1W[] = {'c','h','e','c','k','b','u','t','t','o','n','1','_','i','t','e','m',0};
1556 static const WCHAR checkbutton2W[] = {'c','h','e','c','k','b','u','t','t','o','n','2','_','i','t','e','m',0};
1557 static const WCHAR editbox1W[] = {'e','d','i','t','b','o','x','W','1','_','i','t','e','m',0};
1558 static const WCHAR editbox2W[] = {'e','d','i','t','b','o','x','W','2','_','i','t','e','m',0};
1559 static const WCHAR textW[] = {'t','e','x','t','_','i','t','e','m',0};
1560 static const WCHAR text2W[] = {'t','e','x','t','2','_','i','t','e','m',0};
1561 static const WCHAR separatorW[] = {'s','e','p','a','r','a','t','o','r','_','i','t','e','m',0};
1562 static const WCHAR visualgroup1W[] = {'v','i','s','u','a','l','g','r','o','u','p','1',0};
1563 static const WCHAR visualgroup2W[] = {'v','i','s','u','a','l','g','r','o','u','p','2',0};
1564 
1565 static const WCHAR floatnotifysinkW[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};
1566 static const WCHAR RadioButtonListW[] = {'R','a','d','i','o','B','u','t','t','o','n','L','i','s','t',0};
1567 
1568 static void test_customize_onfolderchange(IFileDialog *pfd)
1569 {
1570     HWND dlg_hwnd, item, item_parent;
1571     BOOL br;
1572     WCHAR buf[1024];
1573 
1574     buf[0] = '\0';
1575 
1576     dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
1577     ok(dlg_hwnd != NULL, "Got NULL.\n");
1578 
1579     item = find_window(dlg_hwnd, NULL, checkbutton2W);
1580     ok(item != NULL, "Failed to find item.\n");
1581     item_parent = GetParent(item);
1582     GetClassNameW(item_parent, buf, 1024);
1583     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1584     item = find_window(dlg_hwnd, NULL, text2W);
1585     ok(item != NULL, "Failed to find item.\n");
1586     item_parent = GetParent(item);
1587     GetClassNameW(item_parent, buf, 1024);
1588     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1589     item = find_window(dlg_hwnd, NULL, radiobutton1W);
1590     ok(item != NULL, "Failed to find item.\n");
1591     item_parent = GetParent(item);
1592     GetClassNameW(item_parent, buf, 1024);
1593     ok(!lstrcmpW(buf, RadioButtonListW), "Got %s\n", wine_dbgstr_w(buf));
1594     item_parent = GetParent(item_parent);
1595     GetClassNameW(item_parent, buf, 1024);
1596     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1597 
1598     item = find_window(dlg_hwnd, NULL, pushbutton1W);
1599     ok(item == NULL, "Found item: %p\n", item);
1600     item = find_window(dlg_hwnd, NULL, pushbutton2W);
1601     ok(item == NULL, "Found item: %p\n", item);
1602     item = find_window(dlg_hwnd, NULL, comboboxitem1W);
1603     ok(item == NULL, "Found item: %p\n", item);
1604     item = find_window(dlg_hwnd, NULL, comboboxitem2W);
1605     ok(item == NULL, "Found item: %p\n", item);
1606     item = find_window(dlg_hwnd, NULL, radiobutton2W);
1607     ok(item == NULL, "Found item: %p\n", item);
1608     item = find_window(dlg_hwnd, NULL, checkbutton1W);
1609     ok(item == NULL, "Found item: %p\n", item);
1610     item = find_window(dlg_hwnd, NULL, editbox1W);
1611     ok(item == NULL, "Found item: %p\n", item);
1612     item = find_window(dlg_hwnd, NULL, editbox2W);
1613     ok(item == NULL, "Found item: %p\n", item);
1614     item = find_window(dlg_hwnd, NULL, textW);
1615     ok(item == NULL, "Found item: %p\n", item);
1616     item = find_window(dlg_hwnd, NULL, separatorW);
1617     ok(item == NULL, "Found item: %p\n", item);
1618     item = find_window(dlg_hwnd, NULL, visualgroup1W);
1619     ok(item == NULL, "Found item: %p\n", item);
1620     item = find_window(dlg_hwnd, NULL, visualgroup2W);
1621     todo_wine ok(item == NULL, "Found item: %p\n", item);
1622 
1623     br = PostMessageW(dlg_hwnd, WM_COMMAND, IDCANCEL, 0);
1624     ok(br, "Failed\n");
1625 }
1626 
1627 static void test_customize(void)
1628 {
1629     IFileDialog *pfod;
1630     IFileDialogCustomize *pfdc;
1631     IFileDialogEventsImpl *pfdeimpl;
1632     IFileDialogEvents *pfde;
1633     IOleWindow *pow;
1634     CDCONTROLSTATEF cdstate;
1635     DWORD cookie;
1636     LPWSTR tmpstr;
1637     UINT i;
1638     UINT id_vgroup1, id_text, id_editbox1;
1639     LONG ref;
1640     HWND dlg_hwnd;
1641     HRESULT hr;
1642     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1643                           &IID_IFileDialog, (void**)&pfod);
1644     ok(hr == S_OK, "got 0x%08x.\n", hr);
1645 
1646     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
1647     ok(hr == S_OK, "got 0x%08x.\n", hr);
1648     if(FAILED(hr))
1649     {
1650         skip("Skipping IFileDialogCustomize tests.\n");
1651         IFileDialog_Release(pfod);
1652         return;
1653     }
1654 
1655     i = 0;
1656     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton1W);
1657     ok(hr == S_OK, "got 0x%08x.\n", hr);
1658     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton1W);
1659     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1660 
1661     hr = IFileDialog_QueryInterface(pfod, &IID_IOleWindow, (void**)&pow);
1662     ok(hr == S_OK, "Got 0x%08x\n", hr);
1663     hr = IOleWindow_GetWindow(pow, &dlg_hwnd);
1664     ok(hr == S_OK, "Got 0x%08x\n", hr);
1665     ok(dlg_hwnd == NULL, "NULL\n");
1666     IOleWindow_Release(pow);
1667 
1668     cdstate = 0xdeadbeef;
1669     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1670     ok(hr == S_OK, "got 0x%08x.\n", hr);
1671     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1672 
1673     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1674     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1675 
1676     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1677     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1678 
1679     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i);
1680     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1681     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, ++i);
1682     ok(hr == S_OK, "got 0x%08x.\n", hr);
1683 
1684     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i);
1685     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1686     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i+1);
1687     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1688 
1689     cdstate = 0xdeadbeef;
1690     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1691     ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1692     ok(cdstate == 0xdeadbeef, "got 0x%08x.\n", cdstate);
1693 
1694     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1695     ok(hr == S_OK, "got 0x%08x.\n", hr);
1696     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1697     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1698 
1699     cdstate = 0xdeadbeef;
1700     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1701     ok(hr == S_OK, "got 0x%08x.\n", hr);
1702     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1703     hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
1704     ok(hr == S_OK, "got 0x%08x.\n", hr);
1705     cdstate = 0xdeadbeef;
1706     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1707     ok(hr == S_OK, "got 0x%08x.\n", hr);
1708     ok(!cdstate, "got 0x%08x.\n", cdstate);
1709     hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
1710     ok(hr == S_OK, "got 0x%08x.\n", hr);
1711     cdstate = 0xdeadbeef;
1712     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1713     ok(hr == S_OK, "got 0x%08x.\n", hr);
1714     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1715 
1716     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1717     ok(hr == E_NOTIMPL, "got 0x%08x (control: %d).\n", hr, i);
1718 
1719     hr = IFileDialogCustomize_AddMenu(pfdc, i, menuW);
1720     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1721     hr = IFileDialogCustomize_AddMenu(pfdc, ++i, label);
1722     ok(hr == S_OK, "got 0x%08x.\n", hr);
1723 
1724     cdstate = 0xdeadbeef;
1725     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1726     ok(hr == S_OK, "got 0x%08x.\n", hr);
1727     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1728 
1729     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1730     ok(hr == S_OK, "got 0x%08x.\n", hr);
1731     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1732     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1733 
1734     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1735     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1736 
1737     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton2W);
1738     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1739     hr = IFileDialogCustomize_AddPushButton(pfdc, ++i, pushbutton2W);
1740     ok(hr == S_OK, "got 0x%08x.\n", hr);
1741 
1742     cdstate = 0xdeadbeef;
1743     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1744     ok(hr == S_OK, "got 0x%08x.\n", hr);
1745     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1746 
1747     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1748     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1749 
1750     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1751     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1752 
1753     hr = IFileDialogCustomize_AddComboBox(pfdc, i);
1754     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1755     hr = IFileDialogCustomize_AddComboBox(pfdc, ++i);
1756     ok(hr == S_OK, "got 0x%08x.\n", hr);
1757 
1758     cdstate = 0xdeadbeef;
1759     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1760     ok(hr == S_OK, "got 0x%08x.\n", hr);
1761     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1762 
1763     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1764     ok(hr == S_OK, "got 0x%08x.\n", hr);
1765     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1766     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1767 
1768     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1769     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1770 
1771     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, i);
1772     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1773     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, ++i);
1774     ok(hr == S_OK, "got 0x%08x.\n", hr);
1775 
1776     cdstate = 0xdeadbeef;
1777     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1778     ok(hr == S_OK, "got 0x%08x.\n", hr);
1779     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1780 
1781     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, radiobutton1W);
1782     ok(hr == S_OK, "got 0x%08x.\n", hr);
1783     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, radiobutton1W);
1784     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1785 
1786     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, radiobutton2W);
1787     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1788 
1789     hr = IFileDialogCustomize_AddCheckButton(pfdc, i, label, TRUE);
1790     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1791     hr = IFileDialogCustomize_AddCheckButton(pfdc, ++i, checkbutton1W, TRUE);
1792     ok(hr == S_OK, "got 0x%08x.\n", hr);
1793 
1794     cdstate = 0xdeadbeef;
1795     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1796     ok(hr == S_OK, "got 0x%08x.\n", hr);
1797     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1798 
1799     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1800     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1801 
1802     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, checkbutton2W);
1803     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1804 
1805     if(SUCCEEDED(hr))
1806     {
1807         BOOL checked;
1808         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1809         ok(hr == S_OK, "got 0x%08x.\n", hr);
1810         ok(checked, "checkbox not checked.\n");
1811 
1812         hr = IFileDialogCustomize_SetCheckButtonState(pfdc, i, FALSE);
1813         ok(hr == S_OK, "got 0x%08x.\n", hr);
1814 
1815         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1816         ok(hr == S_OK, "got 0x%08x.\n", hr);
1817         ok(!checked, "checkbox checked.\n");
1818 
1819         hr = IFileDialogCustomize_SetCheckButtonState(pfdc, i, TRUE);
1820         ok(hr == S_OK, "got 0x%08x.\n", hr);
1821 
1822         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1823         ok(hr == S_OK, "got 0x%08x.\n", hr);
1824         ok(checked, "checkbox not checked.\n");
1825     }
1826 
1827     hr = IFileDialogCustomize_AddEditBox(pfdc, i, label);
1828     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1829     hr = IFileDialogCustomize_AddEditBox(pfdc, ++i, editbox1W);
1830     ok(hr == S_OK, "got 0x%08x.\n", hr);
1831 
1832     cdstate = 0xdeadbeef;
1833     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1834     ok(hr == S_OK, "got 0x%08x.\n", hr);
1835     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1836 
1837     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1838     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1839 
1840     /* Does not affect the text in the editbox */
1841     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, editbox2W);
1842     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1843 
1844     hr = IFileDialogCustomize_GetEditBoxText(pfdc, i, &tmpstr);
1845     ok(hr == S_OK, "got 0x%08x.\n", hr);
1846     if(SUCCEEDED(hr))
1847     {
1848         ok(!lstrcmpW(tmpstr, editbox1W), "got %s.\n", wine_dbgstr_w(tmpstr));
1849         CoTaskMemFree(tmpstr);
1850     }
1851 
1852     hr = IFileDialogCustomize_SetEditBoxText(pfdc, i, label2);
1853     ok(hr == S_OK, "got 0x%08x.\n", hr);
1854 
1855     hr = IFileDialogCustomize_GetEditBoxText(pfdc, i, &tmpstr);
1856     ok(hr == S_OK, "got 0x%08x.\n", hr);
1857     if(SUCCEEDED(hr))
1858     {
1859         ok(!lstrcmpW(tmpstr, label2), "got %s.\n", wine_dbgstr_w(tmpstr));
1860         CoTaskMemFree(tmpstr);
1861     }
1862 
1863     hr = IFileDialogCustomize_AddSeparator(pfdc, i);
1864     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1865     hr = IFileDialogCustomize_AddSeparator(pfdc, ++i);
1866     ok(hr == S_OK, "got 0x%08x.\n", hr);
1867 
1868     cdstate = 0xdeadbeef;
1869     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1870     ok(hr == S_OK, "got 0x%08x.\n", hr);
1871     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1872 
1873     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1874     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1875 
1876     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, separatorW);
1877     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1878 
1879     hr = IFileDialogCustomize_AddText(pfdc, i, label);
1880     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1881     hr = IFileDialogCustomize_AddText(pfdc, ++i, textW);
1882     ok(hr == S_OK, "got 0x%08x.\n", hr);
1883 
1884     cdstate = 0xdeadbeef;
1885     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1886     ok(hr == S_OK, "got 0x%08x.\n", hr);
1887     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1888 
1889     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1890     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1891 
1892     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, text2W);
1893     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1894 
1895     hr = IFileDialogCustomize_StartVisualGroup(pfdc, i, label);
1896     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1897     hr = IFileDialogCustomize_StartVisualGroup(pfdc, ++i, visualgroup1W);
1898     ok(hr == S_OK, "got 0x%08x.\n", hr);
1899 
1900     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1901     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1902 
1903     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, visualgroup2W);
1904     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1905 
1906     cdstate = 0xdeadbeef;
1907     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1908     ok(hr == S_OK, "got 0x%08x.\n", hr);
1909     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1910 
1911     hr = IFileDialogCustomize_StartVisualGroup(pfdc, ++i, label);
1912     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1913     hr = IFileDialogCustomize_EndVisualGroup(pfdc);
1914     ok(hr == S_OK, "got 0x%08x.\n", hr);
1915 
1916     i++; /* Nonexisting control */
1917     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1918     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1919     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1920     ok(hr == E_INVALIDARG, "got 0x%08x (control: %d).\n", hr, i);
1921     cdstate = 0xdeadbeef;
1922     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1923     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1924     ok(cdstate == 0xdeadbeef, "got 0x%08x.\n", cdstate);
1925 
1926     pfde = IFileDialogEvents_Constructor();
1927     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1928     pfdeimpl->events_test = IFDEVENT_TEST1;
1929     hr = IFileDialog_Advise(pfod, pfde, &cookie);
1930     ok(hr == S_OK, "Got 0x%08x\n", hr);
1931 
1932     hr = IFileDialog_Show(pfod, NULL);
1933     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "Got 0x%08x\n", hr);
1934 
1935     hr = IFileDialog_Unadvise(pfod, cookie);
1936     ok(hr == S_OK, "Got 0x%08x\n", hr);
1937 
1938     IFileDialogEvents_Release(pfde);
1939     IFileDialogCustomize_Release(pfdc);
1940     ref = IFileDialog_Release(pfod);
1941     ok(!ref, "Refcount not zero (%d).\n", ref);
1942 
1943 
1944     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1945                           &IID_IFileDialog, (void**)&pfod);
1946     ok(hr == S_OK, "got 0x%08x.\n", hr);
1947 
1948     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
1949     ok(hr == S_OK, "got 0x%08x.\n", hr);
1950 
1951     i = 0;
1952     hr = IFileDialogCustomize_AddMenu(pfdc, ++i, label);
1953     ok(hr == S_OK, "got 0x%08x.\n", hr);
1954     if(SUCCEEDED(hr))
1955     {
1956         DWORD selected;
1957         UINT j = 0;
1958 
1959         for(j = 0; j < 10; j++)
1960         {
1961             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
1962             ok(hr == S_OK, "got 0x%08x.\n", hr);
1963         }
1964 
1965         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
1966         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1967 
1968         cdstate = 0xdeadbeef;
1969         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1970         ok(hr == S_OK, "got 0x%08x.\n", hr);
1971         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1972         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
1973         ok(hr == S_OK, "got 0x%08x.\n", hr);
1974         cdstate = 0xdeadbeef;
1975         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1976         ok(hr == S_OK, "got 0x%08x.\n", hr);
1977         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
1978         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
1979         ok(hr == S_OK, "got 0x%08x.\n", hr);
1980         cdstate = 0xdeadbeef;
1981         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1982         ok(hr == S_OK, "got 0x%08x.\n", hr);
1983         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1984 
1985         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
1986         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1987 
1988         for(j = 0; j < 10; j++)
1989         {
1990             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
1991             ok(hr == S_OK, "got 0x%08x.\n", hr);
1992         }
1993     }
1994     hr = IFileDialogCustomize_AddPushButton(pfdc, ++i, label);
1995     ok(hr == S_OK, "got 0x%08x.\n", hr);
1996     hr = IFileDialogCustomize_AddComboBox(pfdc, ++i);
1997     ok(hr == S_OK, "got 0x%08x.\n", hr);
1998     if(SUCCEEDED(hr))
1999     {
2000         DWORD selected = -1;
2001         UINT j = 0;
2002 
2003         for(j = 0; j < 10; j++)
2004         {
2005             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
2006             ok(hr == S_OK, "got 0x%08x.\n", hr);
2007         }
2008 
2009         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2010         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
2011         ok(selected == -1, "got %d.\n", selected);
2012 
2013         cdstate = 0xdeadbeef;
2014         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2015         ok(hr == S_OK, "got 0x%08x.\n", hr);
2016         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2017         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
2018         ok(hr == S_OK, "got 0x%08x.\n", hr);
2019         cdstate = 0xdeadbeef;
2020         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2021         ok(hr == S_OK, "got 0x%08x.\n", hr);
2022         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2023         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2024         ok(hr == S_OK, "got 0x%08x.\n", hr);
2025         cdstate = 0xdeadbeef;
2026         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2027         ok(hr == S_OK, "got 0x%08x.\n", hr);
2028         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2029 
2030         for(j = 0; j < 10; j++)
2031         {
2032             hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2033             ok(hr == S_OK, "got 0x%08x.\n", hr);
2034             hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2035             ok(hr == S_OK, "got 0x%08x.\n", hr);
2036             ok(selected == j, "got %d.\n", selected);
2037         }
2038         j++;
2039         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2040         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
2041 
2042         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2043         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2044 
2045         for(j = 0; j < 10; j++)
2046         {
2047             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2048             ok(hr == S_OK, "got 0x%08x.\n", hr);
2049         }
2050     }
2051 
2052     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, ++i);
2053     ok(hr == S_OK, "got 0x%08x.\n", hr);
2054     if(SUCCEEDED(hr))
2055     {
2056         DWORD selected = -1;
2057         UINT j = 0;
2058 
2059         for(j = 0; j < 10; j++)
2060         {
2061             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
2062             ok(hr == S_OK, "got 0x%08x.\n", hr);
2063         }
2064 
2065         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2066         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
2067         ok(selected == -1, "got %d.\n", selected);
2068 
2069         cdstate = 0xdeadbeef;
2070         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2071         ok(hr == S_OK, "got 0x%08x.\n", hr);
2072         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2073         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
2074         ok(hr == S_OK, "got 0x%08x.\n", hr);
2075         cdstate = 0xdeadbeef;
2076         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2077         ok(hr == S_OK, "got 0x%08x.\n", hr);
2078         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2079         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2080         ok(hr == S_OK, "got 0x%08x.\n", hr);
2081         cdstate = 0xdeadbeef;
2082         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2083         ok(hr == S_OK, "got 0x%08x.\n", hr);
2084         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2085 
2086         for(j = 0; j < 10; j++)
2087         {
2088             hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2089             ok(hr == S_OK, "got 0x%08x.\n", hr);
2090             hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2091             ok(hr == S_OK, "got 0x%08x.\n", hr);
2092             ok(selected == j, "got %d.\n", selected);
2093         }
2094         j++;
2095         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2096         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
2097 
2098         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2099         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2100 
2101         for(j = 0; j < 10; j++)
2102         {
2103             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2104             ok(hr == S_OK, "got 0x%08x.\n", hr);
2105         }
2106     }
2107     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, ++i);
2108     ok(hr == S_OK, "got 0x%08x.\n", hr);
2109     if(SUCCEEDED(hr))
2110     {
2111         DWORD selected = -1;
2112         UINT j = 0;
2113 
2114         for(j = 0; j < 10; j++)
2115         {
2116             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
2117             ok(hr == S_OK, "got 0x%08x.\n", hr);
2118         }
2119 
2120         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2121         ok(hr == S_OK, "got 0x%08x.\n", hr);
2122         ok(selected == 0, "got %d.\n", selected);
2123 
2124         cdstate = 0xdeadbeef;
2125         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2126         ok(hr == S_OK, "got 0x%08x.\n", hr);
2127         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2128         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
2129         ok(hr == S_OK, "got 0x%08x.\n", hr);
2130         cdstate = 0xdeadbeef;
2131         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2132         ok(hr == S_OK, "got 0x%08x.\n", hr);
2133         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2134         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2135         ok(hr == S_OK, "got 0x%08x.\n", hr);
2136         cdstate = 0xdeadbeef;
2137         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2138         ok(hr == S_OK, "got 0x%08x.\n", hr);
2139         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2140         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, 0);
2141         todo_wine ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2142 
2143         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2144         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2145 
2146         for(j = 0; j < 10; j++)
2147         {
2148             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2149             ok(hr == S_OK, "got 0x%08x.\n", hr);
2150         }
2151     }
2152 
2153     IFileDialogCustomize_Release(pfdc);
2154     ref = IFileDialog_Release(pfod);
2155     ok(!ref, "Refcount not zero (%d).\n", ref);
2156 
2157 
2158     /* Some more tests for VisualGroup behavior */
2159     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2160                           &IID_IFileDialog, (void**)&pfod);
2161     ok(hr == S_OK, "got 0x%08x.\n", hr);
2162 
2163     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
2164     ok(hr == S_OK, "got 0x%08x.\n", hr);
2165 
2166     i = -1;
2167     id_vgroup1 = ++i;
2168     hr = IFileDialogCustomize_StartVisualGroup(pfdc, id_vgroup1, visualgroup1W);
2169     ok(hr == S_OK, "got 0x%08x.\n", hr);
2170 
2171     cdstate = 0xdeadbeef;
2172     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2173     ok(hr == S_OK, "got 0x%08x.\n", hr);
2174     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2175 
2176     id_text = ++i;
2177     hr = IFileDialogCustomize_AddText(pfdc, id_text, label);
2178     ok(hr == S_OK, "got 0x%08x.\n", hr);
2179 
2180     cdstate = 0xdeadbeef;
2181     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2182     ok(hr == S_OK, "got 0x%08x.\n", hr);
2183     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2184 
2185     id_editbox1 = ++i;
2186     hr = IFileDialogCustomize_AddEditBox(pfdc, id_editbox1, editbox1W);
2187     ok(hr == S_OK, "got 0x%08x.\n", hr);
2188 
2189     cdstate = 0xdeadbeef;
2190     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2191     ok(hr == S_OK, "got 0x%08x.\n", hr);
2192     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2193 
2194 
2195     /* Set all Visible but not Enabled */
2196     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_VISIBLE);
2197     ok(hr == S_OK, "got 0x%08x.\n", hr);
2198 
2199     cdstate = 0xdeadbeef;
2200     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2201     ok(hr == S_OK, "got 0x%08x.\n", hr);
2202     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2203     cdstate = 0xdeadbeef;
2204 
2205     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2206     ok(hr == S_OK, "got 0x%08x.\n", hr);
2207     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2208 
2209     cdstate = 0xdeadbeef;
2210     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2211     ok(hr == S_OK, "got 0x%08x.\n", hr);
2212     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2213 
2214     /* Set text to Visible but not Enabled */
2215     hr = IFileDialogCustomize_SetControlState(pfdc, id_text, CDCS_VISIBLE);
2216     ok(hr == S_OK, "got 0x%08x.\n", hr);
2217 
2218     cdstate = 0xdeadbeef;
2219     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2220     ok(hr == S_OK, "got 0x%08x.\n", hr);
2221     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2222     cdstate = 0xdeadbeef;
2223 
2224     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2225     ok(hr == S_OK, "got 0x%08x.\n", hr);
2226     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2227 
2228     cdstate = 0xdeadbeef;
2229     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2230     ok(hr == S_OK, "got 0x%08x.\n", hr);
2231     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2232 
2233     /* Set vgroup to inactive */
2234     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_INACTIVE);
2235     ok(hr == S_OK, "got 0x%08x.\n", hr);
2236 
2237     cdstate = 0xdeadbeef;
2238     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2239     ok(hr == S_OK, "got 0x%08x.\n", hr);
2240     ok(cdstate == CDCS_INACTIVE, "got 0x%08x.\n", cdstate);
2241 
2242     cdstate = 0xdeadbeef;
2243     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2244     ok(hr == S_OK, "got 0x%08x.\n", hr);
2245     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2246 
2247     cdstate = 0xdeadbeef;
2248     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2249     ok(hr == S_OK, "got 0x%08x.\n", hr);
2250     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2251 
2252     /* Set vgroup to Enabled and Visible again */
2253     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_ENABLEDVISIBLE);
2254     ok(hr == S_OK, "got 0x%08x.\n", hr);
2255 
2256     cdstate = 0xdeadbeef;
2257     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2258     ok(hr == S_OK, "got 0x%08x.\n", hr);
2259     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2260 
2261     cdstate = 0xdeadbeef;
2262     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2263     ok(hr == S_OK, "got 0x%08x.\n", hr);
2264     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2265 
2266     cdstate = 0xdeadbeef;
2267     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2268     ok(hr == S_OK, "got 0x%08x.\n", hr);
2269     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2270 
2271     hr = IFileDialogCustomize_MakeProminent(pfdc, id_vgroup1);
2272     ok(hr == S_OK, "got 0x%08x.\n", hr);
2273 
2274     IFileDialogCustomize_Release(pfdc);
2275     ref = IFileDialog_Release(pfod);
2276     ok(!ref, "Refcount not zero (%d).\n", ref);
2277 }
2278 
2279 static void test_persistent_state(void)
2280 {
2281     IFileDialog *fd;
2282     HRESULT hr;
2283 
2284     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2285                           &IID_IFileDialog, (void**)&fd);
2286     ok(hr == S_OK, "got 0x%08x.\n", hr);
2287 
2288 if (0)
2289 {
2290     /* crashes at least on Win8 */
2291     hr = IFileDialog_SetClientGuid(fd, NULL);
2292 }
2293 
2294     hr = IFileDialog_SetClientGuid(fd, &IID_IUnknown);
2295     ok(hr == S_OK, "got 0x%08x\n", hr);
2296 
2297     hr = IFileDialog_SetClientGuid(fd, &IID_NULL);
2298     ok(hr == S_OK, "got 0x%08x\n", hr);
2299 
2300     IFileDialog_Release(fd);
2301 }
2302 
2303 static void test_overwrite(void)
2304 {
2305     static const WCHAR filename_winetest[] = {'w','i','n','e','t','e','s','t','.','o','v','w',0};
2306     IFileDialogEventsImpl *pfdeimpl;
2307     IFileDialogEvents *pfde;
2308     IFileDialog *fd;
2309     DWORD cookie;
2310     LPWSTR filename;
2311     IShellItem *psi_current;
2312     WCHAR buf[MAX_PATH];
2313     HRESULT hr;
2314 
2315     GetCurrentDirectoryW(MAX_PATH, buf);
2316     ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
2317     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
2318     ok(hr == S_OK, "Got 0x%08x\n", hr);
2319 
2320     touch_file(filename_winetest);
2321 
2322     /* FOS_OVERWRITEPROMPT has no effect on open dialog */
2323     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2324                           &IID_IFileDialog, (void**)&fd);
2325     ok(hr == S_OK, "got 0x%08x.\n", hr);
2326 
2327     hr = IFileDialog_SetOptions(fd, FOS_OVERWRITEPROMPT | FOS_NOCHANGEDIR);
2328     ok(hr == S_OK, "got 0x%08x.\n", hr);
2329 
2330     hr = IFileDialog_SetFolder(fd, psi_current);
2331     ok(hr == S_OK, "got 0x%08x.\n", hr);
2332 
2333     pfde = IFileDialogEvents_Constructor();
2334     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2335     pfdeimpl->set_filename = filename_winetest;
2336     hr = IFileDialog_Advise(fd, pfde, &cookie);
2337     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2338 
2339     hr = IFileDialog_Show(fd, NULL);
2340     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2341 
2342     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2343     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2344 
2345     hr = IFileDialog_GetFileName(fd, &filename);
2346     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2347     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2348     CoTaskMemFree(filename);
2349 
2350     hr = IFileDialog_Unadvise(fd, cookie);
2351     ok(hr == S_OK, "got 0x%08x.\n", hr);
2352 
2353     IFileDialog_Release(fd);
2354 
2355     IFileDialogEvents_Release(pfde);
2356 
2357     /* Save dialog doesn't check for overwrite without FOS_OVERWRITEPROMPT set */
2358     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2359                           &IID_IFileDialog, (void**)&fd);
2360     ok(hr == S_OK, "got 0x%08x.\n", hr);
2361 
2362     hr = IFileDialog_SetOptions(fd, FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR);
2363     ok(hr == S_OK, "got 0x%08x.\n", hr);
2364 
2365     hr = IFileDialog_SetFolder(fd, psi_current);
2366     ok(hr == S_OK, "got 0x%08x.\n", hr);
2367 
2368     pfde = IFileDialogEvents_Constructor();
2369     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2370     pfdeimpl->set_filename = filename_winetest;
2371     hr = IFileDialog_Advise(fd, pfde, &cookie);
2372     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2373 
2374     hr = IFileDialog_Show(fd, NULL);
2375     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2376 
2377     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2378     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2379 
2380     hr = IFileDialog_GetFileName(fd, &filename);
2381     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2382     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2383     CoTaskMemFree(filename);
2384 
2385     hr = IFileDialog_Unadvise(fd, cookie);
2386     ok(hr == S_OK, "got 0x%08x.\n", hr);
2387 
2388     IFileDialog_Release(fd);
2389 
2390     IFileDialogEvents_Release(pfde);
2391 
2392     /* Save dialog with FOS_OVERWRITEPROMPT set */
2393     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2394                           &IID_IFileDialog, (void**)&fd);
2395     ok(hr == S_OK, "got 0x%08x.\n", hr);
2396 
2397     hr = IFileDialog_SetFolder(fd, psi_current);
2398     ok(hr == S_OK, "got 0x%08x.\n", hr);
2399 
2400     pfde = IFileDialogEvents_Constructor();
2401     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2402     pfdeimpl->set_filename = filename_winetest;
2403     hr = IFileDialog_Advise(fd, pfde, &cookie);
2404     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2405 
2406     hr = IFileDialog_Show(fd, NULL);
2407     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2408 
2409     ok(pfdeimpl->OnOverwrite == 1, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2410     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2411 
2412     hr = IFileDialog_GetFileName(fd, &filename);
2413     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2414     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2415     CoTaskMemFree(filename);
2416 
2417     hr = IFileDialog_Unadvise(fd, cookie);
2418     ok(hr == S_OK, "got 0x%08x.\n", hr);
2419 
2420     IFileDialog_Release(fd);
2421 
2422     IFileDialogEvents_Release(pfde);
2423 
2424     DeleteFileW(filename_winetest);
2425 
2426     /* Save dialog with FOS_OVERWRITEPROMPT set but without existing file */
2427     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2428                           &IID_IFileDialog, (void**)&fd);
2429     ok(hr == S_OK, "got 0x%08x.\n", hr);
2430 
2431     hr = IFileDialog_SetFolder(fd, psi_current);
2432     ok(hr == S_OK, "got 0x%08x.\n", hr);
2433 
2434     pfde = IFileDialogEvents_Constructor();
2435     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2436     pfdeimpl->set_filename = filename_winetest;
2437     hr = IFileDialog_Advise(fd, pfde, &cookie);
2438     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2439 
2440     hr = IFileDialog_Show(fd, NULL);
2441     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2442 
2443     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2444     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2445 
2446     hr = IFileDialog_GetFileName(fd, &filename);
2447     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2448     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2449     CoTaskMemFree(filename);
2450 
2451     hr = IFileDialog_Unadvise(fd, cookie);
2452     ok(hr == S_OK, "got 0x%08x.\n", hr);
2453 
2454     IFileDialog_Release(fd);
2455 
2456     IFileDialogEvents_Release(pfde);
2457 
2458     IShellItem_Release(psi_current);
2459 }
2460 
2461 START_TEST(itemdlg)
2462 {
2463     OleInitialize(NULL);
2464     init_function_pointers();
2465 
2466     if(test_instantiation())
2467     {
2468         test_basics();
2469         test_advise();
2470         test_events();
2471         test_filename();
2472         test_customize();
2473         test_persistent_state();
2474         test_overwrite();
2475     }
2476     else
2477         skip("Skipping all Item Dialog tests.\n");
2478 
2479     OleUninitialize();
2480 }
2481