cryptnet: Constify a variable.
[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 /*********************************************************************
32  * Some simple helpers
33  */
34 static HRESULT ebrowser_instantiate(IExplorerBrowser **peb)
35 {
36     return CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
37                             &IID_IExplorerBrowser, (void**)peb);
38 }
39
40 static HRESULT ebrowser_initialize(IExplorerBrowser *peb)
41 {
42     RECT rc;
43     rc.top = rc.left = 0; rc.bottom = rc.right = 500;
44     return IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
45 }
46
47 static void test_QueryInterface(void)
48 {
49     IExplorerBrowser *peb;
50     IUnknown *punk;
51     HRESULT hr;
52     LONG lres;
53
54     hr = ebrowser_instantiate(&peb);
55     ok(hr == S_OK, "Got 0x%08x\n", hr);
56
57 #define test_qinterface(iid, exp)                                       \
58     do {                                                                \
59         hr = IExplorerBrowser_QueryInterface(peb, &iid, (void**)&punk); \
60         ok(hr == exp, "(%s:)Expected (0x%08x), got (0x%08x)\n",         \
61            #iid, exp, hr);                                              \
62         if(SUCCEEDED(hr)) IUnknown_Release(punk);                       \
63     } while(0)
64
65     test_qinterface(IID_IUnknown, S_OK);
66     test_qinterface(IID_IExplorerBrowser, S_OK);
67     test_qinterface(IID_IShellBrowser, S_OK);
68     todo_wine test_qinterface(IID_IOleWindow, S_OK);
69     todo_wine test_qinterface(IID_ICommDlgBrowser, S_OK);
70     todo_wine test_qinterface(IID_ICommDlgBrowser2, S_OK);
71     todo_wine test_qinterface(IID_ICommDlgBrowser3, S_OK);
72     todo_wine test_qinterface(IID_IServiceProvider, S_OK);
73     todo_wine test_qinterface(IID_IObjectWithSite, S_OK);
74     todo_wine test_qinterface(IID_IConnectionPointContainer, S_OK);
75     test_qinterface(IID_IOleObject, E_NOINTERFACE);
76     test_qinterface(IID_IViewObject, E_NOINTERFACE);
77     test_qinterface(IID_IViewObject2, E_NOINTERFACE);
78     test_qinterface(IID_IViewObjectEx, E_NOINTERFACE);
79     test_qinterface(IID_IConnectionPoint, E_NOINTERFACE);
80     test_qinterface(IID_IShellView, E_NOINTERFACE);
81     test_qinterface(IID_INameSpaceTreeControlEvents, E_NOINTERFACE);
82
83 #undef test_qinterface
84
85     lres = IExplorerBrowser_Release(peb);
86     ok(lres == 0, "Got %d\n", lres);
87 }
88
89 static void test_SB_misc(void)
90 {
91     IExplorerBrowser *peb;
92     IShellBrowser *psb;
93     HRESULT hr;
94     HWND retHwnd;
95     LONG lres;
96
97     ebrowser_instantiate(&peb);
98     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
99     ok(hr == S_OK, "Got 0x%08x\n", hr);
100     if(FAILED(hr))
101     {
102         skip("Failed to get IShellBrowser interface.\n");
103         return;
104     }
105
106     /* Some unimplemented methods */
107     retHwnd = (HWND)0xDEADBEEF;
108     hr = IShellBrowser_GetControlWindow(psb, FCW_TOOLBAR, &retHwnd);
109     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
110     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
111
112     hr = IShellBrowser_GetControlWindow(psb, FCW_STATUS, &retHwnd);
113     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
114     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
115
116     hr = IShellBrowser_GetControlWindow(psb, FCW_TREE, &retHwnd);
117     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
118     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
119
120     hr = IShellBrowser_GetControlWindow(psb, FCW_PROGRESS, &retHwnd);
121     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
122     ok(retHwnd == (HWND)0xDEADBEEF, "HWND overwritten\n");
123
124     /* ::InsertMenuSB */
125     hr = IShellBrowser_InsertMenusSB(psb, NULL, NULL);
126     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
127
128     /* ::RemoveMenusSB */
129     hr = IShellBrowser_RemoveMenusSB(psb, NULL);
130     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
131
132     /* ::SetMenuSB */
133     hr = IShellBrowser_SetMenuSB(psb, NULL, NULL, NULL);
134     ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
135
136     IShellBrowser_Release(psb);
137     lres = IExplorerBrowser_Release(peb);
138     ok(lres == 0, "Got %d\n", lres);
139 }
140
141 static void test_initialization(void)
142 {
143     IExplorerBrowser *peb;
144     IShellBrowser *psb;
145     HRESULT hr;
146     ULONG lres;
147     RECT rc;
148
149     ebrowser_instantiate(&peb);
150
151     if(0)
152     {
153         /* Crashes on Windows 7 */
154         hr = IExplorerBrowser_Initialize(peb, NULL, NULL, NULL);
155         hr = IExplorerBrowser_Initialize(peb, hwnd, NULL, NULL);
156     }
157
158     ZeroMemory(&rc, sizeof(RECT));
159
160     hr = IExplorerBrowser_Initialize(peb, NULL, &rc, NULL);
161     ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
162
163     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
164     ok(hr == S_OK, "got (0x%08x)\n", hr);
165
166     /* Initialize twice */
167     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
168     ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
169
170     hr = IExplorerBrowser_Destroy(peb);
171     ok(hr == S_OK, "got (0x%08x)\n", hr);
172
173     /* Initialize again */
174     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
175     ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
176
177     /* Destroy again */
178     hr = IExplorerBrowser_Destroy(peb);
179     ok(hr == S_OK, "got (0x%08x)\n", hr);
180     lres = IExplorerBrowser_Release(peb);
181     ok(lres == 0, "Got %d\n", lres);
182
183     /* Initialize with a few different rectangles */
184     peb = NULL;
185     ebrowser_instantiate(&peb);
186     rc.left = 50; rc.top = 20; rc.right = 100; rc.bottom = 80;
187     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
188     ok(hr == S_OK, "got (0x%08x)\n", hr);
189     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
190     ok(hr == S_OK, "Got 0x%08x\n", hr);
191     if(SUCCEEDED(hr))
192     {
193         HWND eb_hwnd;
194         RECT eb_rc;
195         char buf[1024];
196         LONG style, expected_style;
197         static const RECT exp_rc = {0, 0, 48, 58};
198
199         hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
200         ok(hr == S_OK, "Got 0x%08x\n", hr);
201
202         GetClientRect(eb_hwnd, &eb_rc);
203         ok(EqualRect(&eb_rc, &exp_rc), "Got client rect (%d, %d)-(%d, %d)\n",
204            eb_rc.left, eb_rc.top, eb_rc.right, eb_rc.bottom);
205
206         GetWindowRect(eb_hwnd, &eb_rc);
207         ok(eb_rc.right - eb_rc.left == 50, "Got window width %d\n", eb_rc.right - eb_rc.left);
208         ok(eb_rc.bottom - eb_rc.top == 60, "Got window height %d\n", eb_rc.bottom - eb_rc.top);
209
210         buf[0] = '\0';
211         GetClassNameA(eb_hwnd, buf, 1024);
212         ok(!lstrcmpA(buf, "ExplorerBrowserControl"), "Unexpected classname %s\n", buf);
213
214         expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER;
215         style = GetWindowLongPtrW(eb_hwnd, GWL_STYLE);
216         todo_wine ok(style == expected_style, "Got style 0x%08x, expected 0x%08x\n", style, expected_style);
217
218         expected_style = WS_EX_CONTROLPARENT;
219         style = GetWindowLongPtrW(eb_hwnd, GWL_EXSTYLE);
220         ok(style == expected_style, "Got exstyle 0x%08x, expected 0x%08x\n", style, expected_style);
221
222         ok(GetParent(eb_hwnd) == hwnd, "GetParent returns %p\n", GetParent(eb_hwnd));
223
224         /* ::Destroy() destroys the window. */
225         ok(IsWindow(eb_hwnd), "eb_hwnd invalid.\n");
226         IExplorerBrowser_Destroy(peb);
227         ok(!IsWindow(eb_hwnd), "eb_hwnd valid.\n");
228
229         IShellBrowser_Release(psb);
230         lres = IExplorerBrowser_Release(peb);
231         ok(lres == 0, "Got refcount %d\n", lres);
232     }
233     else
234     {
235         skip("Skipping some tests.\n");
236
237         IExplorerBrowser_Destroy(peb);
238         lres = IExplorerBrowser_Release(peb);
239         ok(lres == 0, "Got refcount %d\n", lres);
240     }
241
242     ebrowser_instantiate(&peb);
243     rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
244     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
245     ok(hr == S_OK, "got (0x%08x)\n", hr);
246     IExplorerBrowser_Destroy(peb);
247     lres = IExplorerBrowser_Release(peb);
248     ok(lres == 0, "Got refcount %d\n", lres);
249
250     ebrowser_instantiate(&peb);
251     rc.left = -1; rc.top = -1; rc.right = 1; rc.bottom = 1;
252     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
253     ok(hr == S_OK, "got (0x%08x)\n", hr);
254     IExplorerBrowser_Destroy(peb);
255     lres = IExplorerBrowser_Release(peb);
256     ok(lres == 0, "Got refcount %d\n", lres);
257
258     ebrowser_instantiate(&peb);
259     rc.left = 10; rc.top = 10; rc.right = 5; rc.bottom = 5;
260     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
261     ok(hr == S_OK, "got (0x%08x)\n", hr);
262     IExplorerBrowser_Destroy(peb);
263     lres = IExplorerBrowser_Release(peb);
264     ok(lres == 0, "Got refcount %d\n", lres);
265
266     ebrowser_instantiate(&peb);
267     rc.left = 10; rc.top = 10; rc.right = 5; rc.bottom = 5;
268     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
269     ok(hr == S_OK, "got (0x%08x)\n", hr);
270     IExplorerBrowser_Destroy(peb);
271     lres = IExplorerBrowser_Release(peb);
272     ok(lres == 0, "Got refcount %d\n", lres);
273 }
274
275 static void test_basics(void)
276 {
277     IExplorerBrowser *peb;
278     IShellBrowser *psb;
279     FOLDERSETTINGS fs;
280     ULONG lres;
281     DWORD flags;
282     HDWP hdwp;
283     RECT rc;
284     HRESULT hr;
285
286     ebrowser_instantiate(&peb);
287     ebrowser_initialize(peb);
288
289     /* SetRect */
290     rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
291     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
292     ok(hr == S_OK, "got (0x%08x)\n", hr);
293
294     rc.left = 100; rc.top = 100; rc.right = 10; rc.bottom = 10;
295     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
296     ok(hr == S_OK, "got (0x%08x)\n", hr);
297
298     /* SetRect with DeferWindowPos */
299     rc.left = rc.top = 0; rc.right = rc.bottom = 10;
300     hdwp = BeginDeferWindowPos(1);
301     hr = IExplorerBrowser_SetRect(peb, &hdwp, rc);
302     ok(hr == S_OK, "got (0x%08x)\n", hr);
303     lres = EndDeferWindowPos(hdwp);
304     ok(lres, "EndDeferWindowPos failed.\n");
305
306     hdwp = NULL;
307     hr = IExplorerBrowser_SetRect(peb, &hdwp, rc);
308     ok(hr == S_OK, "got (0x%08x)\n", hr);
309     ok(hdwp == NULL, "got %p\n", hdwp);
310     lres = EndDeferWindowPos(hdwp);
311     ok(!lres, "EndDeferWindowPos succeeded unexpectedly.\n");
312
313     /* Test positioning */
314     rc.left = 10; rc.top = 20; rc.right = 50; rc.bottom = 50;
315     hr = IExplorerBrowser_SetRect(peb, NULL, rc);
316     ok(hr == S_OK, "got (0x%08x)\n", hr);
317     hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
318     ok(hr == S_OK, "Got 0x%08x\n", hr);
319     if(SUCCEEDED(hr))
320     {
321         HWND eb_hwnd;
322         RECT eb_rc;
323         static const RECT exp_rc = {11, 21, 49, 49};
324
325         hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
326         ok(hr == S_OK, "Got 0x%08x\n", hr);
327
328         GetClientRect(eb_hwnd, &eb_rc);
329         MapWindowPoints(eb_hwnd, hwnd, (POINT*)&eb_rc, 2);
330         ok(EqualRect(&eb_rc, &exp_rc), "Got rect (%d, %d) - (%d, %d)\n",
331            eb_rc.left, eb_rc.top, eb_rc.right, eb_rc.bottom);
332
333         IShellBrowser_Release(psb);
334     }
335
336     IExplorerBrowser_Destroy(peb);
337     IExplorerBrowser_Release(peb);
338
339     /* GetOptions/SetOptions*/
340     ebrowser_instantiate(&peb);
341
342     if(0) {
343         /* Crashes on Windows 7 */
344         IExplorerBrowser_GetOptions(peb, NULL);
345     }
346
347     hr = IExplorerBrowser_GetOptions(peb, &flags);
348     ok(hr == S_OK, "got (0x%08x)\n", hr);
349     ok(flags == 0, "got (0x%08x)\n", flags);
350
351     /* Settings preserved through Initialize. */
352     hr = IExplorerBrowser_SetOptions(peb, 0xDEADBEEF);
353     ok(hr == S_OK, "got (0x%08x)\n", hr);
354
355     ebrowser_initialize(peb);
356
357     hr = IExplorerBrowser_GetOptions(peb, &flags);
358     ok(flags == 0xDEADBEEF, "got (0x%08x)\n", flags);
359     ok(hr == S_OK, "got (0x%08x)\n", hr);
360
361     IExplorerBrowser_Destroy(peb);
362     IExplorerBrowser_Release(peb);
363
364     ebrowser_instantiate(&peb);
365     ebrowser_initialize(peb);
366
367     /* SetFolderSettings */
368     hr = IExplorerBrowser_SetFolderSettings(peb, NULL);
369     ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
370     fs.ViewMode = 0; fs.fFlags = 0;
371     hr = IExplorerBrowser_SetFolderSettings(peb, &fs);
372     todo_wine ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
373
374     /* TODO: Test after browsing somewhere. */
375
376     IExplorerBrowser_Destroy(peb);
377     lres = IExplorerBrowser_Release(peb);
378     ok(lres == 0, "Got %d\n", lres);
379 }
380
381 static BOOL test_instantiate_control(void)
382 {
383     IExplorerBrowser *peb;
384     HRESULT hr;
385
386     hr = ebrowser_instantiate(&peb);
387     ok(hr == S_OK || hr == REGDB_E_CLASSNOTREG, "Got (0x%08x)\n", hr);
388     if(FAILED(hr))
389         return FALSE;
390
391     IExplorerBrowser_Release(peb);
392     return TRUE;
393 }
394
395 static void setup_window(void)
396 {
397     WNDCLASSW wc;
398     static const WCHAR ebtestW[] = {'e','b','t','e','s','t',0};
399
400     ZeroMemory(&wc, sizeof(WNDCLASSW));
401     wc.lpfnWndProc      = DefWindowProcW;
402     wc.lpszClassName    = ebtestW;
403     RegisterClassW(&wc);
404     hwnd = CreateWindowExW(0, ebtestW, NULL, 0,
405                            0, 0, 500, 500,
406                            NULL, 0, 0, NULL);
407     ok(hwnd != NULL, "Failed to create window for tests.\n");
408 }
409
410 START_TEST(ebrowser)
411 {
412     OleInitialize(NULL);
413
414     if(!test_instantiate_control())
415     {
416         win_skip("No ExplorerBrowser control..\n");
417         OleUninitialize();
418         return;
419     }
420
421     setup_window();
422
423     test_QueryInterface();
424     test_SB_misc();
425     test_initialization();
426     test_basics();
427
428     DestroyWindow(hwnd);
429     OleUninitialize();
430 }