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 
540     /* This should work on every platform with IFileDialog */
541     SHGetDesktopFolder(&psfdesktop);
542     hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl);
543     if(SUCCEEDED(hr))
544     {
545         hr = pSHCreateShellItem(NULL, NULL, pidl, &psidesktop);
546         ILFree(pidl);
547     }
548     IShellFolder_Release(psfdesktop);
549     if(FAILED(hr))
550     {
551         skip("Failed to get ShellItem from DesktopFolder, skipping tests.\n");
552         return;
553     }
554 
555 
556     /* Instantiate FileOpenDialog and FileSaveDialog */
557     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
558                           &IID_IFileOpenDialog, (void**)&pfod);
559     ok(hr == S_OK, "got 0x%08x.\n", hr);
560     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
561                           &IID_IFileSaveDialog, (void**)&pfsd);
562     ok(hr == S_OK, "got 0x%08x.\n", hr);
563 
564     /* ClearClientData */
565     todo_wine
566     {
567     hr = IFileOpenDialog_ClearClientData(pfod);
568     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
569     hr = IFileSaveDialog_ClearClientData(pfsd);
570     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
571     }
572 
573     /* GetOptions */
574     hr = IFileOpenDialog_GetOptions(pfod, NULL);
575     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
576     hr = IFileSaveDialog_GetOptions(pfsd, NULL);
577     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
578 
579     /* Check default options */
580     hr = IFileOpenDialog_GetOptions(pfod, &fdoptions);
581     ok(hr == S_OK, "got 0x%08x.\n", hr);
582     ok(fdoptions == (FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR),
583        "Unexpected default options: 0x%08x\n", fdoptions);
584     hr = IFileSaveDialog_GetOptions(pfsd, &fdoptions);
585     ok(hr == S_OK, "got 0x%08x.\n", hr);
586     ok(fdoptions == (FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR),
587        "Unexpected default options: 0x%08x\n", fdoptions);
588 
589     /* GetResult */
590     hr = IFileOpenDialog_GetResult(pfod, NULL);
591     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
592     hr = IFileSaveDialog_GetResult(pfsd, NULL);
593     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
594 
595     psi = (void*)0xdeadbeef;
596     hr = IFileOpenDialog_GetResult(pfod, &psi);
597     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
598     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
599     psi = (void*)0xdeadbeef;
600     hr = IFileSaveDialog_GetResult(pfsd, &psi);
601     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
602     ok(psi == (void*)0xdeadbeef, "got %p.\n", psi);
603 
604     /* GetCurrentSelection */
605     if(0) {
606         /* Crashes on Vista/W2K8. Tests below passes on Windows 7 */
607         hr = IFileOpenDialog_GetCurrentSelection(pfod, NULL);
608         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
609         hr = IFileSaveDialog_GetCurrentSelection(pfsd, NULL);
610         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
611         hr = IFileOpenDialog_GetCurrentSelection(pfod, &psi);
612         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
613         hr = IFileSaveDialog_GetCurrentSelection(pfsd, &psi);
614         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
615     }
616 
617     /* GetFileName */
618     hr = IFileOpenDialog_GetFileName(pfod, NULL);
619     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
620     filename = (void*)0xdeadbeef;
621     hr = IFileOpenDialog_GetFileName(pfod, &filename);
622     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
623     ok(filename == NULL, "got %p\n", filename);
624     hr = IFileSaveDialog_GetFileName(pfsd, NULL);
625     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
626     filename = (void*)0xdeadbeef;
627     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
628     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
629     ok(filename == NULL, "got %p\n", filename);
630 
631     /* GetFileTypeIndex */
632     hr = IFileOpenDialog_GetFileTypeIndex(pfod, NULL);
633     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
634     filetype = 0x12345;
635     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
636     ok(hr == S_OK, "got 0x%08x.\n", hr);
637     ok(filetype == 0, "got %d.\n", filetype);
638     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, NULL);
639     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
640     filetype = 0x12345;
641     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
642     ok(hr == S_OK, "got 0x%08x.\n", hr);
643     ok(filetype == 0, "got %d.\n", filetype);
644 
645     /* SetFileTypes / SetFileTypeIndex */
646     hr = IFileOpenDialog_SetFileTypes(pfod, 0, NULL);
647     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
648     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
649     ok(hr == S_OK, "got 0x%08x.\n", hr);
650 
651     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
652     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
653     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 1);
654     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
655     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
656     ok(hr == S_OK, "got 0x%08x.\n", hr);
657     hr = IFileOpenDialog_SetFileTypes(pfod, 0, filterspec);
658     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
659     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 0);
660     ok(hr == S_OK, "got 0x%08x.\n", hr);
661     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
662     ok(hr == S_OK, "got 0x%08x.\n", hr);
663     ok(filetype == 1, "got %d\n", filetype);
664     hr = IFileOpenDialog_SetFileTypeIndex(pfod, 100);
665     ok(hr == S_OK, "got 0x%08x.\n", hr);
666     hr = IFileOpenDialog_GetFileTypeIndex(pfod, &filetype);
667     ok(hr == S_OK, "got 0x%08x.\n", hr);
668     ok(filetype == 1, "got %d\n", filetype);
669     hr = IFileOpenDialog_SetFileTypes(pfod, 1, filterspec);
670     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
671     hr = IFileOpenDialog_SetFileTypes(pfod, 1, &filterspec[1]);
672     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
673 
674     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
675     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
676     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 1);
677     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
678     hr = IFileSaveDialog_SetFileTypes(pfsd, 2, filterspec);
679     ok(hr == S_OK, "got 0x%08x.\n", hr);
680     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
681     ok(hr == S_OK, "got 0x%08x.\n", hr);
682     /* I hope no one relies on this one */
683     todo_wine ok(filetype == 0, "got %d\n", filetype);
684     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 0);
685     ok(hr == S_OK, "got 0x%08x.\n", hr);
686     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
687     ok(hr == S_OK, "got 0x%08x.\n", hr);
688     ok(filetype == 1, "got %d\n", filetype);
689     hr = IFileSaveDialog_SetFileTypeIndex(pfsd, 100);
690     ok(hr == S_OK, "got 0x%08x.\n", hr);
691     hr = IFileSaveDialog_GetFileTypeIndex(pfsd, &filetype);
692     ok(hr == S_OK, "got 0x%08x.\n", hr);
693     ok(filetype == 2, "got %d\n", filetype);
694     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, filterspec);
695     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
696     hr = IFileSaveDialog_SetFileTypes(pfsd, 1, &filterspec[1]);
697     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
698 
699     /* SetFilter */
700     todo_wine
701     {
702     hr = IFileOpenDialog_SetFilter(pfod, NULL);
703     ok(hr == S_OK, "got 0x%08x.\n", hr);
704     hr = IFileSaveDialog_SetFilter(pfsd, NULL);
705     ok(hr == S_OK, "got 0x%08x.\n", hr);
706     }
707 
708     /* SetFolder */
709     hr = IFileOpenDialog_SetFolder(pfod, NULL);
710     ok(hr == S_OK, "got 0x%08x.\n", hr);
711     hr = IFileSaveDialog_SetFolder(pfsd, NULL);
712     ok(hr == S_OK, "got 0x%08x.\n", hr);
713 
714     /* SetDefaultExtension */
715     hr = IFileOpenDialog_SetDefaultExtension(pfod, NULL);
716     ok(hr == S_OK, "got 0x%08x.\n", hr);
717     hr = IFileOpenDialog_SetDefaultExtension(pfod, txt);
718     ok(hr == S_OK, "got 0x%08x.\n", hr);
719     hr = IFileOpenDialog_SetDefaultExtension(pfod, null);
720     ok(hr == S_OK, "got 0x%08x.\n", hr);
721 
722     hr = IFileSaveDialog_SetDefaultExtension(pfsd, NULL);
723     ok(hr == S_OK, "got 0x%08x.\n", hr);
724     hr = IFileSaveDialog_SetDefaultExtension(pfsd, txt);
725     ok(hr == S_OK, "got 0x%08x.\n", hr);
726     hr = IFileSaveDialog_SetDefaultExtension(pfsd, null);
727     ok(hr == S_OK, "got 0x%08x.\n", hr);
728 
729     /* SetDefaultFolder */
730     hr = IFileOpenDialog_SetDefaultFolder(pfod, NULL);
731     ok(hr == S_OK, "got 0x%08x\n", hr);
732     hr = IFileSaveDialog_SetDefaultFolder(pfsd, NULL);
733     ok(hr == S_OK, "got 0x%08x\n", hr);
734 
735     hr = IFileOpenDialog_SetDefaultFolder(pfod, psidesktop);
736     ok(hr == S_OK, "got 0x%08x\n", hr);
737     hr = IFileSaveDialog_SetDefaultFolder(pfsd, psidesktop);
738     ok(hr == S_OK, "got 0x%08x\n", hr);
739 
740     if(0)
741     {
742         /* Crashes under Windows 7 */
743         IFileOpenDialog_SetDefaultFolder(pfod, (void*)0x1234);
744         IFileSaveDialog_SetDefaultFolder(pfsd, (void*)0x1234);
745     }
746 
747     /* GetFolder / SetFolder */
748     hr = IFileOpenDialog_GetFolder(pfod, NULL);
749     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
750 
751     hr = IFileOpenDialog_GetFolder(pfod, &psi_original);
752     ok(hr == S_OK, "got 0x%08x.\n", hr);
753     if(SUCCEEDED(hr))
754     {
755         hr = IFileOpenDialog_SetFolder(pfod, psidesktop);
756         ok(hr == S_OK, "got 0x%08x.\n", hr);
757         hr = IFileOpenDialog_SetFolder(pfod, psi_original);
758         ok(hr == S_OK, "got 0x%08x.\n", hr);
759         IShellItem_Release(psi_original);
760     }
761 
762     hr = IFileSaveDialog_GetFolder(pfsd, &psi_original);
763     ok(hr == S_OK, "got 0x%08x.\n", hr);
764     if(SUCCEEDED(hr))
765     {
766         hr = IFileSaveDialog_SetFolder(pfsd, psidesktop);
767         ok(hr == S_OK, "got 0x%08x.\n", hr);
768         hr = IFileSaveDialog_SetFolder(pfsd, psi_original);
769         ok(hr == S_OK, "got 0x%08x.\n", hr);
770         IShellItem_Release(psi_original);
771     }
772 
773     /* AddPlace */
774     if(0)
775     {
776         /* Crashes under Windows 7 */
777         IFileOpenDialog_AddPlace(pfod, NULL, 0);
778         IFileSaveDialog_AddPlace(pfsd, NULL, 0);
779     }
780 
781     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP + 1);
782     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
783     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_BOTTOM);
784     ok(hr == S_OK, "got 0x%08x\n", hr);
785     hr = IFileOpenDialog_AddPlace(pfod, psidesktop, FDAP_TOP);
786     ok(hr == S_OK, "got 0x%08x\n", hr);
787 
788     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP + 1);
789     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
790     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_BOTTOM);
791     ok(hr == S_OK, "got 0x%08x\n", hr);
792     hr = IFileSaveDialog_AddPlace(pfsd, psidesktop, FDAP_TOP);
793     ok(hr == S_OK, "got 0x%08x\n", hr);
794 
795     /* SetFileName */
796     hr = IFileOpenDialog_SetFileName(pfod, NULL);
797     ok(hr == S_OK, "got 0x%08x\n", hr);
798     hr = IFileOpenDialog_SetFileName(pfod, null);
799     ok(hr == S_OK, "got 0x%08x\n", hr);
800 
801     filename = NULL;
802     hr = IFileOpenDialog_GetFileName(pfod, &filename);
803     ok(hr == S_OK, "Got 0x%08x\n", hr);
804     ok(!lstrcmpW(filename, null), "Strings do not match.\n");
805     CoTaskMemFree(filename);
806 
807     hr = IFileOpenDialog_SetFileName(pfod, NULL);
808     ok(hr == S_OK, "got 0x%08x\n", hr);
809 
810     filename = (void*)0xdeadbeef;
811     hr = IFileOpenDialog_GetFileName(pfod, &filename);
812     ok(hr == E_FAIL, "Got 0x%08x\n", hr);
813     ok(filename == NULL, "got %p.\n", filename);
814 
815     hr = IFileOpenDialog_SetFileName(pfod, txt);
816     ok(hr == S_OK, "got 0x%08x\n", hr);
817     hr = IFileOpenDialog_GetFileName(pfod, &filename);
818     ok(hr == S_OK, "Got 0x%08x\n", hr);
819     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
820     CoTaskMemFree(filename);
821 
822     hr = IFileSaveDialog_SetFileName(pfsd, NULL);
823     ok(hr == S_OK, "got 0x%08x\n", hr);
824     hr = IFileSaveDialog_SetFileName(pfsd, null);
825     ok(hr == S_OK, "got 0x%08x\n", hr);
826     hr = IFileSaveDialog_SetFileName(pfsd, txt);
827     ok(hr == S_OK, "got 0x%08x\n", hr);
828     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
829     ok(hr == S_OK, "Got 0x%08x\n", hr);
830     ok(!lstrcmpW(filename, txt), "Strings do not match.\n");
831     CoTaskMemFree(filename);
832 
833     /* SetFileNameLabel */
834     hr = IFileOpenDialog_SetFileNameLabel(pfod, NULL);
835     ok(hr == S_OK, "got 0x%08x\n", hr);
836     hr = IFileOpenDialog_SetFileNameLabel(pfod, null);
837     ok(hr == S_OK, "got 0x%08x\n", hr);
838     hr = IFileOpenDialog_SetFileNameLabel(pfod, txt);
839     ok(hr == S_OK, "got 0x%08x\n", hr);
840 
841     hr = IFileSaveDialog_SetFileNameLabel(pfsd, NULL);
842     ok(hr == S_OK, "got 0x%08x\n", hr);
843     hr = IFileSaveDialog_SetFileNameLabel(pfsd, null);
844     ok(hr == S_OK, "got 0x%08x\n", hr);
845     hr = IFileSaveDialog_SetFileNameLabel(pfsd, txt);
846     ok(hr == S_OK, "got 0x%08x\n", hr);
847 
848     /* Close */
849     hr = IFileOpenDialog_Close(pfod, S_FALSE);
850     ok(hr == S_OK, "got 0x%08x\n", hr);
851     hr = IFileSaveDialog_Close(pfsd, S_FALSE);
852     ok(hr == S_OK, "got 0x%08x\n", hr);
853 
854     /* SetOkButtonLabel */
855     hr = IFileOpenDialog_SetOkButtonLabel(pfod, NULL);
856     ok(hr == S_OK, "got 0x%08x\n", hr);
857     hr = IFileOpenDialog_SetOkButtonLabel(pfod, null);
858     ok(hr == S_OK, "got 0x%08x\n", hr);
859     hr = IFileOpenDialog_SetOkButtonLabel(pfod, txt);
860     ok(hr == S_OK, "got 0x%08x\n", hr);
861     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, NULL);
862     ok(hr == S_OK, "got 0x%08x\n", hr);
863     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, null);
864     ok(hr == S_OK, "got 0x%08x\n", hr);
865     hr = IFileSaveDialog_SetOkButtonLabel(pfsd, txt);
866     ok(hr == S_OK, "got 0x%08x\n", hr);
867 
868     /* SetTitle */
869     hr = IFileOpenDialog_SetTitle(pfod, NULL);
870     ok(hr == S_OK, "got 0x%08x\n", hr);
871     hr = IFileOpenDialog_SetTitle(pfod, null);
872     ok(hr == S_OK, "got 0x%08x\n", hr);
873     hr = IFileOpenDialog_SetTitle(pfod, txt);
874     ok(hr == S_OK, "got 0x%08x\n", hr);
875     hr = IFileSaveDialog_SetTitle(pfsd, NULL);
876     ok(hr == S_OK, "got 0x%08x\n", hr);
877     hr = IFileSaveDialog_SetTitle(pfsd, null);
878     ok(hr == S_OK, "got 0x%08x\n", hr);
879     hr = IFileSaveDialog_SetTitle(pfsd, txt);
880     ok(hr == S_OK, "got 0x%08x\n", hr);
881 
882     /** IFileOpenDialog specific **/
883 
884     /* GetResults */
885     if(0)
886     {
887         /* Crashes under Windows 7 */
888         IFileOpenDialog_GetResults(pfod, NULL);
889     }
890     psia = (void*)0xdeadbeef;
891     hr = IFileOpenDialog_GetResults(pfod, &psia);
892     ok(hr == E_FAIL, "got 0x%08x.\n", hr);
893     ok(psia == NULL, "got %p.\n", psia);
894 
895     /* GetSelectedItems */
896     if(0)
897     {
898         /* Crashes under W2K8 */
899         hr = IFileOpenDialog_GetSelectedItems(pfod, NULL);
900         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
901         psia = (void*)0xdeadbeef;
902         hr = IFileOpenDialog_GetSelectedItems(pfod, &psia);
903         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
904         ok(psia == (void*)0xdeadbeef, "got %p.\n", psia);
905     }
906 
907     /** IFileSaveDialog specific **/
908 
909     /* ApplyProperties */
910     if(0)
911     {
912         /* Crashes under windows 7 */
913         IFileSaveDialog_ApplyProperties(pfsd, NULL, NULL, NULL, NULL);
914         IFileSaveDialog_ApplyProperties(pfsd, psidesktop, NULL, NULL, NULL);
915     }
916 
917     /* GetProperties */
918     hr = IFileSaveDialog_GetProperties(pfsd, NULL);
919     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
920     pps = (void*)0xdeadbeef;
921     hr = IFileSaveDialog_GetProperties(pfsd, &pps);
922     todo_wine ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
923     ok(pps == (void*)0xdeadbeef, "got %p\n", pps);
924 
925     /* SetProperties */
926     if(0)
927     {
928         /* Crashes under W2K8 */
929         hr = IFileSaveDialog_SetProperties(pfsd, NULL);
930         ok(hr == S_OK, "got 0x%08x\n", hr);
931     }
932 
933     /* SetCollectedProperties */
934     todo_wine
935     {
936     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, TRUE);
937     ok(hr == S_OK, "got 0x%08x\n", hr);
938     hr = IFileSaveDialog_SetCollectedProperties(pfsd, NULL, FALSE);
939     ok(hr == S_OK, "got 0x%08x\n", hr);
940     }
941 
942     /* SetSaveAsItem */
943     todo_wine
944     {
945     hr = IFileSaveDialog_SetSaveAsItem(pfsd, NULL);
946     ok(hr == S_OK, "got 0x%08x\n", hr);
947     hr = IFileSaveDialog_SetSaveAsItem(pfsd, psidesktop);
948     ok(hr == MK_E_NOOBJECT, "got 0x%08x\n", hr);
949     }
950 
951     /** IFileDialog2 **/
952 
953     hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialog2, (void**)&pfd2);
954     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
955     if(SUCCEEDED(hr))
956     {
957         /* SetCancelButtonLabel */
958         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
959         ok(hr == S_OK, "got 0x%08x\n", hr);
960         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
961         ok(hr == S_OK, "got 0x%08x\n", hr);
962         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
963         ok(hr == S_OK, "got 0x%08x\n", hr);
964 
965         /* SetNavigationRoot */
966         todo_wine
967         {
968         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
969         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
970         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
971         ok(hr == S_OK, "got 0x%08x\n", hr);
972         }
973 
974         IFileDialog2_Release(pfd2);
975     }
976 
977     hr = IFileSaveDialog_QueryInterface(pfsd, &IID_IFileDialog2, (void**)&pfd2);
978     ok((hr == S_OK) || broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
979     if(SUCCEEDED(hr))
980     {
981         /* SetCancelButtonLabel */
982         hr = IFileDialog2_SetOkButtonLabel(pfd2, NULL);
983         ok(hr == S_OK, "got 0x%08x\n", hr);
984         hr = IFileDialog2_SetOkButtonLabel(pfd2, null);
985         ok(hr == S_OK, "got 0x%08x\n", hr);
986         hr = IFileDialog2_SetOkButtonLabel(pfd2, txt);
987         ok(hr == S_OK, "got 0x%08x\n", hr);
988 
989         /* SetNavigationRoot */
990         todo_wine
991         {
992         hr = IFileDialog2_SetNavigationRoot(pfd2, NULL);
993         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
994         hr = IFileDialog2_SetNavigationRoot(pfd2, psidesktop);
995         ok(hr == S_OK, "got 0x%08x\n", hr);
996         }
997 
998         IFileDialog2_Release(pfd2);
999     }
1000 
1001     /* Cleanup */
1002     IShellItem_Release(psidesktop);
1003     ref = IFileOpenDialog_Release(pfod);
1004     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1005     ref = IFileSaveDialog_Release(pfsd);
1006     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1007 }
1008 
1009 static void ensure_zero_events_(const char *file, int line, IFileDialogEventsImpl *impl)
1010 {
1011     ok_(file, line)(!impl->OnFileOk, "OnFileOk: %d\n", impl->OnFileOk);
1012     ok_(file, line)(!impl->OnFolderChanging, "OnFolderChanging: %d\n", impl->OnFolderChanging);
1013     ok_(file, line)(!impl->OnFolderChange, "OnFolderChange: %d\n", impl->OnFolderChange);
1014     ok_(file, line)(!impl->OnSelectionChange, "OnSelectionChange: %d\n", impl->OnSelectionChange);
1015     ok_(file, line)(!impl->OnShareViolation, "OnShareViolation: %d\n", impl->OnShareViolation);
1016     ok_(file, line)(!impl->OnTypeChange, "OnTypeChange: %d\n", impl->OnTypeChange);
1017     ok_(file, line)(!impl->OnOverwrite, "OnOverwrite: %d\n", impl->OnOverwrite);
1018     impl->OnFileOk = impl->OnFolderChanging = impl->OnFolderChange = 0;
1019     impl->OnSelectionChange = impl->OnShareViolation = impl->OnTypeChange = 0;
1020     impl->OnOverwrite = 0;
1021 }
1022 #define ensure_zero_events(impl) ensure_zero_events_(__FILE__, __LINE__, impl)
1023 
1024 static void test_advise_helper(IFileDialog *pfd)
1025 {
1026     IFileDialogEventsImpl *pfdeimpl;
1027     IFileDialogEvents *pfde;
1028     DWORD cookie[10];
1029     UINT i;
1030     HRESULT hr;
1031 
1032     pfde = IFileDialogEvents_Constructor();
1033     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1034 
1035     hr = IFileDialog_Advise(pfd, NULL, NULL);
1036     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1037     hr = IFileDialog_Advise(pfd, pfde, NULL);
1038     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1039     hr = IFileDialog_Advise(pfd, NULL, &cookie[0]);
1040     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1041     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1042     ensure_zero_events(pfdeimpl);
1043 
1044     hr = IFileDialog_Unadvise(pfd, 0);
1045     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1046     for(i = 0; i < 10; i++) {
1047         hr = IFileDialog_Advise(pfd, pfde, &cookie[i]);
1048         ok(hr == S_OK, "got 0x%08x\n", hr);
1049         ok(cookie[i] == i+1, "Got cookie: %d\n", cookie[i]);
1050     }
1051     ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
1052     ensure_zero_events(pfdeimpl);
1053 
1054     for(i = 3; i < 7; i++) {
1055         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1056         ok(hr == S_OK, "got 0x%08x\n", hr);
1057     }
1058     ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref);
1059     ensure_zero_events(pfdeimpl);
1060 
1061     for(i = 0; i < 3; i++) {
1062         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1063         ok(hr == S_OK, "got 0x%08x\n", hr);
1064     }
1065     ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref);
1066     ensure_zero_events(pfdeimpl);
1067 
1068     for(i = 7; i < 10; i++) {
1069         hr = IFileDialog_Unadvise(pfd, cookie[i]);
1070         ok(hr == S_OK, "got 0x%08x\n", hr);
1071     }
1072     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1073     ensure_zero_events(pfdeimpl);
1074 
1075     hr = IFileDialog_Unadvise(pfd, cookie[9]+1);
1076     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1077     ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
1078     ensure_zero_events(pfdeimpl);
1079 
1080     hr = IFileDialog_Advise(pfd, pfde, &cookie[0]);
1081     ok(hr == S_OK, "got 0x%08x\n", hr);
1082     todo_wine ok(cookie[0] == 1, "got cookie: %d\n", cookie[0]);
1083     ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref);
1084     ensure_zero_events(pfdeimpl);
1085 
1086     hr = IFileDialog_Unadvise(pfd, cookie[0]);
1087 
1088     if(0)
1089     {
1090         /* Unadvising already unadvised cookies crashes on
1091            Windows 7. */
1092         IFileDialog_Unadvise(pfd, cookie[0]);
1093     }
1094 
1095 
1096     IFileDialogEvents_Release(pfde);
1097 }
1098 
1099 static void test_advise(void)
1100 {
1101     IFileDialog *pfd;
1102     HRESULT hr;
1103     LONG ref;
1104 
1105     trace("Testing FileOpenDialog (advise)\n");
1106     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1107                           &IID_IFileDialog, (void**)&pfd);
1108     ok(hr == S_OK, "got 0x%08x.\n", hr);
1109     test_advise_helper(pfd);
1110     ref = IFileDialog_Release(pfd);
1111     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1112 
1113     trace("Testing FileSaveDialog (advise)\n");
1114     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
1115                           &IID_IFileDialog, (void**)&pfd);
1116     ok(hr == S_OK, "got 0x%08x.\n", hr);
1117     test_advise_helper(pfd);
1118     ref = IFileDialog_Release(pfd);
1119     ok(!ref, "Got refcount %d, should have been released.\n", ref);
1120 }
1121 
1122 static void filedialog_change_filetype(IFileDialog *pfd, HWND dlg_hwnd)
1123 {
1124     HWND cb_filetype;
1125     const WCHAR filetype1[] = {'f','n','a','m','e','1',0};
1126     const WCHAR filetype1_broken[] = {'f','n','a','m','e','1',' ', '(','*','.','t','x','t',')',0};
1127 
1128     cb_filetype = find_window(dlg_hwnd, NULL, filetype1);
1129     ok(cb_filetype != NULL || broken(cb_filetype == NULL), "Could not find combobox on first attempt\n");
1130 
1131     if(!cb_filetype)
1132     {
1133         /* Not sure when this happens. Some specific version?
1134          * Seen on 32-bit English Vista */
1135         trace("Didn't find combobox on first attempt, trying broken string..\n");
1136         cb_filetype = find_window(dlg_hwnd, NULL, filetype1_broken);
1137         ok(broken(cb_filetype != NULL), "Failed to find combobox on second attempt\n");
1138         if(!cb_filetype)
1139             return;
1140     }
1141 
1142     /* Making the combobox send a CBN_SELCHANGE */
1143     SendMessageW( cb_filetype, CB_SHOWDROPDOWN, 1, 0 );
1144     SendMessageW( cb_filetype, CB_SETCURSEL, 1, 0 );
1145     SendMessageW( cb_filetype, WM_LBUTTONDOWN, 0, -1 );
1146     SendMessageW( cb_filetype, WM_LBUTTONUP, 0, -1 );
1147 }
1148 
1149 static void test_events(void)
1150 {
1151     IFileDialog *pfd;
1152     IFileDialogEventsImpl *pfdeimpl;
1153     IFileDialogEvents *pfde;
1154     DWORD cookie;
1155     ULONG ref;
1156     HRESULT hr;
1157     const WCHAR fname1[] = {'f','n','a','m','e','1', 0};
1158     const WCHAR fspec1[] = {'*','.','t','x','t',0};
1159     const WCHAR fname2[] = {'f','n','a','m','e','2', 0};
1160     const WCHAR fspec2[] = {'*','.','e','x','e',0};
1161     COMDLG_FILTERSPEC filterspec[3] = {{fname1, fspec1}, {fname2, fspec2}};
1162 
1163 
1164     /*
1165      * 1. Show the dialog with no filetypes added
1166      */
1167     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1168                           &IID_IFileDialog, (void**)&pfd);
1169     ok(hr == S_OK, "got 0x%08x.\n", hr);
1170 
1171     pfde = IFileDialogEvents_Constructor();
1172     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1173     pfdeimpl->events_test = IFDEVENT_TEST2;
1174 
1175     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1176     ok(hr == S_OK, "got 0x%08x.\n", hr);
1177 
1178     hr = IFileDialog_Show(pfd, NULL);
1179     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1180 
1181     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1182     pfdeimpl->OnFolderChanging = 0;
1183     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1184     pfdeimpl->OnFolderChange = 0;
1185     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1186     pfdeimpl->OnSelectionChange = 0;
1187     ok(pfdeimpl->OnTypeChange == 0, "Got %d\n", pfdeimpl->OnTypeChange);
1188     pfdeimpl->OnTypeChange = 0;
1189 
1190     ensure_zero_events(pfdeimpl);
1191 
1192     hr = IFileDialog_Unadvise(pfd, cookie);
1193     ok(hr == S_OK, "got 0x%08x.\n", hr);
1194 
1195     IFileDialogEvents_Release(pfde);
1196     ref = IFileDialog_Release(pfd);
1197     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1198 
1199 
1200     /*
1201      * 2. Show the dialog with filetypes added
1202      */
1203     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1204                           &IID_IFileDialog, (void**)&pfd);
1205     ok(hr == S_OK, "got 0x%08x.\n", hr);
1206 
1207     pfde = IFileDialogEvents_Constructor();
1208     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1209     pfdeimpl->events_test = IFDEVENT_TEST2;
1210 
1211     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1212     ok(hr == S_OK, "got 0x%08x.\n", hr);
1213 
1214     hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
1215     ok(hr == S_OK, "got 0x%08x.\n", hr);
1216 
1217     ensure_zero_events(pfdeimpl);
1218 
1219     hr = IFileDialog_Show(pfd, NULL);
1220     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1221 
1222     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1223     pfdeimpl->OnFolderChanging = 0;
1224     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1225     pfdeimpl->OnFolderChange = 0;
1226     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1227     pfdeimpl->OnSelectionChange = 0;
1228     /* Called once just by showing the dialog */
1229     ok(pfdeimpl->OnTypeChange == 1, "Got %d\n", pfdeimpl->OnTypeChange);
1230     pfdeimpl->OnTypeChange = 0;
1231 
1232     ensure_zero_events(pfdeimpl);
1233 
1234     hr = IFileDialog_Unadvise(pfd, cookie);
1235     ok(hr == S_OK, "got 0x%08x.\n", hr);
1236 
1237     IFileDialogEvents_Release(pfde);
1238     ref = IFileDialog_Release(pfd);
1239     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1240 
1241 
1242     /*
1243      * 3. Show the dialog with filetypes added and simulate manual change of filetype
1244      */
1245     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1246                           &IID_IFileDialog, (void**)&pfd);
1247     ok(hr == S_OK, "got 0x%08x.\n", hr);
1248 
1249     pfde = IFileDialogEvents_Constructor();
1250     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1251     pfdeimpl->events_test = IFDEVENT_TEST3;
1252 
1253     hr = IFileDialog_Advise(pfd, pfde, &cookie);
1254     ok(hr == S_OK, "got 0x%08x.\n", hr);
1255 
1256     hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
1257     ok(hr == S_OK, "got 0x%08x.\n", hr);
1258 
1259     ensure_zero_events(pfdeimpl);
1260 
1261     hr = IFileDialog_Show(pfd, NULL);
1262     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
1263 
1264     ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
1265     pfdeimpl->OnFolderChanging = 0;
1266     ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
1267     pfdeimpl->OnFolderChange = 0;
1268     /* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
1269     pfdeimpl->OnSelectionChange = 0;
1270     /* Called once by showing the dialog and once again when changing the filetype */
1271     todo_wine ok(pfdeimpl->OnTypeChange == 2, "Got %d\n", pfdeimpl->OnTypeChange);
1272     pfdeimpl->OnTypeChange = 0;
1273 
1274     ensure_zero_events(pfdeimpl);
1275 
1276     hr = IFileDialog_Unadvise(pfd, cookie);
1277     ok(hr == S_OK, "got 0x%08x.\n", hr);
1278 
1279     IFileDialogEvents_Release(pfde);
1280     ref = IFileDialog_Release(pfd);
1281     ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
1282 }
1283 
1284 static void touch_file(LPCWSTR filename)
1285 {
1286     HANDLE file;
1287     file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1288     ok(file != INVALID_HANDLE_VALUE, "Failed to create file.\n");
1289     CloseHandle(file);
1290 }
1291 
1292 static void test_filename_savedlg_(LPCWSTR set_filename, LPCWSTR defext,
1293                                    const COMDLG_FILTERSPEC *filterspec, UINT fs_count,
1294                                    LPCWSTR exp_filename, const char *file, int line)
1295 {
1296     IFileSaveDialog *pfsd;
1297     IFileDialogEventsImpl *pfdeimpl;
1298     IFileDialogEvents *pfde;
1299     DWORD cookie;
1300     LPWSTR filename;
1301     IShellItem *psi;
1302     LONG ref;
1303     HRESULT hr;
1304 
1305     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
1306                           &IID_IFileSaveDialog, (void**)&pfsd);
1307     ok_(file,line)(hr == S_OK, "Got 0x%08x\n", hr);
1308 
1309     if(fs_count)
1310     {
1311         hr = IFileSaveDialog_SetFileTypes(pfsd, fs_count, filterspec);
1312         ok_(file,line)(hr == S_OK, "SetFileTypes failed: Got 0x%08x\n", hr);
1313     }
1314 
1315     if(defext)
1316     {
1317         hr = IFileSaveDialog_SetDefaultExtension(pfsd, defext);
1318         ok_(file,line)(hr == S_OK, "SetDefaultExtensions failed: Got 0x%08x\n", hr);
1319     }
1320 
1321     pfde = IFileDialogEvents_Constructor();
1322     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1323     pfdeimpl->set_filename = set_filename;
1324     hr = IFileSaveDialog_Advise(pfsd, pfde, &cookie);
1325     ok_(file,line)(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
1326 
1327     hr = IFileSaveDialog_Show(pfsd, NULL);
1328     ok_(file,line)(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
1329 
1330     hr = IFileSaveDialog_GetFileName(pfsd, &filename);
1331     ok_(file,line)(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
1332     ok_(file,line)(!lstrcmpW(filename, set_filename), "Got %s\n", wine_dbgstr_w(filename));
1333     CoTaskMemFree(filename);
1334 
1335     hr = IFileSaveDialog_GetResult(pfsd, &psi);
1336     ok_(file,line)(hr == S_OK, "GetResult failed: Got 0x%08x\n", hr);
1337 
1338     hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1339     ok_(file,line)(hr == S_OK, "GetDisplayName failed: Got 0x%08x\n", hr);
1340     ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetDisplayName) Got %s\n", wine_dbgstr_w(filename));
1341     CoTaskMemFree(filename);
1342     IShellItem_Release(psi);
1343 
1344     hr = IFileSaveDialog_Unadvise(pfsd, cookie);
1345     ok_(file,line)(hr == S_OK, "Unadvise failed: Got 0x%08x\n", hr);
1346 
1347     ref = IFileSaveDialog_Release(pfsd);
1348     ok_(file,line)(!ref, "Got refcount %d, should have been released.\n", ref);
1349 
1350     IFileDialogEvents_Release(pfde);
1351 }
1352 #define test_filename_savedlg(set_filename, defext, filterspec, fs_count, exp_filename) \
1353     test_filename_savedlg_(set_filename, defext, filterspec, fs_count, exp_filename, __FILE__, __LINE__)
1354 
1355 static void test_filename_opendlg_(LPCWSTR set_filename, IShellItem *psi_current, LPCWSTR defext,
1356                                    const COMDLG_FILTERSPEC *filterspec, UINT fs_count,
1357                                    LPCWSTR exp_filename, const char *file, int line)
1358 {
1359     IFileOpenDialog *pfod;
1360     IFileDialogEventsImpl *pfdeimpl;
1361     IFileDialogEvents *pfde;
1362     DWORD cookie;
1363     LPWSTR filename;
1364     IShellItemArray *psia;
1365     IShellItem *psi;
1366     LONG ref;
1367     HRESULT hr;
1368 
1369     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1370                           &IID_IFileOpenDialog, (void**)&pfod);
1371     ok_(file,line)(hr == S_OK, "CoCreateInstance failed: Got 0x%08x\n", hr);
1372 
1373     if(defext)
1374     {
1375         hr = IFileOpenDialog_SetDefaultExtension(pfod, defext);
1376         ok_(file,line)(hr == S_OK, "SetDefaultExtensions failed: Got 0x%08x\n", hr);
1377     }
1378 
1379     if(fs_count)
1380     {
1381         hr = IFileOpenDialog_SetFileTypes(pfod, 2, filterspec);
1382         ok_(file,line)(hr == S_OK, "SetFileTypes failed: Got 0x%08x\n", hr);
1383     }
1384 
1385     hr = IFileOpenDialog_SetFolder(pfod, psi_current);
1386     ok_(file,line)(hr == S_OK, "SetFolder failed: Got 0x%08x\n", hr);
1387 
1388     pfde = IFileDialogEvents_Constructor();
1389     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1390     pfdeimpl->set_filename = set_filename;
1391     pfdeimpl->set_filename_tried = FALSE;
1392     hr = IFileOpenDialog_Advise(pfod, pfde, &cookie);
1393     ok_(file,line)(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
1394 
1395     hr = IFileOpenDialog_Show(pfod, NULL);
1396     ok_(file,line)(hr == S_OK || (!exp_filename && hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)),
1397                    "Show failed: Got 0x%08x\n", hr);
1398     if(hr == S_OK)
1399     {
1400         hr = IFileOpenDialog_GetResult(pfod, &psi);
1401         ok_(file,line)(hr == S_OK, "GetResult failed: Got 0x%08x\n", hr);
1402 
1403         hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1404         ok_(file,line)(hr == S_OK, "GetDisplayName(Result) failed: Got 0x%08x\n", hr);
1405         ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetResult) Got %s\n", wine_dbgstr_w(filename));
1406         CoTaskMemFree(filename);
1407         IShellItem_Release(psi);
1408 
1409         hr = IFileOpenDialog_GetResults(pfod, &psia);
1410         ok_(file,line)(hr == S_OK, "GetResults failed: Got 0x%08x\n", hr);
1411         hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1412         ok_(file,line)(hr == S_OK, "GetItemAt failed: Got 0x%08x\n", hr);
1413 
1414         hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
1415         ok_(file,line)(hr == S_OK, "GetDisplayName(Results) failed: Got 0x%08x\n", hr);
1416         ok_(file,line)(!lstrcmpW(filename, exp_filename), "(GetResults) Got %s\n", wine_dbgstr_w(filename));
1417         CoTaskMemFree(filename);
1418 
1419         IShellItem_Release(psi);
1420         IShellItemArray_Release(psia);
1421     }
1422     else
1423     {
1424         hr = IFileOpenDialog_GetResult(pfod, &psi);
1425         ok_(file,line)(hr == E_UNEXPECTED, "GetResult: Got 0x%08x\n", hr);
1426 
1427         hr = IFileOpenDialog_GetResults(pfod, &psia);
1428         ok_(file,line)(hr == E_FAIL, "GetResults: Got 0x%08x\n", hr);
1429     }
1430 
1431     hr = IFileOpenDialog_GetFileName(pfod, &filename);
1432     ok_(file,line)(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
1433     ok_(file,line)(!lstrcmpW(filename, set_filename), "(GetFileName) Got %s\n", wine_dbgstr_w(filename));
1434     CoTaskMemFree(filename);
1435 
1436 
1437     hr = IFileOpenDialog_Unadvise(pfod, cookie);
1438     ok_(file,line)(hr == S_OK, "Unadvise failed: Got 0x%08x\n", hr);
1439 
1440     ref = IFileOpenDialog_Release(pfod);
1441     ok_(file,line)(!ref, "Got refcount %d, should have been released.\n", ref);
1442 
1443     IFileDialogEvents_Release(pfde);
1444 }
1445 #define test_filename_opendlg(set_filename, psi, defext, filterspec, fs_count, exp_filename) \
1446     test_filename_opendlg_(set_filename, psi, defext, filterspec, fs_count, exp_filename, __FILE__, __LINE__)
1447 
1448 static void test_filename(void)
1449 {
1450     IShellItem *psi_current;
1451     HRESULT hr;
1452     WCHAR buf[MAX_PATH];
1453 
1454     static const WCHAR filename_noextW[] = {'w','i','n','e','t','e','s','t',0};
1455     static const WCHAR filename_dotextW[] = {'w','i','n','e','t','e','s','t','.',0};
1456     static const WCHAR filename_dotanddefW[] = {'w','i','n','e','t','e','s','t','.','.','w','t','e',0};
1457     static const WCHAR filename_defextW[] = {'w','i','n','e','t','e','s','t','.','w','t','e',0};
1458     static const WCHAR filename_ext1W[] = {'w','i','n','e','t','e','s','t','.','w','t','1',0};
1459     static const WCHAR filename_ext2W[] = {'w','i','n','e','t','e','s','t','.','w','t','2',0};
1460     static const WCHAR filename_ext1anddefW[] =
1461         {'w','i','n','e','t','e','s','t','.','w','t','1','.','w','t','e',0};
1462     static const WCHAR defextW[] = {'w','t','e',0};
1463     static const WCHAR desc1[] = {'d','e','s','c','r','i','p','t','i','o','n','1',0};
1464     static const WCHAR desc2[] = {'d','e','s','c','r','i','p','t','i','o','n','2',0};
1465     static const WCHAR descdef[] = {'d','e','f','a','u','l','t',' ','d','e','s','c',0};
1466     static const WCHAR ext1[] = {'*','.','w','t','1',0};
1467     static const WCHAR ext2[] = {'*','.','w','t','2',0};
1468     static const WCHAR extdef[] = {'*','.','w','t','e',0};
1469     static const WCHAR complexext[] = {'*','.','w','t','2',';','*','.','w','t','1',0};
1470 
1471     static const COMDLG_FILTERSPEC filterspec[] = {
1472         { desc1, ext1 }, { desc2, ext2 }, { descdef, extdef }
1473     };
1474     static const COMDLG_FILTERSPEC filterspec2[] = {
1475         { desc1, complexext }
1476     };
1477 
1478     /* No extension */
1479     test_filename_savedlg(filename_noextW, NULL, NULL, 0, filename_noextW);
1480     /* Default extension */
1481     test_filename_savedlg(filename_noextW, defextW, NULL, 0, filename_defextW);
1482     /* Default extension on filename ending with a . */
1483     test_filename_savedlg(filename_dotextW, defextW, NULL, 0, filename_dotanddefW);
1484     /* Default extension on filename with default extension */
1485     test_filename_savedlg(filename_defextW, defextW, NULL, 0, filename_defextW);
1486     /* Default extension on filename with another extension */
1487     test_filename_savedlg(filename_ext1W, defextW, NULL, 0, filename_ext1anddefW);
1488     /* Default extension, filterspec without default extension */
1489     test_filename_savedlg(filename_noextW, defextW, filterspec, 2, filename_ext1W);
1490     /* Default extension, filterspec with default extension */
1491     test_filename_savedlg(filename_noextW, defextW, filterspec, 3, filename_ext1W);
1492     /* Default extension, filterspec with "complex" extension */
1493     test_filename_savedlg(filename_noextW, defextW, filterspec2, 1, filename_ext2W);
1494 
1495     GetCurrentDirectoryW(MAX_PATH, buf);
1496     ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
1497     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
1498     ok(hr == S_OK, "Got 0x%08x\n", hr);
1499 
1500     touch_file(filename_noextW);
1501     touch_file(filename_defextW);
1502     touch_file(filename_ext2W);
1503 
1504     /* IFileOpenDialog, default extension */
1505     test_filename_opendlg(filename_noextW, psi_current, defextW, NULL, 0, filename_noextW);
1506     /* IFileOpenDialog, default extension and filterspec */
1507     test_filename_opendlg(filename_noextW, psi_current, defextW, filterspec, 2, filename_noextW);
1508 
1509     DeleteFileW(filename_noextW);
1510     /* IFileOpenDialog, default extension, noextW deleted */
1511     test_filename_opendlg(filename_noextW, psi_current, defextW, NULL, 0, filename_defextW);
1512     if(0) /* Interactive */
1513     {
1514     /* IFileOpenDialog, filterspec, no default extension, noextW deleted */
1515     test_filename_opendlg(filename_noextW, psi_current, NULL, filterspec, 2, NULL);
1516     }
1517 
1518     IShellItem_Release(psi_current);
1519     DeleteFileW(filename_defextW);
1520     DeleteFileW(filename_ext2W);
1521 }
1522 
1523 static const WCHAR label[] = {'l','a','b','e','l',0};
1524 static const WCHAR label2[] = {'t','e','s','t',0};
1525 static const WCHAR menuW[] = {'m','e','n','u','_','i','t','e','m',0};
1526 static const WCHAR pushbutton1W[] = {'p','u','s','h','b','u','t','t','o','n','_','i','t','e','m',0};
1527 static const WCHAR pushbutton2W[] = {'p','u','s','h','b','u','t','t','o','n','2','_','i','t','e','m',0};
1528 static const WCHAR comboboxitem1W[] = {'c','o','m','b','o','b','o','x','1','_','i','t','e','m',0};
1529 static const WCHAR comboboxitem2W[] = {'c','o','m','b','o','b','o','x','2','_','i','t','e','m',0};
1530 static const WCHAR radiobutton1W[] = {'r','a','d','i','o','b','u','t','t','o','n','1','_','i','t','e','m',0};
1531 static const WCHAR radiobutton2W[] = {'r','a','d','i','o','b','u','t','t','o','n','2','_','i','t','e','m',0};
1532 static const WCHAR checkbutton1W[] = {'c','h','e','c','k','b','u','t','t','o','n','1','_','i','t','e','m',0};
1533 static const WCHAR checkbutton2W[] = {'c','h','e','c','k','b','u','t','t','o','n','2','_','i','t','e','m',0};
1534 static const WCHAR editbox1W[] = {'e','d','i','t','b','o','x','W','1','_','i','t','e','m',0};
1535 static const WCHAR editbox2W[] = {'e','d','i','t','b','o','x','W','2','_','i','t','e','m',0};
1536 static const WCHAR textW[] = {'t','e','x','t','_','i','t','e','m',0};
1537 static const WCHAR text2W[] = {'t','e','x','t','2','_','i','t','e','m',0};
1538 static const WCHAR separatorW[] = {'s','e','p','a','r','a','t','o','r','_','i','t','e','m',0};
1539 static const WCHAR visualgroup1W[] = {'v','i','s','u','a','l','g','r','o','u','p','1',0};
1540 static const WCHAR visualgroup2W[] = {'v','i','s','u','a','l','g','r','o','u','p','2',0};
1541 
1542 static const WCHAR floatnotifysinkW[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};
1543 static const WCHAR RadioButtonListW[] = {'R','a','d','i','o','B','u','t','t','o','n','L','i','s','t',0};
1544 
1545 static void test_customize_onfolderchange(IFileDialog *pfd)
1546 {
1547     HWND dlg_hwnd, item, item_parent;
1548     BOOL br;
1549     WCHAR buf[1024];
1550 
1551     buf[0] = '\0';
1552 
1553     dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
1554     ok(dlg_hwnd != NULL, "Got NULL.\n");
1555 
1556     item = find_window(dlg_hwnd, NULL, checkbutton2W);
1557     ok(item != NULL, "Failed to find item.\n");
1558     item_parent = GetParent(item);
1559     GetClassNameW(item_parent, buf, 1024);
1560     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1561     item = find_window(dlg_hwnd, NULL, text2W);
1562     ok(item != NULL, "Failed to find item.\n");
1563     item_parent = GetParent(item);
1564     GetClassNameW(item_parent, buf, 1024);
1565     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1566     item = find_window(dlg_hwnd, NULL, radiobutton1W);
1567     ok(item != NULL, "Failed to find item.\n");
1568     item_parent = GetParent(item);
1569     GetClassNameW(item_parent, buf, 1024);
1570     ok(!lstrcmpW(buf, RadioButtonListW), "Got %s\n", wine_dbgstr_w(buf));
1571     item_parent = GetParent(item_parent);
1572     GetClassNameW(item_parent, buf, 1024);
1573     ok(!lstrcmpW(buf, floatnotifysinkW), "Got %s\n", wine_dbgstr_w(buf));
1574 
1575     item = find_window(dlg_hwnd, NULL, pushbutton1W);
1576     ok(item == NULL, "Found item: %p\n", item);
1577     item = find_window(dlg_hwnd, NULL, pushbutton2W);
1578     ok(item == NULL, "Found item: %p\n", item);
1579     item = find_window(dlg_hwnd, NULL, comboboxitem1W);
1580     ok(item == NULL, "Found item: %p\n", item);
1581     item = find_window(dlg_hwnd, NULL, comboboxitem2W);
1582     ok(item == NULL, "Found item: %p\n", item);
1583     item = find_window(dlg_hwnd, NULL, radiobutton2W);
1584     ok(item == NULL, "Found item: %p\n", item);
1585     item = find_window(dlg_hwnd, NULL, checkbutton1W);
1586     ok(item == NULL, "Found item: %p\n", item);
1587     item = find_window(dlg_hwnd, NULL, editbox1W);
1588     ok(item == NULL, "Found item: %p\n", item);
1589     item = find_window(dlg_hwnd, NULL, editbox2W);
1590     ok(item == NULL, "Found item: %p\n", item);
1591     item = find_window(dlg_hwnd, NULL, textW);
1592     ok(item == NULL, "Found item: %p\n", item);
1593     item = find_window(dlg_hwnd, NULL, separatorW);
1594     ok(item == NULL, "Found item: %p\n", item);
1595     item = find_window(dlg_hwnd, NULL, visualgroup1W);
1596     ok(item == NULL, "Found item: %p\n", item);
1597     item = find_window(dlg_hwnd, NULL, visualgroup2W);
1598     todo_wine ok(item == NULL, "Found item: %p\n", item);
1599 
1600     br = PostMessageW(dlg_hwnd, WM_COMMAND, IDCANCEL, 0);
1601     ok(br, "Failed\n");
1602 }
1603 
1604 static void test_customize(void)
1605 {
1606     IFileDialog *pfod;
1607     IFileDialogCustomize *pfdc;
1608     IFileDialogEventsImpl *pfdeimpl;
1609     IFileDialogEvents *pfde;
1610     IOleWindow *pow;
1611     CDCONTROLSTATEF cdstate;
1612     DWORD cookie;
1613     LPWSTR tmpstr;
1614     UINT i;
1615     UINT id_vgroup1, id_text, id_editbox1;
1616     LONG ref;
1617     HWND dlg_hwnd;
1618     HRESULT hr;
1619     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1620                           &IID_IFileDialog, (void**)&pfod);
1621     ok(hr == S_OK, "got 0x%08x.\n", hr);
1622 
1623     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
1624     ok(hr == S_OK, "got 0x%08x.\n", hr);
1625     if(FAILED(hr))
1626     {
1627         skip("Skipping IFileDialogCustomize tests.\n");
1628         IFileDialog_Release(pfod);
1629         return;
1630     }
1631 
1632     i = 0;
1633     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton1W);
1634     ok(hr == S_OK, "got 0x%08x.\n", hr);
1635     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton1W);
1636     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1637 
1638     hr = IFileDialog_QueryInterface(pfod, &IID_IOleWindow, (void**)&pow);
1639     ok(hr == S_OK, "Got 0x%08x\n", hr);
1640     hr = IOleWindow_GetWindow(pow, &dlg_hwnd);
1641     ok(hr == S_OK, "Got 0x%08x\n", hr);
1642     ok(dlg_hwnd == NULL, "NULL\n");
1643     IOleWindow_Release(pow);
1644 
1645     cdstate = 0xdeadbeef;
1646     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1647     ok(hr == S_OK, "got 0x%08x.\n", hr);
1648     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1649 
1650     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1651     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1652 
1653     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1654     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1655 
1656     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i);
1657     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1658     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, ++i);
1659     ok(hr == S_OK, "got 0x%08x.\n", hr);
1660 
1661     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i);
1662     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1663     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, i+1);
1664     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1665 
1666     cdstate = 0xdeadbeef;
1667     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1668     ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1669     ok(cdstate == 0xdeadbeef, "got 0x%08x.\n", cdstate);
1670 
1671     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1672     ok(hr == S_OK, "got 0x%08x.\n", hr);
1673     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1674     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1675 
1676     cdstate = 0xdeadbeef;
1677     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1678     ok(hr == S_OK, "got 0x%08x.\n", hr);
1679     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1680     hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
1681     ok(hr == S_OK, "got 0x%08x.\n", hr);
1682     cdstate = 0xdeadbeef;
1683     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1684     ok(hr == S_OK, "got 0x%08x.\n", hr);
1685     ok(!cdstate, "got 0x%08x.\n", cdstate);
1686     hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
1687     ok(hr == S_OK, "got 0x%08x.\n", hr);
1688     cdstate = 0xdeadbeef;
1689     hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1690     ok(hr == S_OK, "got 0x%08x.\n", hr);
1691     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1692 
1693     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1694     ok(hr == E_NOTIMPL, "got 0x%08x (control: %d).\n", hr, i);
1695 
1696     hr = IFileDialogCustomize_AddMenu(pfdc, i, menuW);
1697     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1698     hr = IFileDialogCustomize_AddMenu(pfdc, ++i, label);
1699     ok(hr == S_OK, "got 0x%08x.\n", hr);
1700 
1701     cdstate = 0xdeadbeef;
1702     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1703     ok(hr == S_OK, "got 0x%08x.\n", hr);
1704     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1705 
1706     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1707     ok(hr == S_OK, "got 0x%08x.\n", hr);
1708     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1709     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1710 
1711     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1712     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1713 
1714     hr = IFileDialogCustomize_AddPushButton(pfdc, i, pushbutton2W);
1715     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1716     hr = IFileDialogCustomize_AddPushButton(pfdc, ++i, pushbutton2W);
1717     ok(hr == S_OK, "got 0x%08x.\n", hr);
1718 
1719     cdstate = 0xdeadbeef;
1720     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1721     ok(hr == S_OK, "got 0x%08x.\n", hr);
1722     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1723 
1724     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1725     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1726 
1727     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1728     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1729 
1730     hr = IFileDialogCustomize_AddComboBox(pfdc, i);
1731     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1732     hr = IFileDialogCustomize_AddComboBox(pfdc, ++i);
1733     ok(hr == S_OK, "got 0x%08x.\n", hr);
1734 
1735     cdstate = 0xdeadbeef;
1736     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1737     ok(hr == S_OK, "got 0x%08x.\n", hr);
1738     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1739 
1740     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1741     ok(hr == S_OK, "got 0x%08x.\n", hr);
1742     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1743     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1744 
1745     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1746     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1747 
1748     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, i);
1749     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1750     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, ++i);
1751     ok(hr == S_OK, "got 0x%08x.\n", hr);
1752 
1753     cdstate = 0xdeadbeef;
1754     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1755     ok(hr == S_OK, "got 0x%08x.\n", hr);
1756     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1757 
1758     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, radiobutton1W);
1759     ok(hr == S_OK, "got 0x%08x.\n", hr);
1760     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, radiobutton1W);
1761     ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1762 
1763     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, radiobutton2W);
1764     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1765 
1766     hr = IFileDialogCustomize_AddCheckButton(pfdc, i, label, TRUE);
1767     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1768     hr = IFileDialogCustomize_AddCheckButton(pfdc, ++i, checkbutton1W, TRUE);
1769     ok(hr == S_OK, "got 0x%08x.\n", hr);
1770 
1771     cdstate = 0xdeadbeef;
1772     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1773     ok(hr == S_OK, "got 0x%08x.\n", hr);
1774     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1775 
1776     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1777     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1778 
1779     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, checkbutton2W);
1780     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1781 
1782     if(SUCCEEDED(hr))
1783     {
1784         BOOL checked;
1785         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1786         ok(hr == S_OK, "got 0x%08x.\n", hr);
1787         ok(checked, "checkbox not checked.\n");
1788 
1789         hr = IFileDialogCustomize_SetCheckButtonState(pfdc, i, FALSE);
1790         ok(hr == S_OK, "got 0x%08x.\n", hr);
1791 
1792         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1793         ok(hr == S_OK, "got 0x%08x.\n", hr);
1794         ok(!checked, "checkbox checked.\n");
1795 
1796         hr = IFileDialogCustomize_SetCheckButtonState(pfdc, i, TRUE);
1797         ok(hr == S_OK, "got 0x%08x.\n", hr);
1798 
1799         hr = IFileDialogCustomize_GetCheckButtonState(pfdc, i, &checked);
1800         ok(hr == S_OK, "got 0x%08x.\n", hr);
1801         ok(checked, "checkbox not checked.\n");
1802     }
1803 
1804     hr = IFileDialogCustomize_AddEditBox(pfdc, i, label);
1805     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1806     hr = IFileDialogCustomize_AddEditBox(pfdc, ++i, editbox1W);
1807     ok(hr == S_OK, "got 0x%08x.\n", hr);
1808 
1809     cdstate = 0xdeadbeef;
1810     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1811     ok(hr == S_OK, "got 0x%08x.\n", hr);
1812     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1813 
1814     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1815     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1816 
1817     /* Does not affect the text in the editbox */
1818     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, editbox2W);
1819     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1820 
1821     hr = IFileDialogCustomize_GetEditBoxText(pfdc, i, &tmpstr);
1822     ok(hr == S_OK, "got 0x%08x.\n", hr);
1823     if(SUCCEEDED(hr))
1824     {
1825         ok(!lstrcmpW(tmpstr, editbox1W), "got %s.\n", wine_dbgstr_w(tmpstr));
1826         CoTaskMemFree(tmpstr);
1827     }
1828 
1829     hr = IFileDialogCustomize_SetEditBoxText(pfdc, i, label2);
1830     ok(hr == S_OK, "got 0x%08x.\n", hr);
1831 
1832     hr = IFileDialogCustomize_GetEditBoxText(pfdc, i, &tmpstr);
1833     ok(hr == S_OK, "got 0x%08x.\n", hr);
1834     if(SUCCEEDED(hr))
1835     {
1836         ok(!lstrcmpW(tmpstr, label2), "got %s.\n", wine_dbgstr_w(tmpstr));
1837         CoTaskMemFree(tmpstr);
1838     }
1839 
1840     hr = IFileDialogCustomize_AddSeparator(pfdc, i);
1841     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1842     hr = IFileDialogCustomize_AddSeparator(pfdc, ++i);
1843     ok(hr == S_OK, "got 0x%08x.\n", hr);
1844 
1845     cdstate = 0xdeadbeef;
1846     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1847     ok(hr == S_OK, "got 0x%08x.\n", hr);
1848     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1849 
1850     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1851     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1852 
1853     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, separatorW);
1854     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1855 
1856     hr = IFileDialogCustomize_AddText(pfdc, i, label);
1857     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1858     hr = IFileDialogCustomize_AddText(pfdc, ++i, textW);
1859     ok(hr == S_OK, "got 0x%08x.\n", hr);
1860 
1861     cdstate = 0xdeadbeef;
1862     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1863     ok(hr == S_OK, "got 0x%08x.\n", hr);
1864     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1865 
1866     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1867     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1868 
1869     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, text2W);
1870     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1871 
1872     hr = IFileDialogCustomize_StartVisualGroup(pfdc, i, label);
1873     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1874     hr = IFileDialogCustomize_StartVisualGroup(pfdc, ++i, visualgroup1W);
1875     ok(hr == S_OK, "got 0x%08x.\n", hr);
1876 
1877     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1878     ok(hr == E_NOINTERFACE, "got 0x%08x.\n", hr);
1879 
1880     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, visualgroup2W);
1881     ok(hr == S_OK, "got 0x%08x (control: %d).\n", hr, i);
1882 
1883     cdstate = 0xdeadbeef;
1884     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1885     ok(hr == S_OK, "got 0x%08x.\n", hr);
1886     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1887 
1888     hr = IFileDialogCustomize_StartVisualGroup(pfdc, ++i, label);
1889     ok(hr == E_UNEXPECTED, "got 0x%08x.\n", hr);
1890     hr = IFileDialogCustomize_EndVisualGroup(pfdc);
1891     ok(hr == S_OK, "got 0x%08x.\n", hr);
1892 
1893     i++; /* Nonexisting control */
1894     hr = IFileDialogCustomize_AddControlItem(pfdc, i, 0, label);
1895     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1896     hr = IFileDialogCustomize_SetControlLabel(pfdc, i, label2);
1897     ok(hr == E_INVALIDARG, "got 0x%08x (control: %d).\n", hr, i);
1898     cdstate = 0xdeadbeef;
1899     hr = IFileDialogCustomize_GetControlState(pfdc, i, &cdstate);
1900     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
1901     ok(cdstate == 0xdeadbeef, "got 0x%08x.\n", cdstate);
1902 
1903     pfde = IFileDialogEvents_Constructor();
1904     pfdeimpl = impl_from_IFileDialogEvents(pfde);
1905     pfdeimpl->events_test = IFDEVENT_TEST1;
1906     hr = IFileDialog_Advise(pfod, pfde, &cookie);
1907     ok(hr == S_OK, "Got 0x%08x\n", hr);
1908 
1909     hr = IFileDialog_Show(pfod, NULL);
1910     ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "Got 0x%08x\n", hr);
1911 
1912     hr = IFileDialog_Unadvise(pfod, cookie);
1913     ok(hr == S_OK, "Got 0x%08x\n", hr);
1914 
1915     IFileDialogEvents_Release(pfde);
1916     IFileDialogCustomize_Release(pfdc);
1917     ref = IFileDialog_Release(pfod);
1918     ok(!ref, "Refcount not zero (%d).\n", ref);
1919 
1920 
1921     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
1922                           &IID_IFileDialog, (void**)&pfod);
1923     ok(hr == S_OK, "got 0x%08x.\n", hr);
1924 
1925     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
1926     ok(hr == S_OK, "got 0x%08x.\n", hr);
1927 
1928     i = 0;
1929     hr = IFileDialogCustomize_AddMenu(pfdc, ++i, label);
1930     ok(hr == S_OK, "got 0x%08x.\n", hr);
1931     if(SUCCEEDED(hr))
1932     {
1933         DWORD selected;
1934         UINT j = 0;
1935 
1936         for(j = 0; j < 10; j++)
1937         {
1938             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
1939             ok(hr == S_OK, "got 0x%08x.\n", hr);
1940         }
1941 
1942         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
1943         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1944 
1945         cdstate = 0xdeadbeef;
1946         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1947         ok(hr == S_OK, "got 0x%08x.\n", hr);
1948         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1949         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
1950         ok(hr == S_OK, "got 0x%08x.\n", hr);
1951         cdstate = 0xdeadbeef;
1952         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1953         ok(hr == S_OK, "got 0x%08x.\n", hr);
1954         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
1955         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
1956         ok(hr == S_OK, "got 0x%08x.\n", hr);
1957         cdstate = 0xdeadbeef;
1958         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1959         ok(hr == S_OK, "got 0x%08x.\n", hr);
1960         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1961 
1962         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
1963         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
1964 
1965         for(j = 0; j < 10; j++)
1966         {
1967             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
1968             ok(hr == S_OK, "got 0x%08x.\n", hr);
1969         }
1970     }
1971     hr = IFileDialogCustomize_AddPushButton(pfdc, ++i, label);
1972     ok(hr == S_OK, "got 0x%08x.\n", hr);
1973     hr = IFileDialogCustomize_AddComboBox(pfdc, ++i);
1974     ok(hr == S_OK, "got 0x%08x.\n", hr);
1975     if(SUCCEEDED(hr))
1976     {
1977         DWORD selected = -1;
1978         UINT j = 0;
1979 
1980         for(j = 0; j < 10; j++)
1981         {
1982             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
1983             ok(hr == S_OK, "got 0x%08x.\n", hr);
1984         }
1985 
1986         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
1987         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
1988         ok(selected == -1, "got %d.\n", selected);
1989 
1990         cdstate = 0xdeadbeef;
1991         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1992         ok(hr == S_OK, "got 0x%08x.\n", hr);
1993         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
1994         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
1995         ok(hr == S_OK, "got 0x%08x.\n", hr);
1996         cdstate = 0xdeadbeef;
1997         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
1998         ok(hr == S_OK, "got 0x%08x.\n", hr);
1999         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2000         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2001         ok(hr == S_OK, "got 0x%08x.\n", hr);
2002         cdstate = 0xdeadbeef;
2003         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2004         ok(hr == S_OK, "got 0x%08x.\n", hr);
2005         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2006 
2007         for(j = 0; j < 10; j++)
2008         {
2009             hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2010             ok(hr == S_OK, "got 0x%08x.\n", hr);
2011             hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2012             ok(hr == S_OK, "got 0x%08x.\n", hr);
2013             ok(selected == j, "got %d.\n", selected);
2014         }
2015         j++;
2016         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2017         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
2018 
2019         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2020         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2021 
2022         for(j = 0; j < 10; j++)
2023         {
2024             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2025             ok(hr == S_OK, "got 0x%08x.\n", hr);
2026         }
2027     }
2028 
2029     hr = IFileDialogCustomize_AddRadioButtonList(pfdc, ++i);
2030     ok(hr == S_OK, "got 0x%08x.\n", hr);
2031     if(SUCCEEDED(hr))
2032     {
2033         DWORD selected = -1;
2034         UINT j = 0;
2035 
2036         for(j = 0; j < 10; j++)
2037         {
2038             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
2039             ok(hr == S_OK, "got 0x%08x.\n", hr);
2040         }
2041 
2042         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2043         ok(hr == E_FAIL, "got 0x%08x.\n", hr);
2044         ok(selected == -1, "got %d.\n", selected);
2045 
2046         cdstate = 0xdeadbeef;
2047         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2048         ok(hr == S_OK, "got 0x%08x.\n", hr);
2049         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2050         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
2051         ok(hr == S_OK, "got 0x%08x.\n", hr);
2052         cdstate = 0xdeadbeef;
2053         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2054         ok(hr == S_OK, "got 0x%08x.\n", hr);
2055         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2056         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2057         ok(hr == S_OK, "got 0x%08x.\n", hr);
2058         cdstate = 0xdeadbeef;
2059         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2060         ok(hr == S_OK, "got 0x%08x.\n", hr);
2061         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2062 
2063         for(j = 0; j < 10; j++)
2064         {
2065             hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2066             ok(hr == S_OK, "got 0x%08x.\n", hr);
2067             hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2068             ok(hr == S_OK, "got 0x%08x.\n", hr);
2069             ok(selected == j, "got %d.\n", selected);
2070         }
2071         j++;
2072         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, j);
2073         ok(hr == E_INVALIDARG, "got 0x%08x.\n", hr);
2074 
2075         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2076         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2077 
2078         for(j = 0; j < 10; j++)
2079         {
2080             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2081             ok(hr == S_OK, "got 0x%08x.\n", hr);
2082         }
2083     }
2084     hr = IFileDialogCustomize_EnableOpenDropDown(pfdc, ++i);
2085     ok(hr == S_OK, "got 0x%08x.\n", hr);
2086     if(SUCCEEDED(hr))
2087     {
2088         DWORD selected = -1;
2089         UINT j = 0;
2090 
2091         for(j = 0; j < 10; j++)
2092         {
2093             hr = IFileDialogCustomize_AddControlItem(pfdc, i, j, label);
2094             ok(hr == S_OK, "got 0x%08x.\n", hr);
2095         }
2096 
2097         hr = IFileDialogCustomize_GetSelectedControlItem(pfdc, i, &selected);
2098         ok(hr == S_OK, "got 0x%08x.\n", hr);
2099         ok(selected == 0, "got %d.\n", selected);
2100 
2101         cdstate = 0xdeadbeef;
2102         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2103         ok(hr == S_OK, "got 0x%08x.\n", hr);
2104         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2105         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, 0);
2106         ok(hr == S_OK, "got 0x%08x.\n", hr);
2107         cdstate = 0xdeadbeef;
2108         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2109         ok(hr == S_OK, "got 0x%08x.\n", hr);
2110         ok(cdstate == 0, "got 0x%08x.\n", cdstate);
2111         hr = IFileDialogCustomize_SetControlItemState(pfdc, i, 0, CDCS_ENABLEDVISIBLE);
2112         ok(hr == S_OK, "got 0x%08x.\n", hr);
2113         cdstate = 0xdeadbeef;
2114         hr = IFileDialogCustomize_GetControlItemState(pfdc, i, 0, &cdstate);
2115         ok(hr == S_OK, "got 0x%08x.\n", hr);
2116         ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2117         hr = IFileDialogCustomize_SetSelectedControlItem(pfdc, i, 0);
2118         todo_wine ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2119 
2120         hr = IFileDialogCustomize_RemoveAllControlItems(pfdc, i);
2121         ok(hr == E_NOTIMPL, "got 0x%08x.\n", hr);
2122 
2123         for(j = 0; j < 10; j++)
2124         {
2125             hr = IFileDialogCustomize_RemoveControlItem(pfdc, i, j);
2126             ok(hr == S_OK, "got 0x%08x.\n", hr);
2127         }
2128     }
2129 
2130     IFileDialogCustomize_Release(pfdc);
2131     ref = IFileDialog_Release(pfod);
2132     ok(!ref, "Refcount not zero (%d).\n", ref);
2133 
2134 
2135     /* Some more tests for VisualGroup behavior */
2136     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2137                           &IID_IFileDialog, (void**)&pfod);
2138     ok(hr == S_OK, "got 0x%08x.\n", hr);
2139 
2140     hr = IFileDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
2141     ok(hr == S_OK, "got 0x%08x.\n", hr);
2142 
2143     i = -1;
2144     id_vgroup1 = ++i;
2145     hr = IFileDialogCustomize_StartVisualGroup(pfdc, id_vgroup1, visualgroup1W);
2146     ok(hr == S_OK, "got 0x%08x.\n", hr);
2147 
2148     cdstate = 0xdeadbeef;
2149     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2150     ok(hr == S_OK, "got 0x%08x.\n", hr);
2151     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2152 
2153     id_text = ++i;
2154     hr = IFileDialogCustomize_AddText(pfdc, id_text, label);
2155     ok(hr == S_OK, "got 0x%08x.\n", hr);
2156 
2157     cdstate = 0xdeadbeef;
2158     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2159     ok(hr == S_OK, "got 0x%08x.\n", hr);
2160     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2161 
2162     id_editbox1 = ++i;
2163     hr = IFileDialogCustomize_AddEditBox(pfdc, id_editbox1, editbox1W);
2164     ok(hr == S_OK, "got 0x%08x.\n", hr);
2165 
2166     cdstate = 0xdeadbeef;
2167     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2168     ok(hr == S_OK, "got 0x%08x.\n", hr);
2169     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2170 
2171 
2172     /* Set all Visible but not Enabled */
2173     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_VISIBLE);
2174     ok(hr == S_OK, "got 0x%08x.\n", hr);
2175 
2176     cdstate = 0xdeadbeef;
2177     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2178     ok(hr == S_OK, "got 0x%08x.\n", hr);
2179     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2180     cdstate = 0xdeadbeef;
2181 
2182     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2183     ok(hr == S_OK, "got 0x%08x.\n", hr);
2184     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2185 
2186     cdstate = 0xdeadbeef;
2187     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2188     ok(hr == S_OK, "got 0x%08x.\n", hr);
2189     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2190 
2191     /* Set text to Visible but not Enabled */
2192     hr = IFileDialogCustomize_SetControlState(pfdc, id_text, CDCS_VISIBLE);
2193     ok(hr == S_OK, "got 0x%08x.\n", hr);
2194 
2195     cdstate = 0xdeadbeef;
2196     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2197     ok(hr == S_OK, "got 0x%08x.\n", hr);
2198     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2199     cdstate = 0xdeadbeef;
2200 
2201     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2202     ok(hr == S_OK, "got 0x%08x.\n", hr);
2203     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2204 
2205     cdstate = 0xdeadbeef;
2206     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2207     ok(hr == S_OK, "got 0x%08x.\n", hr);
2208     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2209 
2210     /* Set vgroup to inactive */
2211     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_INACTIVE);
2212     ok(hr == S_OK, "got 0x%08x.\n", hr);
2213 
2214     cdstate = 0xdeadbeef;
2215     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2216     ok(hr == S_OK, "got 0x%08x.\n", hr);
2217     ok(cdstate == CDCS_INACTIVE, "got 0x%08x.\n", cdstate);
2218 
2219     cdstate = 0xdeadbeef;
2220     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2221     ok(hr == S_OK, "got 0x%08x.\n", hr);
2222     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2223 
2224     cdstate = 0xdeadbeef;
2225     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2226     ok(hr == S_OK, "got 0x%08x.\n", hr);
2227     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2228 
2229     /* Set vgroup to Enabled and Visible again */
2230     hr = IFileDialogCustomize_SetControlState(pfdc, id_vgroup1, CDCS_ENABLEDVISIBLE);
2231     ok(hr == S_OK, "got 0x%08x.\n", hr);
2232 
2233     cdstate = 0xdeadbeef;
2234     hr = IFileDialogCustomize_GetControlState(pfdc, id_vgroup1, &cdstate);
2235     ok(hr == S_OK, "got 0x%08x.\n", hr);
2236     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2237 
2238     cdstate = 0xdeadbeef;
2239     hr = IFileDialogCustomize_GetControlState(pfdc, id_text, &cdstate);
2240     ok(hr == S_OK, "got 0x%08x.\n", hr);
2241     ok(cdstate == CDCS_VISIBLE, "got 0x%08x.\n", cdstate);
2242 
2243     cdstate = 0xdeadbeef;
2244     hr = IFileDialogCustomize_GetControlState(pfdc, id_editbox1, &cdstate);
2245     ok(hr == S_OK, "got 0x%08x.\n", hr);
2246     ok(cdstate == CDCS_ENABLEDVISIBLE, "got 0x%08x.\n", cdstate);
2247 
2248     hr = IFileDialogCustomize_MakeProminent(pfdc, id_vgroup1);
2249     ok(hr == S_OK, "got 0x%08x.\n", hr);
2250 
2251     IFileDialogCustomize_Release(pfdc);
2252     ref = IFileDialog_Release(pfod);
2253     ok(!ref, "Refcount not zero (%d).\n", ref);
2254 }
2255 
2256 static void test_persistent_state(void)
2257 {
2258     IFileDialog *fd;
2259     HRESULT hr;
2260 
2261     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2262                           &IID_IFileDialog, (void**)&fd);
2263     ok(hr == S_OK, "got 0x%08x.\n", hr);
2264 
2265 if (0)
2266 {
2267     /* crashes at least on Win8 */
2268     hr = IFileDialog_SetClientGuid(fd, NULL);
2269 }
2270 
2271     hr = IFileDialog_SetClientGuid(fd, &IID_IUnknown);
2272     ok(hr == S_OK, "got 0x%08x\n", hr);
2273 
2274     hr = IFileDialog_SetClientGuid(fd, &IID_NULL);
2275     ok(hr == S_OK, "got 0x%08x\n", hr);
2276 
2277     IFileDialog_Release(fd);
2278 }
2279 
2280 static void test_overwrite(void)
2281 {
2282     static const WCHAR filename_winetest[] = {'w','i','n','e','t','e','s','t','.','o','v','w',0};
2283     IFileDialogEventsImpl *pfdeimpl;
2284     IFileDialogEvents *pfde;
2285     IFileDialog *fd;
2286     DWORD cookie;
2287     LPWSTR filename;
2288     IShellItem *psi_current;
2289     WCHAR buf[MAX_PATH];
2290     HRESULT hr;
2291 
2292     GetCurrentDirectoryW(MAX_PATH, buf);
2293     ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
2294     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
2295     ok(hr == S_OK, "Got 0x%08x\n", hr);
2296 
2297     touch_file(filename_winetest);
2298 
2299     /* FOS_OVERWRITEPROMPT has no effect on open dialog */
2300     hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
2301                           &IID_IFileDialog, (void**)&fd);
2302     ok(hr == S_OK, "got 0x%08x.\n", hr);
2303 
2304     hr = IFileDialog_SetOptions(fd, FOS_OVERWRITEPROMPT | FOS_NOCHANGEDIR);
2305     ok(hr == S_OK, "got 0x%08x.\n", hr);
2306 
2307     hr = IFileDialog_SetFolder(fd, psi_current);
2308     ok(hr == S_OK, "got 0x%08x.\n", hr);
2309 
2310     pfde = IFileDialogEvents_Constructor();
2311     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2312     pfdeimpl->set_filename = filename_winetest;
2313     hr = IFileDialog_Advise(fd, pfde, &cookie);
2314     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2315 
2316     hr = IFileDialog_Show(fd, NULL);
2317     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2318 
2319     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2320     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2321 
2322     hr = IFileDialog_GetFileName(fd, &filename);
2323     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2324     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2325     CoTaskMemFree(filename);
2326 
2327     hr = IFileDialog_Unadvise(fd, cookie);
2328     ok(hr == S_OK, "got 0x%08x.\n", hr);
2329 
2330     IFileDialog_Release(fd);
2331 
2332     IFileDialogEvents_Release(pfde);
2333 
2334     /* Save dialog doesn't check for overwrite without FOS_OVERWRITEPROMPT set */
2335     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2336                           &IID_IFileDialog, (void**)&fd);
2337     ok(hr == S_OK, "got 0x%08x.\n", hr);
2338 
2339     hr = IFileDialog_SetOptions(fd, FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR);
2340     ok(hr == S_OK, "got 0x%08x.\n", hr);
2341 
2342     hr = IFileDialog_SetFolder(fd, psi_current);
2343     ok(hr == S_OK, "got 0x%08x.\n", hr);
2344 
2345     pfde = IFileDialogEvents_Constructor();
2346     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2347     pfdeimpl->set_filename = filename_winetest;
2348     hr = IFileDialog_Advise(fd, pfde, &cookie);
2349     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2350 
2351     hr = IFileDialog_Show(fd, NULL);
2352     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2353 
2354     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2355     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2356 
2357     hr = IFileDialog_GetFileName(fd, &filename);
2358     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2359     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2360     CoTaskMemFree(filename);
2361 
2362     hr = IFileDialog_Unadvise(fd, cookie);
2363     ok(hr == S_OK, "got 0x%08x.\n", hr);
2364 
2365     IFileDialog_Release(fd);
2366 
2367     IFileDialogEvents_Release(pfde);
2368 
2369     /* Save dialog with FOS_OVERWRITEPROMPT set */
2370     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2371                           &IID_IFileDialog, (void**)&fd);
2372     ok(hr == S_OK, "got 0x%08x.\n", hr);
2373 
2374     hr = IFileDialog_SetFolder(fd, psi_current);
2375     ok(hr == S_OK, "got 0x%08x.\n", hr);
2376 
2377     pfde = IFileDialogEvents_Constructor();
2378     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2379     pfdeimpl->set_filename = filename_winetest;
2380     hr = IFileDialog_Advise(fd, pfde, &cookie);
2381     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2382 
2383     hr = IFileDialog_Show(fd, NULL);
2384     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2385 
2386     ok(pfdeimpl->OnOverwrite == 1, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2387     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2388 
2389     hr = IFileDialog_GetFileName(fd, &filename);
2390     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2391     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2392     CoTaskMemFree(filename);
2393 
2394     hr = IFileDialog_Unadvise(fd, cookie);
2395     ok(hr == S_OK, "got 0x%08x.\n", hr);
2396 
2397     IFileDialog_Release(fd);
2398 
2399     IFileDialogEvents_Release(pfde);
2400 
2401     DeleteFileW(filename_winetest);
2402 
2403     /* Save dialog with FOS_OVERWRITEPROMPT set but without existing file */
2404     hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
2405                           &IID_IFileDialog, (void**)&fd);
2406     ok(hr == S_OK, "got 0x%08x.\n", hr);
2407 
2408     hr = IFileDialog_SetFolder(fd, psi_current);
2409     ok(hr == S_OK, "got 0x%08x.\n", hr);
2410 
2411     pfde = IFileDialogEvents_Constructor();
2412     pfdeimpl = impl_from_IFileDialogEvents(pfde);
2413     pfdeimpl->set_filename = filename_winetest;
2414     hr = IFileDialog_Advise(fd, pfde, &cookie);
2415     ok(hr == S_OK, "Advise failed: Got 0x%08x\n", hr);
2416 
2417     hr = IFileDialog_Show(fd, NULL);
2418     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
2419 
2420     ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
2421     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
2422 
2423     hr = IFileDialog_GetFileName(fd, &filename);
2424     ok(hr == S_OK, "GetFileName failed: Got 0x%08x\n", hr);
2425     ok(!lstrcmpW(filename, filename_winetest), "Got %s\n", wine_dbgstr_w(filename));
2426     CoTaskMemFree(filename);
2427 
2428     hr = IFileDialog_Unadvise(fd, cookie);
2429     ok(hr == S_OK, "got 0x%08x.\n", hr);
2430 
2431     IFileDialog_Release(fd);
2432 
2433     IFileDialogEvents_Release(pfde);
2434 
2435     IShellItem_Release(psi_current);
2436 }
2437 
2438 START_TEST(itemdlg)
2439 {
2440     OleInitialize(NULL);
2441     init_function_pointers();
2442 
2443     if(test_instantiation())
2444     {
2445         test_basics();
2446         test_advise();
2447         test_events();
2448         test_filename();
2449         test_customize();
2450         test_persistent_state();
2451         test_overwrite();
2452     }
2453     else
2454         skip("Skipping all Item Dialog tests.\n");
2455 
2456     OleUninitialize();
2457 }
2458