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
41 #include "wine/test.h"
45 #define LISTVIEW_SEQ_INDEX 0
46 #define NUM_MSG_SEQUENCES 1
48 DEFINE_GUID(IID_IPersistHistory, 0x91a565c1, 0xe38f, 0x11d0, 0x94, 0xbf, 0x00, 0xa0, 0xc9, 0x05, 0x5c, 0xbf);
50 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
52 static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
54 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
55 static LONG defwndproc_counter = 0;
59 trace("listview: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
61 msg.message = message;
62 msg.flags = sent|wparam|lparam;
63 if (defwndproc_counter) msg.flags |= defwinproc;
66 add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
69 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
74 static HWND subclass_listview(HWND hwnd)
79 /* listview is a first child */
80 listview = FindWindowExA(hwnd, NULL, WC_LISTVIEWA, NULL);
83 /* .. except for some versions of Windows XP, where things
84 are slightly more complicated. */
86 hwnd_tmp = FindWindowExA(hwnd, NULL, "DUIViewWndClassName", NULL);
87 hwnd_tmp = FindWindowExA(hwnd_tmp, NULL, "DirectUIHWND", NULL);
88 hwnd_tmp = FindWindowExA(hwnd_tmp, NULL, "CtrlNotifySink", NULL);
89 listview = FindWindowExA(hwnd_tmp, NULL, WC_LISTVIEWA, NULL);
92 oldproc = (WNDPROC)SetWindowLongPtrA(listview, GWLP_WNDPROC,
93 (LONG_PTR)listview_subclass_proc);
94 SetWindowLongPtrA(listview, GWLP_USERDATA, (LONG_PTR)oldproc);
99 static UINT get_msg_count(struct msg_sequence **seq, int sequence_index, UINT message)
101 struct msg_sequence *msg_seq = seq[sequence_index];
104 for(i = 0; i < msg_seq->count ; i++)
105 if(msg_seq->sequence[i].message == message)
111 /* Checks that every message in the sequence seq is also present in
112 * the UINT array msgs */
113 static void verify_msgs_in_(struct msg_sequence *seq, const UINT *msgs,
114 const char *file, int line)
116 UINT i, j, msg, failcount = 0;
117 for(i = 0; i < seq->count; i++)
120 msg = seq->sequence[i].message;
121 for(j = 0; msgs[j] != 0; j++)
122 if(msgs[j] == msg) found = TRUE;
127 trace("Unexpected message %d\n", msg);
130 ok_(file, line) (!failcount, "%d failures.\n", failcount);
131 flush_sequences(sequences, NUM_MSG_SEQUENCES);
134 #define verify_msgs_in(seq, msgs) \
135 verify_msgs_in_(seq, msgs, __FILE__, __LINE__)
137 /* dummy IDataObject implementation */
139 IDataObject IDataObject_iface;
143 static const IDataObjectVtbl IDataObjectImpl_Vtbl;
145 static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
147 return CONTAINING_RECORD(iface, IDataObjectImpl, IDataObject_iface);
150 static IDataObject* IDataObjectImpl_Construct(void)
152 IDataObjectImpl *obj;
154 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
155 obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl;
158 return &obj->IDataObject_iface;
161 static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, void **ppvObj)
163 IDataObjectImpl *This = impl_from_IDataObject(iface);
165 if (IsEqualIID(riid, &IID_IUnknown) ||
166 IsEqualIID(riid, &IID_IDataObject))
173 IUnknown_AddRef(iface);
177 return E_NOINTERFACE;
180 static ULONG WINAPI IDataObjectImpl_AddRef(IDataObject * iface)
182 IDataObjectImpl *This = impl_from_IDataObject(iface);
183 return InterlockedIncrement(&This->ref);
186 static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
188 IDataObjectImpl *This = impl_from_IDataObject(iface);
189 ULONG ref = InterlockedDecrement(&This->ref);
193 HeapFree(GetProcessHeap(), 0, This);
199 static HRESULT WINAPI IDataObjectImpl_GetData(IDataObject *iface, FORMATETC *pformat, STGMEDIUM *pmedium)
204 static HRESULT WINAPI IDataObjectImpl_GetDataHere(IDataObject *iface, FORMATETC *pformat, STGMEDIUM *pmedium)
209 static HRESULT WINAPI IDataObjectImpl_QueryGetData(IDataObject *iface, FORMATETC *pformat)
214 static HRESULT WINAPI IDataObjectImpl_GetCanonicalFormatEtc(
215 IDataObject *iface, FORMATETC *pformatIn, FORMATETC *pformatOut)
220 static HRESULT WINAPI IDataObjectImpl_SetData(
221 IDataObject *iface, FORMATETC *pformat, STGMEDIUM *pmedium, BOOL release)
226 static HRESULT WINAPI IDataObjectImpl_EnumFormatEtc(
227 IDataObject *iface, DWORD direction, IEnumFORMATETC **ppenumFormatEtc)
232 static HRESULT WINAPI IDataObjectImpl_DAdvise(
233 IDataObject *iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pSink, DWORD *pConnection)
238 static HRESULT WINAPI IDataObjectImpl_DUnadvise(IDataObject *iface, DWORD connection)
243 static HRESULT WINAPI IDataObjectImpl_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **ppenumAdvise)
248 static const IDataObjectVtbl IDataObjectImpl_Vtbl =
250 IDataObjectImpl_QueryInterface,
251 IDataObjectImpl_AddRef,
252 IDataObjectImpl_Release,
253 IDataObjectImpl_GetData,
254 IDataObjectImpl_GetDataHere,
255 IDataObjectImpl_QueryGetData,
256 IDataObjectImpl_GetCanonicalFormatEtc,
257 IDataObjectImpl_SetData,
258 IDataObjectImpl_EnumFormatEtc,
259 IDataObjectImpl_DAdvise,
260 IDataObjectImpl_DUnadvise,
261 IDataObjectImpl_EnumDAdvise
264 /* dummy IShellBrowser implementation */
266 IShellBrowser IShellBrowser_iface;
270 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
272 static inline IShellBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
274 return CONTAINING_RECORD(iface, IShellBrowserImpl, IShellBrowser_iface);
277 static IShellBrowser* IShellBrowserImpl_Construct(void)
279 IShellBrowserImpl *browser;
281 browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
282 browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
285 return &browser->IShellBrowser_iface;
288 static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
292 IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
296 if(IsEqualIID(riid, &IID_IUnknown) ||
297 IsEqualIID(riid, &IID_IOleWindow) ||
298 IsEqualIID(riid, &IID_IShellBrowser))
305 IUnknown_AddRef(iface);
309 return E_NOINTERFACE;
312 static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
314 IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
315 return InterlockedIncrement(&This->ref);
318 static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
320 IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
321 ULONG ref = InterlockedDecrement(&This->ref);
325 HeapFree(GetProcessHeap(), 0, This);
331 static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser *iface,
334 if (phwnd) *phwnd = GetDesktopWindow();
338 static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser *iface,
344 static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
351 static HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
358 static HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
366 static HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
374 static HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
376 LPOLEMENUGROUPWIDTHS lpMenuWidths)
382 static HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
389 static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
396 static HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
403 static HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
414 static HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
416 HOLEMENU holemenuReserved,
417 HWND hwndActiveObject)
423 static HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
424 LPCOLESTR lpszStatusText)
430 static HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
431 LPTBBUTTON lpButtons,
439 static HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
447 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl =
449 IShellBrowserImpl_QueryInterface,
450 IShellBrowserImpl_AddRef,
451 IShellBrowserImpl_Release,
452 IShellBrowserImpl_GetWindow,
453 IShellBrowserImpl_ContextSensitiveHelp,
454 IShellBrowserImpl_InsertMenusSB,
455 IShellBrowserImpl_SetMenuSB,
456 IShellBrowserImpl_RemoveMenusSB,
457 IShellBrowserImpl_SetStatusTextSB,
458 IShellBrowserImpl_EnableModelessSB,
459 IShellBrowserImpl_TranslateAcceleratorSB,
460 IShellBrowserImpl_BrowseObject,
461 IShellBrowserImpl_GetViewStateStream,
462 IShellBrowserImpl_GetControlWindow,
463 IShellBrowserImpl_SendControlMsg,
464 IShellBrowserImpl_QueryActiveShellView,
465 IShellBrowserImpl_OnViewWindowActive,
466 IShellBrowserImpl_SetToolbarItems
469 static const struct message empty_seq[] = {
473 static const struct message folderview_getspacing_seq[] = {
474 { LVM_GETITEMSPACING, wparam|sent, FALSE },
478 static const struct message folderview_getselectionmarked_seq[] = {
479 { LVM_GETSELECTIONMARK, sent },
483 static const struct message folderview_getfocused_seq[] = {
484 { LVM_GETNEXTITEM, sent|wparam|lparam|optional, -1, LVNI_FOCUSED },
488 static const struct message folderview_itemcount_seq[] = {
489 { LVM_GETITEMCOUNT, sent },
493 static void test_IShellView_CreateViewWindow(void)
495 IShellFolder *desktop;
496 FOLDERSETTINGS settings;
503 hr = SHGetDesktopFolder(&desktop);
504 ok(hr == S_OK, "got (0x%08x)\n", hr);
506 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
507 ok(hr == S_OK, "got (0x%08x)\n", hr);
511 /* crashes on native */
512 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
515 settings.ViewMode = FVM_ICON;
517 hwnd_view = (HWND)0xdeadbeef;
518 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, &hwnd_view);
519 ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
520 ok(hwnd_view == 0, "got %p\n", hwnd_view);
522 hwnd_view = (HWND)0xdeadbeef;
523 hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, &r, &hwnd_view);
524 ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
525 ok(hwnd_view == 0, "got %p\n", hwnd_view);
527 /* ::DragLeave without drag operation */
528 hr = IShellView_QueryInterface(view, &IID_IDropTarget, (void**)&dt);
529 ok(hr == S_OK, "got (0x%08x)\n", hr);
530 hr = IDropTarget_DragLeave(dt);
531 ok(hr == S_OK, "got (0x%08x)\n", hr);
532 IDropTarget_Release(dt);
534 IShellView_Release(view);
535 IShellFolder_Release(desktop);
538 static void test_IFolderView(void)
540 IShellFolder *desktop, *folder;
541 FOLDERSETTINGS settings;
543 IShellBrowser *browser;
545 HWND hwnd_view, hwnd_list;
553 hr = SHGetDesktopFolder(&desktop);
554 ok(hr == S_OK, "got (0x%08x)\n", hr);
556 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
557 ok(hr == S_OK, "got (0x%08x)\n", hr);
559 hr = IShellView_QueryInterface(view, &IID_IFolderView, (void**)&fv);
562 win_skip("IFolderView not supported by desktop folder\n");
563 IShellView_Release(view);
564 IShellFolder_Release(desktop);
568 /* call methods before window creation */
569 hr = IFolderView_GetSpacing(fv, NULL);
570 ok(hr == S_FALSE || broken(hr == S_OK) /* win7 */, "got (0x%08x)\n", hr);
572 pidl = (void*)0xdeadbeef;
573 hr = IFolderView_Item(fv, 0, &pidl);
574 ok(hr == E_INVALIDARG || broken(hr == E_FAIL) /* < Vista */, "got (0x%08x)\n", hr);
575 ok(pidl == 0 || broken(pidl == (void*)0xdeadbeef) /* < Vista */, "got %p\n", pidl);
579 /* crashes on Vista and Win2k8 - List not created yet case */
580 hr = IFolderView_GetSpacing(fv, &pt);
583 hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
584 hr = IFolderView_GetFocusedItem(fv, NULL);
586 /* crashes on Vista+ */
587 hr = IFolderView_Item(fv, 0, NULL);
590 browser = IShellBrowserImpl_Construct();
592 settings.ViewMode = FVM_ICON;
594 hwnd_view = (HWND)0xdeadbeef;
596 r.right = r.bottom = 100;
597 hr = IShellView_CreateViewWindow(view, NULL, &settings, browser, &r, &hwnd_view);
598 ok(hr == S_OK, "got (0x%08x)\n", hr);
599 ok(IsWindow(hwnd_view), "got %p\n", hwnd_view);
601 hwnd_list = subclass_listview(hwnd_view);
604 win_skip("Failed to subclass ListView control\n");
605 IShellBrowser_Release(browser);
606 IFolderView_Release(fv);
607 IShellView_Release(view);
608 IShellFolder_Release(desktop);
612 /* IFolderView::GetSpacing */
613 flush_sequences(sequences, NUM_MSG_SEQUENCES);
614 hr = IFolderView_GetSpacing(fv, NULL);
615 ok(hr == S_OK, "got (0x%08x)\n", hr);
616 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetSpacing, empty", FALSE);
618 flush_sequences(sequences, NUM_MSG_SEQUENCES);
619 hr = IFolderView_GetSpacing(fv, &pt);
620 ok(hr == S_OK, "got (0x%08x)\n", hr);
621 /* fails with empty sequence on win7 for unknown reason */
622 if (sequences[LISTVIEW_SEQ_INDEX]->count)
624 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getspacing_seq, "IFolderView::GetSpacing", FALSE);
625 ok(pt.x > 0, "got %d\n", pt.x);
626 ok(pt.y > 0, "got %d\n", pt.y);
627 ret = SendMessageA(hwnd_list, LVM_GETITEMSPACING, 0, 0);
628 ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret));
631 /* IFolderView::ItemCount */
635 hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL);
638 flush_sequences(sequences, NUM_MSG_SEQUENCES);
639 hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &count);
640 ok(hr == S_OK, "got (0x%08x)\n", hr);
641 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, count ? folderview_itemcount_seq : empty_seq,
642 "IFolderView::ItemCount", FALSE);
644 /* IFolderView::GetSelectionMarkedItem */
648 hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
651 flush_sequences(sequences, NUM_MSG_SEQUENCES);
652 hr = IFolderView_GetSelectionMarkedItem(fv, &ret);
654 ok(hr == S_OK, "got (0x%08x)\n", hr);
656 ok(hr == S_FALSE, "got (0x%08x)\n", hr);
657 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq,
658 "IFolderView::GetSelectionMarkedItem", FALSE);
660 /* IFolderView::GetFocusedItem */
661 flush_sequences(sequences, NUM_MSG_SEQUENCES);
662 hr = IFolderView_GetFocusedItem(fv, &ret);
664 ok(hr == S_OK, "got (0x%08x)\n", hr);
666 ok(hr == S_FALSE, "got (0x%08x)\n", hr);
667 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq,
668 "IFolderView::GetFocusedItem", FALSE);
670 /* IFolderView::GetFolder, just return pointer */
674 hr = IFolderView_GetFolder(fv, NULL, (void**)&folder);
675 hr = IFolderView_GetFolder(fv, NULL, NULL);
678 hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL);
679 ok(hr == E_POINTER, "got (0x%08x)\n", hr);
681 ref1 = IShellFolder_AddRef(desktop);
682 IShellFolder_Release(desktop);
683 hr = IFolderView_GetFolder(fv, &IID_IShellFolder, (void**)&folder);
684 ok(hr == S_OK, "got (0x%08x)\n", hr);
685 ref2 = IShellFolder_AddRef(desktop);
686 IShellFolder_Release(desktop);
687 ok(ref1 == ref2 || ref1 + 1 == ref2, /* >= vista */
688 "expected same refcount, got %d\n", ref2);
689 ok(desktop == folder, "\n");
691 IShellBrowser_Release(browser);
692 IFolderView_Release(fv);
693 IShellView_Release(view);
694 IShellFolder_Release(desktop);
697 static void test_GetItemObject(void)
699 IShellFolder *desktop;
704 hr = SHGetDesktopFolder(&desktop);
705 ok(hr == S_OK, "got (0x%08x)\n", hr);
707 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
708 ok(hr == S_OK, "got (0x%08x)\n", hr);
710 /* from documentation three interfaces are supported for SVGIO_BACKGROUND:
711 IContextMenu, IDispatch, IPersistHistory */
712 hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IContextMenu, (void**)&unk);
713 ok(hr == S_OK, "got (0x%08x)\n", hr);
714 IUnknown_Release(unk);
717 hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&unk);
718 todo_wine ok(hr == S_OK || broken(hr == E_NOTIMPL) /* NT4 */, "got (0x%08x)\n", hr);
719 if (unk) IUnknown_Release(unk);
722 hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IPersistHistory, (void**)&unk);
723 todo_wine ok(hr == S_OK || broken(hr == E_NOTIMPL) /* W9x, NT4 */, "got (0x%08x)\n", hr);
724 if (unk) IUnknown_Release(unk);
726 /* example of unsupported interface, base for IPersistHistory */
727 hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IPersist, (void**)&unk);
728 ok(hr == E_NOINTERFACE || broken(hr == E_NOTIMPL) /* W2K */, "got (0x%08x)\n", hr);
730 IShellView_Release(view);
731 IShellFolder_Release(desktop);
734 static void test_IShellFolderView(void)
736 IShellFolderView *folderview;
737 IShellFolder *desktop;
743 hr = SHGetDesktopFolder(&desktop);
744 ok(hr == S_OK, "got (0x%08x)\n", hr);
746 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
747 ok(hr == S_OK, "got (0x%08x)\n", hr);
749 hr = IShellView_QueryInterface(view, &IID_IShellFolderView, (void**)&folderview);
752 win_skip("IShellView doesn't provide IShellFolderView on this platform\n");
753 IShellView_Release(view);
754 IShellFolder_Release(desktop);
759 obj = IDataObjectImpl_Construct();
760 hr = IShellFolderView_MoveIcons(folderview, obj);
761 ok(hr == E_NOTIMPL || broken(hr == S_OK) /* W98 */, "got (0x%08x)\n", hr);
762 IDataObject_Release(obj);
764 /* ::SetRedraw without list created */
765 hr = IShellFolderView_SetRedraw(folderview, TRUE);
766 ok(hr == S_OK, "got (0x%08x)\n", hr);
769 hr = IShellFolderView_QuerySupport(folderview, NULL);
770 ok(hr == S_OK, "got (0x%08x)\n", hr);
772 hr = IShellFolderView_QuerySupport(folderview, &i);
773 ok(hr == S_OK, "got (0x%08x)\n", hr);
774 ok(i == 0xdeadbeef, "got %d\n", i);
778 hr = IShellFolderView_RemoveObject(folderview, NULL, &i);
779 ok(hr == S_OK || hr == E_FAIL, "got (0x%08x)\n", hr);
780 if (hr == S_OK) ok(i == 0 || broken(i == 0xdeadbeef) /* Vista, 2k8 */,
783 IShellFolderView_Release(folderview);
785 IShellView_Release(view);
786 IShellFolder_Release(desktop);
789 static void test_IOleWindow(void)
791 IShellFolder *desktop;
795 hr = SHGetDesktopFolder(&desktop);
796 ok(hr == S_OK, "got (0x%08x)\n", hr);
798 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
799 ok(hr == S_OK, "got (0x%08x)\n", hr);
801 /* IShellView::ContextSensitiveHelp */
802 hr = IShellView_ContextSensitiveHelp(view, TRUE);
803 ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
804 hr = IShellView_ContextSensitiveHelp(view, FALSE);
805 ok(hr == E_NOTIMPL, "got (0x%08x)\n", hr);
807 IShellView_Release(view);
808 IShellFolder_Release(desktop);
811 static const struct message folderview_setcurrentviewmode1_2_prevista[] = {
812 { LVM_SETVIEW, sent|wparam, LV_VIEW_ICON},
813 { LVM_SETIMAGELIST, sent|wparam, 0},
814 { LVM_SETIMAGELIST, sent|wparam, 1},
816 { LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
817 { LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
818 { LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
819 { LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
820 { LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
821 { LVM_ARRANGE, sent },
822 { LVM_ARRANGE, sent|optional }, /* WinXP */
826 static const struct message folderview_setcurrentviewmode3_prevista[] = {
827 { LVM_SETVIEW, sent|wparam, LV_VIEW_LIST},
828 { LVM_SETIMAGELIST, sent|wparam, 0},
829 { LVM_SETIMAGELIST, sent|wparam, 1},
831 { LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
832 { LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
833 { LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
834 { LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
835 { LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
839 static const struct message folderview_setcurrentviewmode4_prevista[] = {
840 { LVM_GETHEADER, sent},
841 { LVM_GETITEMCOUNT, sent|optional },
842 { LVM_SETSELECTEDCOLUMN, sent},
847 { LVM_SETVIEW, sent|wparam, LV_VIEW_DETAILS},
848 { LVM_SETIMAGELIST, sent|wparam, 0},
849 { LVM_SETIMAGELIST, sent|wparam, 1},
851 { LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
852 { LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
853 { LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
854 { LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
855 { LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
859 /* XP, SetCurrentViewMode(5)
860 108e - LVM_SETVIEW (LV_VIEW_ICON);
861 1036 - LVM_SETEXTEDEDLISTVIEWSTYLE (0x8000, 0)
862 100c/104c repeated X times
863 1003 - LVM_SETIMAGELIST
864 1035 - LVM_SETICONSPACING
865 1004 - LVM_GETITEMCOUNT
871 /* XP, SetCurrentViewMode(6)
872 1036 - LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0)
873 1035 - LVM_SETICONSPACING
874 1003 - LVM_SETIMAGELIST
875 1003 - LVM_SETIMAGELIST
876 100c/104c repeated X times
877 10a2 - LVM_SETTILEVIEWINFO
878 108e - LVM_SETVIEW (LV_VIEW_TILE)
879 1003 - LVM_SETIMAGELIST
885 /* XP, SetCurrentViewMode (7)
886 10a2 - LVM_SETTILEVIEWINFO
887 108e - LVM_SETVIEW (LV_VIEW_ICON)
888 1004/10a4 (LVM_GETITEMCOUNT/LVM_SETTILEINFO) X times
892 LVM_SETEXTENDEDLISTVIEWSTYLE (0x40000, 0x40000)
894 LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0x8000)
897 static void test_GetSetCurrentViewMode(void)
899 IShellFolder *desktop;
902 IShellBrowser *browser;
906 RECT rc = {0, 0, 10, 10};
909 static const int winxp_res[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
910 static const int win2k3_res[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0};
911 static const int vista_res[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0};
912 static const int win7_res[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8};
914 hr = SHGetDesktopFolder(&desktop);
915 ok(hr == S_OK, "got (0x%08x)\n", hr);
917 hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&sview);
918 ok(hr == S_OK, "got (0x%08x)\n", hr);
922 browser = IShellBrowserImpl_Construct();
923 hr = IShellView_CreateViewWindow(sview, NULL, &fs, browser, &rc, &hwnd);
924 ok(hr == S_OK || broken(hr == S_FALSE /*Win2k*/ ), "got (0x%08x)\n", hr);
926 hr = IShellView_QueryInterface(sview, &IID_IFolderView, (void**)&fview);
927 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "got (0x%08x)\n", hr);
935 /* Crashes under Win7/WinXP */
936 hr = IFolderView_GetCurrentViewMode(fview, NULL);
939 hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
940 ok(hr == S_OK, "got (0x%08x)\n", hr);
941 ok(viewmode == 1, "ViewMode was %d\n", viewmode);
943 hr = IFolderView_SetCurrentViewMode(fview, FVM_AUTO);
944 ok(hr == S_OK, "got (0x%08x)\n", hr);
946 hr = IFolderView_SetCurrentViewMode(fview, 0);
947 ok(hr == E_INVALIDARG || broken(hr == S_OK),
948 "got (0x%08x)\n", hr);
950 hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
951 ok(hr == S_OK, "got (0x%08x)\n", hr);
953 for(i = 1; i < 9; i++)
955 hr = IFolderView_SetCurrentViewMode(fview, i);
956 ok(hr == S_OK || (i == 8 && hr == E_INVALIDARG /*Vista*/),
957 "(%d) got (0x%08x)\n", i, hr);
959 hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
960 ok(hr == S_OK, "(%d) got (0x%08x)\n", i, hr);
962 /* Wine currently behaves like winxp here. */
963 ok((viewmode == win7_res[i]) || (viewmode == vista_res[i]) ||
964 (viewmode == win2k3_res[i]) || (viewmode == winxp_res[i]),
965 "(%d) got %d\n",i , viewmode);
968 hr = IFolderView_SetCurrentViewMode(fview, 9);
969 ok(hr == E_INVALIDARG || broken(hr == S_OK),
970 "got (0x%08x)\n", hr);
973 hwnd_lv = subclass_listview(hwnd);
974 ok(hwnd_lv != NULL, "Failed to subclass listview\n");
977 /* Vista seems to set the viewmode by other means than
978 sending messages. At least no related messages are
979 captured by subclassing.
981 BOOL vista_plus = FALSE;
982 static const UINT vista_plus_msgs[] = {
983 WM_SETREDRAW, WM_NOTIFY, WM_NOTIFYFORMAT, WM_QUERYUISTATE,
984 WM_MENUCHAR, WM_WINDOWPOSCHANGING, WM_NCCALCSIZE, WM_WINDOWPOSCHANGED,
985 WM_PARENTNOTIFY, LVM_GETHEADER, 0 };
987 flush_sequences(sequences, NUM_MSG_SEQUENCES);
988 hr = IFolderView_SetCurrentViewMode(fview, 1);
989 ok(hr == S_OK, "got 0x%08x\n", hr);
991 /* WM_SETREDRAW is not sent in versions before Vista. */
992 vista_plus = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, WM_SETREDRAW);
994 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
996 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista,
997 "IFolderView::SetCurrentViewMode(1)", TRUE);
999 hr = IFolderView_SetCurrentViewMode(fview, 2);
1000 ok(hr == S_OK, "got 0x%08x\n", hr);
1002 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1004 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista,
1005 "IFolderView::SetCurrentViewMode(2)", TRUE);
1007 hr = IFolderView_SetCurrentViewMode(fview, 3);
1008 ok(hr == S_OK, "got 0x%08x\n", hr);
1010 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1012 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode3_prevista,
1013 "IFolderView::SetCurrentViewMode(3)", TRUE);
1015 hr = IFolderView_SetCurrentViewMode(fview, 4);
1016 ok(hr == S_OK, "got 0x%08x\n", hr);
1018 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1020 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode4_prevista,
1021 "IFolderView::SetCurrentViewMode(4)", TRUE);
1023 hr = IFolderView_SetCurrentViewMode(fview, 5);
1024 ok(hr == S_OK, "got 0x%08x\n", hr);
1029 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1033 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
1034 ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
1035 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
1036 ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
1037 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1041 hr = IFolderView_SetCurrentViewMode(fview, 6);
1042 ok(hr == S_OK, "got 0x%08x\n", hr);
1047 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1051 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
1052 ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
1053 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
1054 ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
1055 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1059 hr = IFolderView_SetCurrentViewMode(fview, 7);
1060 ok(hr == S_OK, "got 0x%08x\n", hr);
1065 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1069 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
1070 ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
1071 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
1072 ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
1073 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1077 hr = IFolderView_SetCurrentViewMode(fview, 8);
1078 ok(hr == S_OK || broken(hr == E_INVALIDARG /* Vista */), "got 0x%08x\n", hr);
1083 verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
1087 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
1088 ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
1089 count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
1090 ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
1091 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1095 hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
1096 ok(hr == S_OK, "Failed to get current viewmode.\n");
1097 ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq,
1098 "IFolderView::GetCurrentViewMode", FALSE);
1101 IFolderView_Release(fview);
1105 skip("No IFolderView for the desktop folder.\n");
1108 IShellBrowser_Release(browser);
1109 IShellView_DestroyViewWindow(sview);
1110 IShellView_Release(sview);
1111 IShellFolder_Release(desktop);
1114 static void test_IOleCommandTarget(void)
1116 IShellFolder *psf_desktop;
1118 IOleCommandTarget *poct;
1121 hr = SHGetDesktopFolder(&psf_desktop);
1122 ok(hr == S_OK, "got (0x%08x)\n", hr);
1124 hr = IShellFolder_CreateViewObject(psf_desktop, NULL, &IID_IShellView, (void**)&psv);
1125 ok(hr == S_OK, "got (0x%08x)\n", hr);
1128 hr = IShellView_QueryInterface(psv, &IID_IOleCommandTarget, (void**)&poct);
1129 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win95/NT4 */, "Got 0x%08x\n", hr);
1134 hr = IOleCommandTarget_QueryStatus(poct, NULL, 0, NULL, NULL);
1135 ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr);
1138 hr = IOleCommandTarget_QueryStatus(poct, NULL, 0, &oc, NULL);
1139 ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
1142 hr = IOleCommandTarget_QueryStatus(poct, NULL, 1, &oc, NULL);
1143 ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
1145 hr = IOleCommandTarget_Exec(poct, NULL, 0, 0, NULL, NULL);
1146 ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
1148 IOleCommandTarget_Release(poct);
1151 IShellView_Release(psv);
1154 IShellFolder_Release(psf_desktop);
1159 OleInitialize(NULL);
1161 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
1163 test_IShellView_CreateViewWindow();
1165 test_GetItemObject();
1166 test_IShellFolderView();
1168 test_GetSetCurrentViewMode();
1169 test_IOleCommandTarget();