2 * Unit test of the IShellView
4 * Copyright 2010 Nikolay Sivov for CodeWeavers
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.
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.
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
39 #include "wine/test.h"
43 #define LISTVIEW_SEQ_INDEX 0
44 #define NUM_MSG_SEQUENCES 1
46 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
48 static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
50 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
51 static LONG defwndproc_counter = 0;
55 trace("listview: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
57 msg.message = message;
58 msg.flags = sent|wparam|lparam;
59 if (defwndproc_counter) msg.flags |= defwinproc;
62 add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
65 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
70 static HWND subclass_listview(HWND hwnd)
75 /* listview is a first child */
76 listview = FindWindowExA(hwnd, NULL, WC_LISTVIEWA, NULL);
78 oldproc = (WNDPROC)SetWindowLongPtrA(listview, GWLP_WNDPROC,
79 (LONG_PTR)listview_subclass_proc);
80 SetWindowLongPtrA(listview, GWLP_USERDATA, (LONG_PTR)oldproc);
87 const IShellBrowserVtbl *lpVtbl;
91 /* dummy IShellBrowser implementation */
92 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
94 IShellBrowser* IShellBrowserImpl_Construct(void)
96 IShellBrowserImpl *browser;
98 browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
99 browser->lpVtbl = &IShellBrowserImpl_Vtbl;
102 return (IShellBrowser*)browser;
105 static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
109 IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
113 if(IsEqualIID(riid, &IID_IUnknown))
117 else if(IsEqualIID(riid, &IID_IOleWindow))
121 else if(IsEqualIID(riid, &IID_IShellBrowser))
128 IUnknown_AddRef( (IShellBrowser*) *ppvObj);
132 return E_NOINTERFACE;
135 static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
137 IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
138 return InterlockedIncrement(&This->ref);
141 static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
143 IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
144 ULONG ref = InterlockedDecrement(&This->ref);
148 HeapFree(GetProcessHeap(), 0, This);
154 static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser *iface,
157 if (phwnd) *phwnd = GetDesktopWindow();
161 static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser *iface,
167 static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
174 static HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
181 static HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
189 static HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
197 static HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
199 LPOLEMENUGROUPWIDTHS lpMenuWidths)
205 static HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
212 static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
219 static HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
226 static HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
237 static HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
239 HOLEMENU holemenuReserved,
240 HWND hwndActiveObject)
246 static HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
247 LPCOLESTR lpszStatusText)
253 static HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
254 LPTBBUTTON lpButtons,
262 static HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
270 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl =
272 IShellBrowserImpl_QueryInterface,
273 IShellBrowserImpl_AddRef,
274 IShellBrowserImpl_Release,
275 IShellBrowserImpl_GetWindow,
276 IShellBrowserImpl_ContextSensitiveHelp,
277 IShellBrowserImpl_InsertMenusSB,
278 IShellBrowserImpl_SetMenuSB,
279 IShellBrowserImpl_RemoveMenusSB,
280 IShellBrowserImpl_SetStatusTextSB,
281 IShellBrowserImpl_EnableModelessSB,
282 IShellBrowserImpl_TranslateAcceleratorSB,
283 IShellBrowserImpl_BrowseObject,
284 IShellBrowserImpl_GetViewStateStream,
285 IShellBrowserImpl_GetControlWindow,
286 IShellBrowserImpl_SendControlMsg,
287 IShellBrowserImpl_QueryActiveShellView,
288 IShellBrowserImpl_OnViewWindowActive,
289 IShellBrowserImpl_SetToolbarItems
292 static const struct message empty_seq[] = {
296 static const struct message folderview_getspacing_seq[] = {
297 { LVM_GETITEMSPACING, wparam|sent, FALSE },
301 static const struct message folderview_getselectionmarked_seq[] = {
302 { LVM_GETSELECTIONMARK, sent },
306 static const struct message folderview_getfocused_seq[] = {
307 { LVM_GETNEXTITEM, sent|wparam|lparam, -1, LVNI_FOCUSED },
311 static const struct message folderview_itemcount_seq[] = {
312 { LVM_GETITEMCOUNT, sent },
316 static void test_IShellView_CreateViewWindow(void)
318 IShellFolder *desktop;
319 FOLDERSETTINGS settings;
326 hr = SHGetDesktopFolder(&desktop);
327 ok(hr == S_OK, "got (0x%08x)\n", hr);
329 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
330 ok(hr == S_OK, "got (0x%08x)\n", hr);
334 /* crashes on native */
335 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
338 settings.ViewMode = FVM_ICON;
340 hwnd_view = (HWND)0xdeadbeef;
341 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, &hwnd_view);
342 ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
343 ok(hwnd_view == 0, "got %p\n", hwnd_view);
345 hwnd_view = (HWND)0xdeadbeef;
346 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, &r, &hwnd_view);
347 ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
348 ok(hwnd_view == 0, "got %p\n", hwnd_view);
350 /* ::DragLeave without drag operation */
351 hr = IShellView_QueryInterface(view, &IID_IDropTarget, (void**)&dt);
352 ok(hr == S_OK, "got (0x%08x)\n", hr);
353 hr = IDropTarget_DragLeave(dt);
354 ok(hr == S_OK, "got (0x%08x)\n", hr);
355 IDropTarget_Release(dt);
357 IShellView_Release(view);
358 IShellFolder_Release(desktop);
361 static void test_IFolderView(void)
363 IShellFolder *desktop, *folder;
364 FOLDERSETTINGS settings;
366 IShellBrowser *browser;
368 HWND hwnd_view, hwnd_list;
375 hr = SHGetDesktopFolder(&desktop);
376 ok(hr == S_OK, "got (0x%08x)\n", hr);
378 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
379 ok(hr == S_OK, "got (0x%08x)\n", hr);
381 hr = IShellView_QueryInterface(view, &IID_IFolderView, (void**)&fv);
384 win_skip("IFolderView not supported by desktop folder\n");
385 IShellView_Release(view);
386 IShellFolder_Release(desktop);
390 /* call methods before window creation */
391 hr = IFolderView_GetSpacing(fv, NULL);
392 ok(hr == S_FALSE || broken(hr == S_OK) /* win7 */, "got (0x%08x)\n", hr);
396 /* crashes on Vista and Win2k8 - List not created yet case */
397 hr = IFolderView_GetSpacing(fv, &pt);
400 hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
401 hr = IFolderView_GetFocusedItem(fv, NULL);
404 browser = IShellBrowserImpl_Construct();
406 settings.ViewMode = FVM_ICON;
408 hwnd_view = (HWND)0xdeadbeef;
410 r.right = r.bottom = 100;
411 hr = IShellView_CreateViewWindow(view, NULL, &settings, browser, &r, &hwnd_view);
412 ok(hr == S_OK, "got (0x%08x)\n", hr);
413 ok(IsWindow(hwnd_view), "got %p\n", hwnd_view);
415 hwnd_list = subclass_listview(hwnd_view);
418 win_skip("Failed to subclass ListView control\n");
419 IShellBrowser_Release(browser);
420 IFolderView_Release(fv);
421 IShellView_Release(view);
422 IShellFolder_Release(desktop);
426 /* IFolderView::GetSpacing */
427 flush_sequences(sequences, NUM_MSG_SEQUENCES);
428 hr = IFolderView_GetSpacing(fv, NULL);
429 ok(hr == S_OK, "got (0x%08x)\n", hr);
430 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetSpacing, empty", FALSE);
432 flush_sequences(sequences, NUM_MSG_SEQUENCES);
433 hr = IFolderView_GetSpacing(fv, &pt);
434 ok(hr == S_OK, "got (0x%08x)\n", hr);
435 /* fails with empty sequence on win7 for unknown reason */
436 if (sequences[LISTVIEW_SEQ_INDEX]->count)
438 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getspacing_seq, "IFolderView::GetSpacing", FALSE);
439 ok(pt.x > 0, "got %d\n", pt.x);
440 ok(pt.y > 0, "got %d\n", pt.y);
441 ret = SendMessageA(hwnd_list, LVM_GETITEMSPACING, 0, 0);
442 ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret));
445 /* IFolderView::GetSelectionMarkedItem */
449 hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
452 flush_sequences(sequences, NUM_MSG_SEQUENCES);
453 hr = IFolderView_GetSelectionMarkedItem(fv, &ret);
454 ok(hr == S_OK, "got (0x%08x)\n", hr);
455 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq,
456 "IFolderView::GetSelectionMarkedItem", FALSE);
458 /* IFolderView::GetFocusedItem */
459 flush_sequences(sequences, NUM_MSG_SEQUENCES);
460 hr = IFolderView_GetFocusedItem(fv, &ret);
461 ok(hr == S_OK, "got (0x%08x)\n", hr);
462 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq,
463 "IFolderView::GetFocusedItem", FALSE);
465 /* IFolderView::GetFolder, just return pointer */
469 hr = IFolderView_GetFolder(fv, NULL, (void**)&folder);
470 hr = IFolderView_GetFolder(fv, NULL, NULL);
473 hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL);
474 ok(hr == E_POINTER, "got (0x%08x)\n", hr);
476 ref1 = IShellFolder_AddRef(desktop);
477 IShellFolder_Release(desktop);
478 hr = IFolderView_GetFolder(fv, &IID_IShellFolder, (void**)&folder);
479 ok(hr == S_OK, "got (0x%08x)\n", hr);
480 ref2 = IShellFolder_AddRef(desktop);
481 IShellFolder_Release(desktop);
482 ok(ref1 == ref2, "expected same refcount, got %d\n", ref2);
483 ok(desktop == folder, "\n");
485 /* IFolderView::ItemCount */
489 hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL);
492 flush_sequences(sequences, NUM_MSG_SEQUENCES);
493 hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &ret);
494 ok(hr == S_OK, "got (0x%08x)\n", hr);
495 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_itemcount_seq,
496 "IFolderView::ItemCount", FALSE);
498 IShellBrowser_Release(browser);
499 IFolderView_Release(fv);
500 IShellView_Release(view);
501 IShellFolder_Release(desktop);
508 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
510 test_IShellView_CreateViewWindow();