shell32: Implement IExplorerBrowser::BrowseToObject.
[wine] / dlls / shell32 / tests / ebrowser.c
1 /*
2  *    Unit tests for the Explorer Browser control
3  *
4  * Copyright 2010 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 #include <stdio.h>
22
23 #define COBJMACROS
24
25 #include "shlobj.h"
26
27 #include "wine/test.h"
28
29 static HWND hwnd;
30
31 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
32 static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
33
34 static void init_function_pointers(void)
35 {
36     HMODULE hmod;
37
38     hmod = GetModuleHandleA("shell32.dll");
39     pSHCreateShellItem = (void*)GetProcAddress(hmod, "SHCreateShellItem");
40     pSHParseDisplayName = (void*)GetProcAddress(hmod, "SHParseDisplayName");
41 }
42
43 /*********************************************************************
44  * Some simple helpers
45  */
46 static HRESULT ebrowser_instantiate(IExplorerBrowser **peb)
47 {
48     return CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
49                             &IID_IExplorerBrowser, (void**)peb);
50 }
51
52 static HRESULT ebrowser_initialize(IExplorerBrowser *peb)
53 {
54     RECT rc;
55     rc.top = rc.left = 0; rc.bottom = rc.right = 500;
56     return IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
57 }
58
59 static HRESULT ebrowser_browse_to_desktop(IExplorerBrowser *peb)
60 {
61     LPITEMIDLIST pidl_desktop;
62     SHGetSpecialFolderLocation (hwnd, CSIDL_DESKTOP, &pidl_desktop);
63     return IExplorerBrowser_BrowseToIDList(peb, pidl_desktop, 0);
64 }
65
66 /* Process some messages */
67 static void process_msgs(void)
68 {
69     MSG msg;
70     while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
71     {
72         TranslateMessage(&msg);
73         DispatchMessage(&msg);
74     }
75 }
76
77 /*********************************************************************
78  * IExplorerBrowserEvents implementation
79  */
80 typedef struct {
81     const IExplorerBrowserEventsVtbl *lpVtbl;
82     LONG ref;
83     UINT pending, created, completed, failed;
84 } IExplorerBrowserEventsImpl;
85
86 static IExplorerBrowserEventsImpl ebev;
87
88 static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
89                                                               REFIID riid, void **ppvObj)
90 {
91     ok(0, "Never called.\n");
92     return E_NOINTERFACE;
93 }
94
95 static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
96 {
97     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
98     return InterlockedIncrement(&This->ref);
99 }
100
101 static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
102 {
103     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
104     return InterlockedDecrement(&This->ref);
105 }
106
107 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
108                                                                    PCIDLIST_ABSOLUTE pidlFolder)
109 {
110     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
111     This->pending++;
112     return S_OK;
113 }
114
115 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
116                                                                     PCIDLIST_ABSOLUTE pidlFolder)
117 {
118     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
119     This->completed++;
120     return S_OK;
121 }
122 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
123                                                                   PCIDLIST_ABSOLUTE pidlFolder)
124 {
125     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
126     This->failed++;
127     return S_OK;
128 }
129 static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
130                                                              IShellView *psv)
131 {
132     IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
133     This->created++;
134     return S_OK;
135 }
136
137 static const IExplorerBrowserEventsVtbl ebevents =
138 {
139     IExplorerBrowserEvents_fnQueryInterface,
140     IExplorerBrowserEvents_fnAddRef,
141     IExplorerBrowserEvents_fnRelease,
142     IExplorerBrowserEvents_fnOnNavigationPending,
143     IExplorerBrowserEvents_fnOnViewCreated,
144     IExplorerBrowserEvents_fnOnNavigationComplete,
145     IExplorerBrowserEvents_fnOnNavigationFailed
146 };
147
148 static void test_QueryInterface(void)
149 {
150     IExplorerBrowser *peb;
151     IUnknown *punk;
152     HRESULT hr;
153     LONG lres;
154
155     hr = ebrowser_instantiate(&peb);
156     ok(hr == S_OK, "Got 0x%08x\n", hr);
157
158 #define test_qinterface(iid, exp)                                       \
159     do {                                                                \
160         hr = IExplorerBrowser_QueryInterface(peb, &iid, (void**)&punk); \
161         ok(hr == exp, "(%s:)Expected (0x%08x), got (0x%08x)\n",         \
162            #iid, exp, hr);                                              \
163         if(SUCCEEDED(hr)) IUnknown_Release(punk);                       \
164     } while(0)
165
166     test_qinterface(IID_IUnknown, S_OK);
167     test_qinterface(IID_IExplorerBrowser, S_OK);
168     test_qinterface(IID_IShellBrowser, S_OK);
169     todo_wine test_qinterface(IID_IOleWindow, S_OK);
170     todo_wine test_qinterface(IID_ICommDlgBrowser, S_OK);
171     todo_wine test_qinterface(IID_ICommDlgBrowser2, S_OK);
172     todo_wine test_qinterface(IID_ICommDlgBrowser3, S_OK);
173     todo_wine test_qinterface(IID_IServiceProvider, S_OK);
174     todo_wine test_qinterface(IID_IObjectWithSite, S_OK);
175     todo_wine test_qinterface(IID_IConnectionPointContainer, S_OK);
176     test_qinterface(IID_IOleObject, E_NOINTERFACE);
177     test_qinterface(IID_IViewObject, E_NOINTERFACE);
178     test_qinterface(IID_IViewObject2, E_NOINTERFACE);
179     test_qinterface(IID_IViewObjectEx, E_NOINTERFACE);
180     test_qinterface(IID_IConnectionPoint, E_NOINTERFACE);
181     test_qinterface(IID_IShellView, E_NOINTERFACE);
182     test_qinterface(IID_INameSpaceTreeControlEvents, E_NOINTERFACE);
183
184 #undef test_qinterface
185
186     lres = IExplorerBrowser_Release(peb);
187     ok(lres == 0, "Got %d\n", lres);
188 }
189
190 static void test_SB_misc(void)
191 {
192     IExplorerBrowser *peb;
193     IShellBrowser *psb;
194     IUnknown *punk;
195     HRESULT hr;
196     HWND retHwnd;
197     LRESULT lres;
198     LONG ref;
199
200     ebrowser_instantiate(&peb);
201     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
202     ok(hr == S_OK, "Got 0x%08x\n", hr);
203     if(FAILED(hr))
204     {
205         skip("Failed to get IShellBrowser interface.\n");
206         return;
207     }
208
209     /* Some unimplemented methods */
210     retHwnd = (HWND)0xDEADBEEF;
211     hr = IShellBrowser_GetControlWindow(psb, FCW_TOOLBAR, &retHwnd);
212     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
213     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
214
215     hr = IShellBrowser_GetControlWindow(psb, FCW_STATUS, &retHwnd);
216     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
217     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
218
219     hr = IShellBrowser_GetControlWindow(psb, FCW_TREE, &retHwnd);
220     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
221     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
222
223     hr = IShellBrowser_GetControlWindow(psb, FCW_PROGRESS, &retHwnd);
224     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
225     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
226
227     /* ::InsertMenuSB */
228     hr = IShellBrowser_InsertMenusSB(psb, NULL, NULL);
229     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
230
231     /* ::RemoveMenusSB */
232     hr = IShellBrowser_RemoveMenusSB(psb, NULL);
233     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
234
235     /* ::SetMenuSB */
236     hr = IShellBrowser_SetMenuSB(psb, NULL, NULL, NULL);
237     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
238
239     /***** Before EB::Initialize *****/
240
241     /* ::GetWindow */
242     retHwnd = (HWND)0xDEADBEEF;
243     hr = IShellBrowser_GetWindow(psb, &retHwnd);
244     ok(hr == E_FAIL, "got (0x%08x)\n", hr);
245     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
246
247     todo_wine
248     {
249
250         /* ::SendControlMsg */
251         lres = 0xDEADBEEF;
252         hr = IShellBrowser_SendControlMsg(psb, FCW_STATUS, 0, 0, 0, &lres);
253         ok(hr == S_OK, "got (0x%08x)\n", hr);
254         ok(lres == 0, "lres was %ld\n", lres);
255
256         lres = 0xDEADBEEF;
257         hr = IShellBrowser_SendControlMsg(psb, FCW_TOOLBAR, TB_CHECKBUTTON,
258                                           FCIDM_TB_SMALLICON, TRUE, &lres);
259         ok(hr == S_OK, "got (0x%08x)\n", hr);
260         ok(lres == 0, "lres was %ld\n", lres);
261
262         hr = IShellBrowser_SendControlMsg(psb, FCW_STATUS, 0, 0, 0, NULL);
263         ok(hr == S_OK, "got (0x%08x)\n", hr);
264
265         hr = IShellBrowser_SendControlMsg(psb, FCW_TREE, 0, 0, 0, NULL);
266         ok(hr == S_OK, "got (0x%08x)\n", hr);
267
268         hr = IShellBrowser_SendControlMsg(psb, FCW_PROGRESS, 0, 0, 0, NULL);
269         ok(hr == S_OK, "got (0x%08x)\n", hr);
270     }
271
272     /* ::QueryActiveShellView */
273     hr = IShellBrowser_QueryActiveShellView(psb, (IShellView**)&punk);
274     ok(hr == E_FAIL, "got (0x%08x)\n", hr);
275
276     /* Initialize ExplorerBrowser */
277     ebrowser_initialize(peb);
278
279     /***** After EB::Initialize *****/
280
281     /* ::GetWindow */
282     hr = IShellBrowser_GetWindow(psb, &retHwnd);
283     ok(hr == S_OK, "got (0x%08x)\n", hr);
284     ok(GetParent(retHwnd) == hwnd, "The HWND returned is not our child.\n");
285
286     todo_wine
287     {
288         /* ::SendControlMsg */
289         hr = IShellBrowser_SendControlMsg(psb, FCW_STATUS, 0, 0, 0, NULL);
290         ok(hr == S_OK, "got (0x%08x)\n", hr);
291
292         lres = 0xDEADBEEF;
293         hr = IShellBrowser_SendControlMsg(psb, FCW_TOOLBAR, 0, 0, 0, &lres);
294         ok(hr == S_OK, "got (0x%08x)\n", hr);
295         ok(lres == 0, "lres was %ld\n", lres);
296
297         lres = 0xDEADBEEF;
298         hr = IShellBrowser_SendControlMsg(psb, FCW_STATUS, 0, 0, 0, &lres);
299         ok(hr == S_OK, "got (0x%08x)\n", hr);
300         ok(lres == 0, "lres was %ld\n", lres);
301
302         lres = 0xDEADBEEF;
303         hr = IShellBrowser_SendControlMsg(psb, 1234, 0, 0, 0, &lres);
304         ok(hr == S_OK, "got (0x%08x)\n", hr);
305         ok(lres == 0, "lres was %ld\n", lres);
306
307         /* Returns S_OK */
308         hr = IShellBrowser_SetStatusTextSB(psb, NULL);
309         ok(hr == S_OK, "got (0x%08x)\n", hr);
310
311         hr = IShellBrowser_ContextSensitiveHelp(psb, FALSE);
312         ok(hr == S_OK, "got (0x%08x)\n", hr);
313
314         hr = IShellBrowser_EnableModelessSB(psb, TRUE);
315         ok(hr == S_OK, "got (0x%08x)\n", hr);
316
317         hr = IShellBrowser_SetToolbarItems(psb, NULL, 1, 1);
318         ok(hr == S_OK, "got (0x%08x)\n", hr);
319     }
320
321     hr = IShellBrowser_QueryActiveShellView(psb, (IShellView**)&punk);
322     ok(hr == E_FAIL, "got (0x%08x)\n", hr);
323
324     IShellBrowser_Release(psb);
325     IExplorerBrowser_Destroy(peb);
326     IExplorerBrowser_Release(peb);
327
328     /* Browse to the desktop. */
329     ebrowser_instantiate(&peb);
330     ebrowser_initialize(peb);
331     IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
332
333     process_msgs();
334     hr = ebrowser_browse_to_desktop(peb);
335     ok(hr == S_OK, "got (0x%08x)\n", hr);
336     process_msgs();
337
338     /****** After Browsing *****/
339
340     hr = IShellBrowser_QueryActiveShellView(psb, (IShellView**)&punk);
341     ok(hr == S_OK, "got (0x%08x)\n", hr);
342     if(SUCCEEDED(hr)) IUnknown_Release(punk);
343
344     IShellBrowser_Release(psb);
345     IExplorerBrowser_Destroy(peb);
346     ref = IExplorerBrowser_Release(peb);
347     ok(ref == 0, "Got %d\n", ref);
348 }
349
350 static void test_initialization(void)
351 {
352     IExplorerBrowser *peb;
353     IShellBrowser *psb;
354     HRESULT hr;
355     ULONG lres;
356     RECT rc;
357
358     ebrowser_instantiate(&peb);
359
360     if(0)
361     {
362         /* Crashes on Windows 7 */
363         hr = IExplorerBrowser_Initialize(peb, NULL, NULL, NULL);
364         hr = IExplorerBrowser_Initialize(peb, hwnd, NULL, NULL);
365     }
366
367     ZeroMemory(&rc, sizeof(RECT));
368
369     hr = IExplorerBrowser_Initialize(peb, NULL, &rc, NULL);
370     ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
371
372     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
373     ok(hr == S_OK, "got (0x%08x)\n", hr);
374
375     /* Initialize twice */
376     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
377     ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
378
379     hr = IExplorerBrowser_Destroy(peb);
380     ok(hr == S_OK, "got (0x%08x)\n", hr);
381
382     /* Initialize again */
383     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
384     ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
385
386     /* Destroy again */
387     hr = IExplorerBrowser_Destroy(peb);
388     ok(hr == S_OK, "got (0x%08x)\n", hr);
389     lres = IExplorerBrowser_Release(peb);
390     ok(lres == 0, "Got %d\n", lres);
391
392     /* Initialize with a few different rectangles */
393     peb = NULL;
394     ebrowser_instantiate(&peb);
395     rc.left = 50; rc.top = 20; rc.right = 100; rc.bottom = 80;
396     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
397     ok(hr == S_OK, "got (0x%08x)\n", hr);
398     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
399     ok(hr == S_OK, "Got 0x%08x\n", hr);
400     if(SUCCEEDED(hr))
401     {
402         HWND eb_hwnd;
403         RECT eb_rc;
404         char buf[1024];
405         LONG style, expected_style;
406         static const RECT exp_rc = {0, 0, 48, 58};
407
408         hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
409         ok(hr == S_OK, "Got 0x%08x\n", hr);
410
411         GetClientRect(eb_hwnd, &eb_rc);
412         ok(EqualRect(&eb_rc, &exp_rc), "Got client rect (%d, %d)-(%d, %d)\n",
413            eb_rc.left, eb_rc.top, eb_rc.right, eb_rc.bottom);
414
415         GetWindowRect(eb_hwnd, &eb_rc);
416         ok(eb_rc.right - eb_rc.left == 50, "Got window width %d\n", eb_rc.right - eb_rc.left);
417         ok(eb_rc.bottom - eb_rc.top == 60, "Got window height %d\n", eb_rc.bottom - eb_rc.top);
418
419         buf[0] = '\0';
420         GetClassNameA(eb_hwnd, buf, 1024);
421         ok(!lstrcmpA(buf, "ExplorerBrowserControl"), "Unexpected classname %s\n", buf);
422
423         expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER;
424         style = GetWindowLongPtrW(eb_hwnd, GWL_STYLE);
425         todo_wine ok(style == expected_style, "Got style 0x%08x, expected 0x%08x\n", style, expected_style);
426
427         expected_style = WS_EX_CONTROLPARENT;
428         style = GetWindowLongPtrW(eb_hwnd, GWL_EXSTYLE);
429         ok(style == expected_style, "Got exstyle 0x%08x, expected 0x%08x\n", style, expected_style);
430
431         ok(GetParent(eb_hwnd) == hwnd, "GetParent returns %p\n", GetParent(eb_hwnd));
432
433         /* ::Destroy() destroys the window. */
434         ok(IsWindow(eb_hwnd), "eb_hwnd invalid.\n");
435         IExplorerBrowser_Destroy(peb);
436         ok(!IsWindow(eb_hwnd), "eb_hwnd valid.\n");
437
438         IShellBrowser_Release(psb);
439         lres = IExplorerBrowser_Release(peb);
440         ok(lres == 0, "Got refcount %d\n", lres);
441     }
442     else
443     {
444         skip("Skipping some tests.\n");
445
446         IExplorerBrowser_Destroy(peb);
447         lres = IExplorerBrowser_Release(peb);
448         ok(lres == 0, "Got refcount %d\n", lres);
449     }
450
451     ebrowser_instantiate(&peb);
452     rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
453     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
454     ok(hr == S_OK, "got (0x%08x)\n", hr);
455     IExplorerBrowser_Destroy(peb);
456     lres = IExplorerBrowser_Release(peb);
457     ok(lres == 0, "Got refcount %d\n", lres);
458
459     ebrowser_instantiate(&peb);
460     rc.left = -1; rc.top = -1; rc.right = 1; rc.bottom = 1;
461     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
462     ok(hr == S_OK, "got (0x%08x)\n", hr);
463     IExplorerBrowser_Destroy(peb);
464     lres = IExplorerBrowser_Release(peb);
465     ok(lres == 0, "Got refcount %d\n", lres);
466
467     ebrowser_instantiate(&peb);
468     rc.left = 10; rc.top = 10; rc.right = 5; rc.bottom = 5;
469     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
470     ok(hr == S_OK, "got (0x%08x)\n", hr);
471     IExplorerBrowser_Destroy(peb);
472     lres = IExplorerBrowser_Release(peb);
473     ok(lres == 0, "Got refcount %d\n", lres);
474
475     ebrowser_instantiate(&peb);
476     rc.left = 10; rc.top = 10; rc.right = 5; rc.bottom = 5;
477     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
478     ok(hr == S_OK, "got (0x%08x)\n", hr);
479     IExplorerBrowser_Destroy(peb);
480     lres = IExplorerBrowser_Release(peb);
481     ok(lres == 0, "Got refcount %d\n", lres);
482 }
483
484 static void test_basics(void)
485 {
486     IExplorerBrowser *peb;
487     IShellBrowser *psb;
488     FOLDERSETTINGS fs;
489     ULONG lres;
490     DWORD flags;
491     HDWP hdwp;
492     RECT rc;
493     HRESULT hr;
494
495     ebrowser_instantiate(&peb);
496     ebrowser_initialize(peb);
497
498     /* SetRect */
499     rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
500     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
501     ok(hr == S_OK, "got (0x%08x)\n", hr);
502
503     rc.left = 100; rc.top = 100; rc.right = 10; rc.bottom = 10;
504     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
505     ok(hr == S_OK, "got (0x%08x)\n", hr);
506
507     /* SetRect with DeferWindowPos */
508     rc.left = rc.top = 0; rc.right = rc.bottom = 10;
509     hdwp = BeginDeferWindowPos(1);
510     hr = IExplorerBrowser_SetRect(peb, &hdwp, rc);
511     ok(hr == S_OK, "got (0x%08x)\n", hr);
512     lres = EndDeferWindowPos(hdwp);
513     ok(lres, "EndDeferWindowPos failed.\n");
514
515     hdwp = NULL;
516     hr = IExplorerBrowser_SetRect(peb, &hdwp, rc);
517     ok(hr == S_OK, "got (0x%08x)\n", hr);
518     ok(hdwp == NULL, "got %p\n", hdwp);
519     lres = EndDeferWindowPos(hdwp);
520     ok(!lres, "EndDeferWindowPos succeeded unexpectedly.\n");
521
522     /* Test positioning */
523     rc.left = 10; rc.top = 20; rc.right = 50; rc.bottom = 50;
524     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
525     ok(hr == S_OK, "got (0x%08x)\n", hr);
526     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
527     ok(hr == S_OK, "Got 0x%08x\n", hr);
528     if(SUCCEEDED(hr))
529     {
530         HWND eb_hwnd;
531         RECT eb_rc;
532         static const RECT exp_rc = {11, 21, 49, 49};
533
534         hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
535         ok(hr == S_OK, "Got 0x%08x\n", hr);
536
537         GetClientRect(eb_hwnd, &eb_rc);
538         MapWindowPoints(eb_hwnd, hwnd, (POINT*)&eb_rc, 2);
539         ok(EqualRect(&eb_rc, &exp_rc), "Got rect (%d, %d) - (%d, %d)\n",
540            eb_rc.left, eb_rc.top, eb_rc.right, eb_rc.bottom);
541
542         IShellBrowser_Release(psb);
543     }
544
545     IExplorerBrowser_Destroy(peb);
546     IExplorerBrowser_Release(peb);
547
548     /* GetOptions/SetOptions*/
549     ebrowser_instantiate(&peb);
550
551     if(0) {
552         /* Crashes on Windows 7 */
553         IExplorerBrowser_GetOptions(peb, NULL);
554     }
555
556     hr = IExplorerBrowser_GetOptions(peb, &flags);
557     ok(hr == S_OK, "got (0x%08x)\n", hr);
558     ok(flags == 0, "got (0x%08x)\n", flags);
559
560     /* Settings preserved through Initialize. */
561     hr = IExplorerBrowser_SetOptions(peb, 0xDEADBEEF);
562     ok(hr == S_OK, "got (0x%08x)\n", hr);
563
564     ebrowser_initialize(peb);
565
566     hr = IExplorerBrowser_GetOptions(peb, &flags);
567     ok(flags == 0xDEADBEEF, "got (0x%08x)\n", flags);
568     ok(hr == S_OK, "got (0x%08x)\n", hr);
569
570     IExplorerBrowser_Destroy(peb);
571     IExplorerBrowser_Release(peb);
572
573     ebrowser_instantiate(&peb);
574     ebrowser_initialize(peb);
575
576     /* SetFolderSettings */
577     hr = IExplorerBrowser_SetFolderSettings(peb, NULL);
578     ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
579     fs.ViewMode = 0; fs.fFlags = 0;
580     hr = IExplorerBrowser_SetFolderSettings(peb, &fs);
581     todo_wine ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
582
583     /* TODO: Test after browsing somewhere. */
584
585     IExplorerBrowser_Destroy(peb);
586     lres = IExplorerBrowser_Release(peb);
587     ok(lres == 0, "Got %d\n", lres);
588 }
589
590 static void test_Advise(void)
591 {
592     IExplorerBrowser *peb;
593     IExplorerBrowserEvents *pebe;
594     DWORD cookies[10];
595     HRESULT hr;
596     UINT i, ref;
597
598     /* Set up our IExplorerBrowserEvents implementation */
599     ebev.lpVtbl = &ebevents;
600     pebe = (IExplorerBrowserEvents*) &ebev;
601
602     ebrowser_instantiate(&peb);
603
604     if(0)
605     {
606         /* Crashes on Windows 7 */
607         IExplorerBrowser_Advise(peb, pebe, NULL);
608         IExplorerBrowser_Advise(peb, NULL, &cookies[0]);
609     }
610
611     /* Using Unadvise with a cookie that has yet to be given out
612      * results in E_INVALIDARG */
613     hr = IExplorerBrowser_Unadvise(peb, 11);
614     ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
615
616     /* Add some before initialization */
617     for(i = 0; i < 5; i++)
618     {
619         hr = IExplorerBrowser_Advise(peb, pebe, &cookies[i]);
620         ok(hr == S_OK, "got (0x%08x)\n", hr);
621     }
622
623     ebrowser_initialize(peb);
624
625     /* Add some after initialization */
626     for(i = 5; i < 10; i++)
627     {
628         hr = IExplorerBrowser_Advise(peb, pebe, &cookies[i]);
629         ok(hr == S_OK, "got (0x%08x)\n", hr);
630     }
631
632     ok(ebev.ref == 10, "Got %d\n", ebev.ref);
633
634     ebev.completed = 0;
635     ebrowser_browse_to_desktop(peb);
636     process_msgs();
637     ok(ebev.completed == 10, "Got %d\n", ebev.completed);
638
639     /* Remove a bunch somewhere in the middle */
640     for(i = 4; i < 8; i++)
641     {
642         hr = IExplorerBrowser_Unadvise(peb, cookies[i]);
643         ok(hr == S_OK, "got (0x%08x)\n", hr);
644     }
645
646     ebev.completed = 0;
647     ebrowser_browse_to_desktop(peb);
648     process_msgs();
649     ok(ebev.completed == 6, "Got %d\n", ebev.completed);
650
651     if(0)
652     {
653         /* Using unadvise with a previously unadvised cookie results
654          * in a crash. */
655         hr = IExplorerBrowser_Unadvise(peb, cookies[5]);
656     }
657
658     /* Remove the rest. */
659     for(i = 0; i < 10; i++)
660     {
661         if(i<4||i>7)
662         {
663             hr = IExplorerBrowser_Unadvise(peb, cookies[i]);
664             ok(hr == S_OK, "%d: got (0x%08x)\n", i, hr);
665         }
666     }
667
668     ok(ebev.ref == 0, "Got %d\n", ebev.ref);
669
670     ebev.completed = 0;
671     ebrowser_browse_to_desktop(peb);
672     process_msgs();
673     ok(ebev.completed == 0, "Got %d\n", ebev.completed);
674
675     /* ::Destroy implies ::Unadvise. */
676     hr = IExplorerBrowser_Advise(peb, pebe, &cookies[0]);
677     ok(hr == S_OK, "Got 0x%08x\n", hr);
678     ok(ebev.ref == 1, "Got %d\n", ebev.ref);
679
680     hr = IExplorerBrowser_Destroy(peb);
681     ok(hr == S_OK, "Got 0x%08x\n", hr);
682     ok(ebev.ref == 0, "Got %d\n", ebev.ref);
683
684     ref = IExplorerBrowser_Release(peb);
685     ok(!ref, "Got %d", ref);
686 }
687
688 /* Based on PathAddBackslashW from dlls/shlwapi/path.c */
689 static LPWSTR myPathAddBackslashW( LPWSTR lpszPath )
690 {
691   size_t iLen;
692
693   if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH)
694     return NULL;
695
696   if (iLen)
697   {
698     lpszPath += iLen;
699     if (lpszPath[-1] != '\\')
700     {
701       *lpszPath++ = '\\';
702       *lpszPath = '\0';
703     }
704   }
705   return lpszPath;
706 }
707
708 static void test_browse_pidl_(IExplorerBrowser *peb, IExplorerBrowserEventsImpl *ebev,
709                               LPITEMIDLIST pidl, UINT uFlags,
710                               HRESULT hr_exp, UINT pending, UINT created, UINT failed, UINT completed,
711                               const char *file, int line)
712 {
713     HRESULT hr;
714     ebev->completed = ebev->created = ebev->pending = ebev->failed = 0;
715
716     hr = IExplorerBrowser_BrowseToIDList(peb, pidl, uFlags);
717     ok_(file, line) (hr == hr_exp, "BrowseToIDList returned 0x%08x\n", hr);
718     process_msgs();
719
720     ok_(file, line)
721         (ebev->pending == pending && ebev->created == created &&
722          ebev->failed == failed && ebev->completed == completed,
723          "Events occurred: %d, %d, %d, %d\n",
724          ebev->pending, ebev->created, ebev->failed, ebev->completed);
725 }
726 #define test_browse_pidl(peb, ebev, pidl, uFlags, hr, p, cr, f, co)     \
727     test_browse_pidl_(peb, ebev, pidl, uFlags, hr, p, cr, f, co, __FILE__, __LINE__)
728
729 static void test_browse_pidl_sb_(IExplorerBrowser *peb, IExplorerBrowserEventsImpl *ebev,
730                                  LPITEMIDLIST pidl, UINT uFlags,
731                                  HRESULT hr_exp, UINT pending, UINT created, UINT failed, UINT completed,
732                                  const char *file, int line)
733 {
734     IShellBrowser *psb;
735     HRESULT hr;
736
737     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
738     ok_(file, line) (hr == S_OK, "QueryInterface returned 0x%08x\n", hr);
739     if(SUCCEEDED(hr))
740     {
741         ebev->completed = ebev->created = ebev->pending = ebev->failed = 0;
742
743         hr = IShellBrowser_BrowseObject(psb, pidl, uFlags);
744         ok_(file, line) (hr == hr_exp, "BrowseObject returned 0x%08x\n", hr);
745         process_msgs();
746
747         ok_(file, line)
748             (ebev->pending == pending && ebev->created == created &&
749              ebev->failed == failed && ebev->completed == completed,
750              "Events occurred: %d, %d, %d, %d\n",
751              ebev->pending, ebev->created, ebev->failed, ebev->completed);
752
753         IShellBrowser_Release(psb);
754     }
755 }
756 #define test_browse_pidl_sb(peb, ebev, pidl, uFlags, hr, p, cr, f, co)  \
757     test_browse_pidl_sb_(peb, ebev, pidl, uFlags, hr, p, cr, f, co, __FILE__, __LINE__)
758
759 static void test_navigation(void)
760 {
761     IExplorerBrowser *peb, *peb2;
762     IFolderView *pfv;
763     IShellItem *psi;
764     IShellFolder *psf;
765     LPITEMIDLIST pidl_current, pidl_child;
766     DWORD cookie, cookie2;
767     HRESULT hr;
768     LONG lres;
769     WCHAR current_path[MAX_PATH];
770     WCHAR child_path[MAX_PATH];
771     static const WCHAR testfolderW[] =
772         {'w','i','n','e','t','e','s','t','f','o','l','d','e','r','\0'};
773
774     ok(pSHParseDisplayName != NULL, "pSHParseDisplayName unexpectedly missing.\n");
775     ok(pSHCreateShellItem != NULL, "pSHCreateShellItem unexpectedly missing.\n");
776
777     GetCurrentDirectoryW(MAX_PATH, current_path);
778     if(!lstrlenW(current_path))
779     {
780         skip("Failed to create test-directory.\n");
781         return;
782     }
783
784     lstrcpyW(child_path, current_path);
785     myPathAddBackslashW(child_path);
786     lstrcatW(child_path, testfolderW);
787
788     CreateDirectoryW(child_path, NULL);
789
790     pSHParseDisplayName(current_path, NULL, &pidl_current, 0, NULL);
791     pSHParseDisplayName(child_path, NULL, &pidl_child, 0, NULL);
792
793     ebrowser_instantiate(&peb);
794     ebrowser_initialize(peb);
795
796     ebrowser_instantiate(&peb2);
797     ebrowser_initialize(peb2);
798
799     /* Set up our IExplorerBrowserEvents implementation */
800     ebev.lpVtbl = &ebevents;
801
802     IExplorerBrowser_Advise(peb, (IExplorerBrowserEvents*)&ebev, &cookie);
803     IExplorerBrowser_Advise(peb2, (IExplorerBrowserEvents*)&ebev, &cookie2);
804
805     /* These should all fail */
806     test_browse_pidl(peb, &ebev, 0, SBSP_ABSOLUTE | SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
807     test_browse_pidl_sb(peb2, &ebev, 0, SBSP_ABSOLUTE | SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
808     test_browse_pidl(peb, &ebev, 0, SBSP_ABSOLUTE, E_INVALIDARG, 0, 0, 0, 0);
809     test_browse_pidl_sb(peb2, &ebev, 0, SBSP_ABSOLUTE, E_INVALIDARG, 0, 0, 0, 0);
810     test_browse_pidl(peb, &ebev, 0, SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
811     test_browse_pidl_sb(peb2, &ebev, 0, SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
812     test_browse_pidl(peb, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
813     test_browse_pidl_sb(peb2, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
814
815     /* "The first browse is synchronous" */
816     test_browse_pidl(peb, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
817     test_browse_pidl_sb(peb2, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
818
819     /* Relative navigation */
820     test_browse_pidl(peb, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
821     test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
822
823     hr = IExplorerBrowser_GetCurrentView(peb, &IID_IFolderView, (void**)&pfv);
824     ok(hr == S_OK, "Got 0x%08x\n", hr);
825     if(SUCCEEDED(hr))
826     {
827         LPITEMIDLIST pidl_relative;
828
829         hr = IFolderView_GetFolder(pfv, &IID_IShellFolder, (void**)&psf);
830         ok(hr == S_OK, "Got 0x%08x\n", hr);
831         hr = IShellFolder_ParseDisplayName(psf, NULL, NULL, (LPWSTR)testfolderW,
832                                            NULL, &pidl_relative, NULL);
833         ok(hr == S_OK, "Got 0x%08x\n", hr);
834
835         /* Browsing to another location here before using the
836          * pidl_relative would make ExplorerBrowser in Windows 7 show a
837          * not-available dialog. Also, passing a relative pidl without
838          * specifying SBSP_RELATIVE makes it look for the pidl on the
839          * desktop
840          */
841
842         test_browse_pidl(peb, &ebev, pidl_relative, SBSP_RELATIVE, S_OK, 1, 1, 0, 1);
843         test_browse_pidl_sb(peb2, &ebev, pidl_relative, SBSP_RELATIVE, S_OK, 1, 1, 0, 1);
844
845         ILFree(pidl_relative);
846         /* IShellFolder_Release(psf); */
847         IFolderView_Release(pfv);
848     }
849
850     /* misc **/
851     test_browse_pidl(peb, &ebev, NULL, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
852     test_browse_pidl_sb(peb2, &ebev, NULL, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
853     test_browse_pidl(peb, &ebev, NULL, SBSP_DEFBROWSER, S_OK, 0, 0, 0, 0);
854     test_browse_pidl_sb(peb2, &ebev, NULL, SBSP_DEFBROWSER, S_OK, 0, 0, 0, 0);
855     test_browse_pidl(peb, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 1, 0, 1);
856     test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 1, 0, 1);
857     test_browse_pidl(peb, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 0, 0, 1);
858     test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 0, 0, 1);
859
860     test_browse_pidl(peb, &ebev, pidl_current, SBSP_EXPLOREMODE, E_INVALIDARG, 0, 0, 0, 0);
861     test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_EXPLOREMODE, E_INVALIDARG, 0, 0, 0, 0);
862     test_browse_pidl(peb, &ebev, pidl_current, SBSP_OPENMODE, S_OK, 1, 0, 0, 1);
863     test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_OPENMODE, S_OK, 1, 0, 0, 1);
864
865     /* SBSP_NEWBROWSER will return E_INVALIDARG, claims MSDN, but in
866      * reality it works as one would expect (Windows 7 only?).
867      */
868     if(0)
869     {
870         IExplorerBrowser_BrowseToIDList(peb, NULL, SBSP_NEWBROWSER);
871     }
872
873     hr = IExplorerBrowser_Unadvise(peb, cookie);
874     ok(hr == S_OK, "Got 0x%08x\n", hr);
875     IExplorerBrowser_Destroy(peb);
876     process_msgs();
877     hr = IExplorerBrowser_Unadvise(peb2, cookie2);
878     ok(hr == S_OK, "Got 0x%08x\n", hr);
879     IExplorerBrowser_Destroy(peb2);
880     process_msgs();
881
882     /* Attempt browsing after destroyed */
883     test_browse_pidl(peb, &ebev, pidl_child, SBSP_ABSOLUTE, HRESULT_FROM_WIN32(ERROR_BUSY), 0, 0, 0, 0);
884     test_browse_pidl_sb(peb2, &ebev, pidl_child, SBSP_ABSOLUTE, HRESULT_FROM_WIN32(ERROR_BUSY), 0, 0, 0, 0);
885
886     lres = IExplorerBrowser_Release(peb);
887     ok(lres == 0, "Got lres %d\n", lres);
888     lres = IExplorerBrowser_Release(peb2);
889     ok(lres == 0, "Got lres %d\n", lres);
890
891     /******************************************/
892     /* Test some options that affect browsing */
893
894     ebrowser_instantiate(&peb);
895     hr = IExplorerBrowser_Advise(peb, (IExplorerBrowserEvents*)&ebev, &cookie);
896     ok(hr == S_OK, "Got 0x%08x\n", hr);
897     hr = IExplorerBrowser_SetOptions(peb, EBO_NAVIGATEONCE);
898     ok(hr == S_OK, "got (0x%08x)\n", hr);
899     ebrowser_initialize(peb);
900
901     test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 1, 0, 1);
902     test_browse_pidl(peb, &ebev, pidl_current, 0, E_FAIL, 0, 0, 0, 0);
903
904     hr = IExplorerBrowser_SetOptions(peb, 0);
905     ok(hr == S_OK, "got (0x%08x)\n", hr);
906
907     test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
908     test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
909
910     /* Difference in behavior lies where? */
911     hr = IExplorerBrowser_SetOptions(peb, EBO_ALWAYSNAVIGATE);
912     ok(hr == S_OK, "got (0x%08x)\n", hr);
913
914     test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
915     test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
916
917     hr = IExplorerBrowser_Unadvise(peb, cookie);
918     ok(hr == S_OK, "Got 0x%08x\n", hr);
919
920     IExplorerBrowser_Destroy(peb);
921     lres = IExplorerBrowser_Release(peb);
922     ok(lres == 0, "Got lres %d\n", lres);
923
924     /* BrowseToObject tests */
925     ebrowser_instantiate(&peb);
926     ebrowser_initialize(peb);
927
928     /* Browse to the desktop by passing an IShellFolder */
929     hr = SHGetDesktopFolder(&psf);
930     ok(hr == S_OK, "Got 0x%08x\n", hr);
931     if(SUCCEEDED(hr))
932     {
933         hr = IExplorerBrowser_BrowseToObject(peb, (IUnknown*)psf, SBSP_DEFBROWSER);
934         ok(hr == S_OK, "got (0x%08x)\n", hr);
935         if(hr == S_OK) process_msgs();
936
937         IShellFolder_Release(psf);
938     }
939
940     /* Browse to the current directory by passing a ShellItem */
941     hr = pSHCreateShellItem(NULL, NULL, pidl_current, &psi);
942     ok(hr == S_OK, "Got 0x%08x\n", hr);
943     if(SUCCEEDED(hr))
944     {
945         hr = IExplorerBrowser_BrowseToObject(peb, (IUnknown*)psi, SBSP_DEFBROWSER);
946         ok(hr == S_OK, "got (0x%08x)\n", hr);
947         process_msgs();
948
949         IShellItem_Release(psi);
950     }
951
952     IExplorerBrowser_Destroy(peb);
953     lres = IExplorerBrowser_Release(peb);
954     ok(lres == 0, "Got lres %d\n", lres);
955
956     /* Cleanup */
957     RemoveDirectoryW(child_path);
958     ILFree(pidl_current);
959     ILFree(pidl_child);
960 }
961
962 static void test_GetCurrentView(void)
963 {
964     IExplorerBrowser *peb;
965     IUnknown *punk;
966     HRESULT hr;
967
968     /* GetCurrentView */
969     ebrowser_instantiate(&peb);
970
971     if(0)
972     {
973         /* Crashes under Windows 7 */
974         hr = IExplorerBrowser_GetCurrentView(peb, NULL, NULL);
975     }
976     hr = IExplorerBrowser_GetCurrentView(peb, NULL, (void**)&punk);
977     ok(hr == E_FAIL, "Got 0x%08x\n", hr);
978
979 #define test_gcv(iid, exp)                                              \
980     do {                                                                \
981         hr = IExplorerBrowser_GetCurrentView(peb, &iid, (void**)&punk); \
982         ok(hr == exp, "(%s:)Expected (0x%08x), got: (0x%08x)\n",        \
983            #iid ,exp, hr);                                              \
984         if(SUCCEEDED(hr)) IUnknown_Release(punk);                       \
985     } while(0)
986
987     test_gcv(IID_IUnknown, E_FAIL);
988     test_gcv(IID_IUnknown, E_FAIL);
989     test_gcv(IID_IShellView, E_FAIL);
990     test_gcv(IID_IShellView2, E_FAIL);
991     test_gcv(IID_IFolderView, E_FAIL);
992     test_gcv(IID_IPersistFolder, E_FAIL);
993     test_gcv(IID_IPersistFolder2, E_FAIL);
994     test_gcv(IID_ICommDlgBrowser, E_FAIL);
995     test_gcv(IID_ICommDlgBrowser2, E_FAIL);
996     test_gcv(IID_ICommDlgBrowser3, E_FAIL);
997
998     ebrowser_initialize(peb);
999     ebrowser_browse_to_desktop(peb);
1000
1001     test_gcv(IID_IUnknown, S_OK);
1002     test_gcv(IID_IUnknown, S_OK);
1003     test_gcv(IID_IShellView, S_OK);
1004     test_gcv(IID_IShellView2, S_OK);
1005     test_gcv(IID_IFolderView, S_OK);
1006     todo_wine test_gcv(IID_IPersistFolder, S_OK);
1007     test_gcv(IID_IPersistFolder2, E_NOINTERFACE);
1008     test_gcv(IID_ICommDlgBrowser, E_NOINTERFACE);
1009     test_gcv(IID_ICommDlgBrowser2, E_NOINTERFACE);
1010     test_gcv(IID_ICommDlgBrowser3, E_NOINTERFACE);
1011
1012 #undef test_gcv
1013
1014     IExplorerBrowser_Destroy(peb);
1015     IExplorerBrowser_Release(peb);
1016 }
1017
1018 static BOOL test_instantiate_control(void)
1019 {
1020     IExplorerBrowser *peb;
1021     HRESULT hr;
1022
1023     hr = ebrowser_instantiate(&peb);
1024     ok(hr == S_OK || hr == REGDB_E_CLASSNOTREG, "Got (0x%08x)\n", hr);
1025     if(FAILED(hr))
1026         return FALSE;
1027
1028     IExplorerBrowser_Release(peb);
1029     return TRUE;
1030 }
1031
1032 static void setup_window(void)
1033 {
1034     WNDCLASSW wc;
1035     static const WCHAR ebtestW[] = {'e','b','t','e','s','t',0};
1036
1037     ZeroMemory(&wc, sizeof(WNDCLASSW));
1038     wc.lpfnWndProc      = DefWindowProcW;
1039     wc.lpszClassName    = ebtestW;
1040     RegisterClassW(&wc);
1041     hwnd = CreateWindowExW(0, ebtestW, NULL, 0,
1042                            0, 0, 500, 500,
1043                            NULL, 0, 0, NULL);
1044     ok(hwnd != NULL, "Failed to create window for tests.\n");
1045 }
1046
1047 START_TEST(ebrowser)
1048 {
1049     OleInitialize(NULL);
1050
1051     if(!test_instantiate_control())
1052     {
1053         win_skip("No ExplorerBrowser control..\n");
1054         OleUninitialize();
1055         return;
1056     }
1057
1058     setup_window();
1059     init_function_pointers();
1060
1061     test_QueryInterface();
1062     test_SB_misc();
1063     test_initialization();
1064     test_basics();
1065     test_Advise();
1066     test_navigation();
1067     test_GetCurrentView();
1068
1069     DestroyWindow(hwnd);
1070     OleUninitialize();
1071 }