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;
56 struct message msg
= { 0 };
59 msg
.message
= message
;
60 msg
.flags
= sent
|wparam
|lparam
;
61 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
64 add_message(sequences
, LISTVIEW_SEQ_INDEX
, &msg
);
67 ret
= CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
72 static HWND
subclass_listview(HWND hwnd
)
77 /* listview is a first child */
78 listview
= FindWindowExA(hwnd
, NULL
, WC_LISTVIEWA
, NULL
);
81 /* .. except for some versions of Windows XP, where things
82 are slightly more complicated. */
84 hwnd_tmp
= FindWindowExA(hwnd
, NULL
, "DUIViewWndClassName", NULL
);
85 hwnd_tmp
= FindWindowExA(hwnd_tmp
, NULL
, "DirectUIHWND", NULL
);
86 hwnd_tmp
= FindWindowExA(hwnd_tmp
, NULL
, "CtrlNotifySink", NULL
);
87 listview
= FindWindowExA(hwnd_tmp
, NULL
, WC_LISTVIEWA
, NULL
);
90 oldproc
= (WNDPROC
)SetWindowLongPtrA(listview
, GWLP_WNDPROC
,
91 (LONG_PTR
)listview_subclass_proc
);
92 SetWindowLongPtrA(listview
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
97 static UINT
get_msg_count(struct msg_sequence
**seq
, int sequence_index
, UINT message
)
99 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
102 for(i
= 0; i
< msg_seq
->count
; i
++)
103 if(msg_seq
->sequence
[i
].message
== message
)
109 /* Checks that every message in the sequence seq is also present in
110 * the UINT array msgs */
111 static void verify_msgs_in_(struct msg_sequence
*seq
, const UINT
*msgs
,
112 const char *file
, int line
)
114 UINT i
, j
, msg
, failcount
= 0;
115 for(i
= 0; i
< seq
->count
; i
++)
118 msg
= seq
->sequence
[i
].message
;
119 for(j
= 0; msgs
[j
] != 0; j
++)
120 if(msgs
[j
] == msg
) found
= TRUE
;
125 trace("Unexpected message %d\n", msg
);
128 ok_(file
, line
) (!failcount
, "%d failures.\n", failcount
);
129 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
132 #define verify_msgs_in(seq, msgs) \
133 verify_msgs_in_(seq, msgs, __FILE__, __LINE__)
135 /* dummy IDataObject implementation */
137 IDataObject IDataObject_iface
;
141 static const IDataObjectVtbl IDataObjectImpl_Vtbl
;
143 static inline IDataObjectImpl
*impl_from_IDataObject(IDataObject
*iface
)
145 return CONTAINING_RECORD(iface
, IDataObjectImpl
, IDataObject_iface
);
148 static IDataObject
* IDataObjectImpl_Construct(void)
150 IDataObjectImpl
*obj
;
152 obj
= malloc(sizeof(*obj
));
153 obj
->IDataObject_iface
.lpVtbl
= &IDataObjectImpl_Vtbl
;
156 return &obj
->IDataObject_iface
;
159 static HRESULT WINAPI
IDataObjectImpl_QueryInterface(IDataObject
*iface
, REFIID riid
, void **ppvObj
)
161 IDataObjectImpl
*This
= impl_from_IDataObject(iface
);
163 if (IsEqualIID(riid
, &IID_IUnknown
) ||
164 IsEqualIID(riid
, &IID_IDataObject
))
166 *ppvObj
= &This
->IDataObject_iface
;
171 IDataObject_AddRef(iface
);
175 return E_NOINTERFACE
;
178 static ULONG WINAPI
IDataObjectImpl_AddRef(IDataObject
* iface
)
180 IDataObjectImpl
*This
= impl_from_IDataObject(iface
);
181 return InterlockedIncrement(&This
->ref
);
184 static ULONG WINAPI
IDataObjectImpl_Release(IDataObject
* iface
)
186 IDataObjectImpl
*This
= impl_from_IDataObject(iface
);
187 ULONG ref
= InterlockedDecrement(&This
->ref
);
195 static HRESULT WINAPI
IDataObjectImpl_GetData(IDataObject
*iface
, FORMATETC
*pformat
, STGMEDIUM
*pmedium
)
200 static HRESULT WINAPI
IDataObjectImpl_GetDataHere(IDataObject
*iface
, FORMATETC
*pformat
, STGMEDIUM
*pmedium
)
205 static HRESULT WINAPI
IDataObjectImpl_QueryGetData(IDataObject
*iface
, FORMATETC
*pformat
)
210 static HRESULT WINAPI
IDataObjectImpl_GetCanonicalFormatEtc(
211 IDataObject
*iface
, FORMATETC
*pformatIn
, FORMATETC
*pformatOut
)
216 static HRESULT WINAPI
IDataObjectImpl_SetData(
217 IDataObject
*iface
, FORMATETC
*pformat
, STGMEDIUM
*pmedium
, BOOL release
)
222 static HRESULT WINAPI
IDataObjectImpl_EnumFormatEtc(
223 IDataObject
*iface
, DWORD direction
, IEnumFORMATETC
**ppenumFormatEtc
)
228 static HRESULT WINAPI
IDataObjectImpl_DAdvise(
229 IDataObject
*iface
, FORMATETC
*pformatetc
, DWORD advf
, IAdviseSink
*pSink
, DWORD
*pConnection
)
234 static HRESULT WINAPI
IDataObjectImpl_DUnadvise(IDataObject
*iface
, DWORD connection
)
239 static HRESULT WINAPI
IDataObjectImpl_EnumDAdvise(IDataObject
*iface
, IEnumSTATDATA
**ppenumAdvise
)
244 static const IDataObjectVtbl IDataObjectImpl_Vtbl
=
246 IDataObjectImpl_QueryInterface
,
247 IDataObjectImpl_AddRef
,
248 IDataObjectImpl_Release
,
249 IDataObjectImpl_GetData
,
250 IDataObjectImpl_GetDataHere
,
251 IDataObjectImpl_QueryGetData
,
252 IDataObjectImpl_GetCanonicalFormatEtc
,
253 IDataObjectImpl_SetData
,
254 IDataObjectImpl_EnumFormatEtc
,
255 IDataObjectImpl_DAdvise
,
256 IDataObjectImpl_DUnadvise
,
257 IDataObjectImpl_EnumDAdvise
260 /* dummy IShellBrowser implementation */
262 IShellBrowser IShellBrowser_iface
;
266 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl
;
268 static inline IShellBrowserImpl
*impl_from_IShellBrowser(IShellBrowser
*iface
)
270 return CONTAINING_RECORD(iface
, IShellBrowserImpl
, IShellBrowser_iface
);
273 static IShellBrowser
* IShellBrowserImpl_Construct(void)
275 IShellBrowserImpl
*browser
;
277 browser
= malloc(sizeof(*browser
));
278 browser
->IShellBrowser_iface
.lpVtbl
= &IShellBrowserImpl_Vtbl
;
281 return &browser
->IShellBrowser_iface
;
284 static HRESULT WINAPI
IShellBrowserImpl_QueryInterface(IShellBrowser
*iface
,
288 IShellBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
292 if(IsEqualIID(riid
, &IID_IUnknown
) ||
293 IsEqualIID(riid
, &IID_IOleWindow
) ||
294 IsEqualIID(riid
, &IID_IShellBrowser
))
296 *ppvObj
= &This
->IShellBrowser_iface
;
301 IShellBrowser_AddRef(iface
);
305 return E_NOINTERFACE
;
308 static ULONG WINAPI
IShellBrowserImpl_AddRef(IShellBrowser
* iface
)
310 IShellBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
311 return InterlockedIncrement(&This
->ref
);
314 static ULONG WINAPI
IShellBrowserImpl_Release(IShellBrowser
* iface
)
316 IShellBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
317 ULONG ref
= InterlockedDecrement(&This
->ref
);
325 static HRESULT WINAPI
IShellBrowserImpl_GetWindow(IShellBrowser
*iface
,
328 if (phwnd
) *phwnd
= GetDesktopWindow();
332 static HRESULT WINAPI
IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser
*iface
,
338 static HRESULT WINAPI
IShellBrowserImpl_BrowseObject(IShellBrowser
*iface
,
345 static HRESULT WINAPI
IShellBrowserImpl_EnableModelessSB(IShellBrowser
*iface
,
352 static HRESULT WINAPI
IShellBrowserImpl_GetControlWindow(IShellBrowser
*iface
,
360 static HRESULT WINAPI
IShellBrowserImpl_GetViewStateStream(IShellBrowser
*iface
,
368 static HRESULT WINAPI
IShellBrowserImpl_InsertMenusSB(IShellBrowser
*iface
,
370 LPOLEMENUGROUPWIDTHS lpMenuWidths
)
376 static HRESULT WINAPI
IShellBrowserImpl_OnViewWindowActive(IShellBrowser
*iface
,
383 static HRESULT WINAPI
IShellBrowserImpl_QueryActiveShellView(IShellBrowser
*iface
,
390 static HRESULT WINAPI
IShellBrowserImpl_RemoveMenusSB(IShellBrowser
*iface
,
397 static HRESULT WINAPI
IShellBrowserImpl_SendControlMsg(IShellBrowser
*iface
,
408 static HRESULT WINAPI
IShellBrowserImpl_SetMenuSB(IShellBrowser
*iface
,
410 HOLEMENU holemenuReserved
,
411 HWND hwndActiveObject
)
417 static HRESULT WINAPI
IShellBrowserImpl_SetStatusTextSB(IShellBrowser
*iface
,
418 LPCOLESTR lpszStatusText
)
424 static HRESULT WINAPI
IShellBrowserImpl_SetToolbarItems(IShellBrowser
*iface
,
425 LPTBBUTTON lpButtons
,
433 static HRESULT WINAPI
IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser
*iface
,
441 static const IShellBrowserVtbl IShellBrowserImpl_Vtbl
=
443 IShellBrowserImpl_QueryInterface
,
444 IShellBrowserImpl_AddRef
,
445 IShellBrowserImpl_Release
,
446 IShellBrowserImpl_GetWindow
,
447 IShellBrowserImpl_ContextSensitiveHelp
,
448 IShellBrowserImpl_InsertMenusSB
,
449 IShellBrowserImpl_SetMenuSB
,
450 IShellBrowserImpl_RemoveMenusSB
,
451 IShellBrowserImpl_SetStatusTextSB
,
452 IShellBrowserImpl_EnableModelessSB
,
453 IShellBrowserImpl_TranslateAcceleratorSB
,
454 IShellBrowserImpl_BrowseObject
,
455 IShellBrowserImpl_GetViewStateStream
,
456 IShellBrowserImpl_GetControlWindow
,
457 IShellBrowserImpl_SendControlMsg
,
458 IShellBrowserImpl_QueryActiveShellView
,
459 IShellBrowserImpl_OnViewWindowActive
,
460 IShellBrowserImpl_SetToolbarItems
463 static const struct message empty_seq
[] = {
467 static const struct message folderview_getspacing_seq
[] = {
468 { LVM_GETITEMSPACING
, wparam
|sent
, FALSE
},
472 static const struct message folderview_getselectionmarked_seq
[] = {
473 { LVM_GETSELECTIONMARK
, sent
},
477 static const struct message folderview_getfocused_seq
[] = {
478 { LVM_GETNEXTITEM
, sent
|wparam
|lparam
|optional
, -1, LVNI_FOCUSED
},
482 static HRESULT WINAPI
shellbrowser_QueryInterface(IShellBrowser
*iface
, REFIID riid
, void **ppv
)
486 if (IsEqualGUID(&IID_IShellBrowser
, riid
) ||
487 IsEqualGUID(&IID_IOleWindow
, riid
) ||
488 IsEqualGUID(&IID_IUnknown
, riid
))
495 IUnknown_AddRef((IUnknown
*)*ppv
);
499 return E_NOINTERFACE
;
502 static ULONG WINAPI
shellbrowser_AddRef(IShellBrowser
*iface
)
507 static ULONG WINAPI
shellbrowser_Release(IShellBrowser
*iface
)
512 static HRESULT WINAPI
shellbrowser_GetWindow(IShellBrowser
*iface
, HWND
*phwnd
)
514 *phwnd
= GetDesktopWindow();
518 static HRESULT WINAPI
shellbrowser_ContextSensitiveHelp(IShellBrowser
*iface
, BOOL mode
)
520 ok(0, "unexpected\n");
524 static HRESULT WINAPI
shellbrowser_InsertMenusSB(IShellBrowser
*iface
, HMENU hmenuShared
,
525 OLEMENUGROUPWIDTHS
*menuwidths
)
530 static HRESULT WINAPI
shellbrowser_SetMenuSB(IShellBrowser
*iface
, HMENU hmenuShared
,
531 HOLEMENU holemenuReserved
, HWND hwndActiveObject
)
536 static HRESULT WINAPI
shellbrowser_RemoveMenusSB(IShellBrowser
*iface
, HMENU hmenuShared
)
541 static HRESULT WINAPI
shellbrowser_SetStatusTextSB(IShellBrowser
*iface
, LPCOLESTR text
)
543 ok(0, "unexpected\n");
547 static HRESULT WINAPI
shellbrowser_EnableModelessSB(IShellBrowser
*iface
, BOOL enable
)
549 ok(0, "unexpected\n");
553 static HRESULT WINAPI
shellbrowser_TranslateAcceleratorSB(IShellBrowser
*iface
, MSG
*pmsg
, WORD wID
)
555 ok(0, "unexpected\n");
559 static HRESULT WINAPI
shellbrowser_BrowseObject(IShellBrowser
*iface
, LPCITEMIDLIST pidl
, UINT flags
)
561 ok(0, "unexpected\n");
565 static HRESULT WINAPI
shellbrowser_GetViewStateStream(IShellBrowser
*iface
, DWORD mode
, IStream
**stream
)
570 static HRESULT WINAPI
shellbrowser_GetControlWindow(IShellBrowser
*iface
, UINT id
, HWND
*phwnd
)
575 static HRESULT WINAPI
shellbrowser_SendControlMsg(IShellBrowser
*iface
, UINT id
, UINT uMsg
,
576 WPARAM wParam
, LPARAM lParam
, LRESULT
*pret
)
581 static HRESULT WINAPI
shellbrowser_QueryActiveShellView(IShellBrowser
*iface
, IShellView
**view
)
583 ok(0, "unexpected\n");
587 static HRESULT WINAPI
shellbrowser_OnViewWindowActive(IShellBrowser
*iface
, IShellView
*view
)
589 ok(0, "unexpected\n");
593 static HRESULT WINAPI
shellbrowser_SetToolbarItems(IShellBrowser
*iface
, LPTBBUTTONSB buttons
,
594 UINT count
, UINT flags
)
599 static const IShellBrowserVtbl shellbrowservtbl
= {
600 shellbrowser_QueryInterface
,
602 shellbrowser_Release
,
603 shellbrowser_GetWindow
,
604 shellbrowser_ContextSensitiveHelp
,
605 shellbrowser_InsertMenusSB
,
606 shellbrowser_SetMenuSB
,
607 shellbrowser_RemoveMenusSB
,
608 shellbrowser_SetStatusTextSB
,
609 shellbrowser_EnableModelessSB
,
610 shellbrowser_TranslateAcceleratorSB
,
611 shellbrowser_BrowseObject
,
612 shellbrowser_GetViewStateStream
,
613 shellbrowser_GetControlWindow
,
614 shellbrowser_SendControlMsg
,
615 shellbrowser_QueryActiveShellView
,
616 shellbrowser_OnViewWindowActive
,
617 shellbrowser_SetToolbarItems
620 static IShellBrowser test_shellbrowser
= { &shellbrowservtbl
};
622 static void create_interfaces(IShellFolder
**desktop
, IShellView
**view
)
626 hr
= SHGetDesktopFolder(desktop
);
627 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
628 hr
= IShellFolder_CreateViewObject(*desktop
, NULL
, &IID_IShellView
, (void **)view
);
629 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
632 static void destroy_interfaces(IShellFolder
*desktop
, IShellView
*view
)
634 IShellFolder_Release(desktop
);
635 IShellView_Release(view
);
638 static void test_CreateViewWindow(void)
640 IShellFolder
*desktop
;
641 HWND hwnd_view
, hwnd2
;
642 FOLDERSETTINGS settings
;
650 create_interfaces(&desktop
, &view
);
652 hr
= IShellView_QueryInterface(view
, &IID_CDefView
, (void **)&unk
);
653 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
654 ok(unk
== (IUnknown
*)view
, "got %p\n", unk
);
655 IUnknown_Release(unk
);
659 /* crashes on native */
660 IShellView_CreateViewWindow(view
, NULL
, &settings
, NULL
, NULL
, NULL
);
663 settings
.ViewMode
= FVM_ICON
;
665 hwnd_view
= (HWND
)0xdeadbeef;
666 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, NULL
, NULL
, &hwnd_view
);
667 ok(hr
== E_UNEXPECTED
, "got (0x%08lx)\n", hr
);
668 ok(hwnd_view
== 0, "got %p\n", hwnd_view
);
670 hwnd_view
= (HWND
)0xdeadbeef;
671 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, NULL
, &r
, &hwnd_view
);
672 ok(hr
== E_UNEXPECTED
, "got (0x%08lx)\n", hr
);
673 ok(hwnd_view
== 0, "got %p\n", hwnd_view
);
676 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, &test_shellbrowser
, &r
, &hwnd_view
);
677 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got (0x%08lx)\n", hr
);
678 ok(hwnd_view
!= 0, "got %p\n", hwnd_view
);
680 hwnd2
= (HWND
)0xdeadbeef;
681 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, &test_shellbrowser
, &r
, &hwnd2
);
682 ok(hr
== E_UNEXPECTED
, "got (0x%08lx)\n", hr
);
683 ok(hwnd2
== NULL
, "got %p\n", hwnd2
);
685 /* ::DragLeave without drag operation */
686 hr
= IShellView_QueryInterface(view
, &IID_IDropTarget
, (void**)&dt
);
687 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
688 hr
= IDropTarget_DragLeave(dt
);
689 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
690 IDropTarget_Release(dt
);
692 IShellView_AddRef(view
);
693 ref1
= IShellView_Release(view
);
694 hr
= IShellView_DestroyViewWindow(view
);
695 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
696 ok(!IsWindow(hwnd_view
), "hwnd %p still valid\n", hwnd_view
);
697 ref2
= IShellView_Release(view
);
698 ok(ref1
> ref2
, "expected %lu > %lu\n", ref1
, ref2
);
701 /* Show that releasing the shell view does not destroy the window */
702 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
703 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
705 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, &test_shellbrowser
, &r
, &hwnd_view
);
706 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got (0x%08lx)\n", hr
);
707 ok(hwnd_view
!= NULL
, "got %p\n", hwnd_view
);
708 ok(IsWindow(hwnd_view
), "hwnd %p still valid\n", hwnd_view
);
709 ref2
= IShellView_Release(view
);
710 ok(ref2
!= 0, "ref2 = %lu\n", ref2
);
711 ok(ref2
> ref1
, "expected %lu > %lu\n", ref2
, ref1
);
712 ok(IsWindow(hwnd_view
), "hwnd %p still valid\n", hwnd_view
);
713 DestroyWindow(hwnd_view
);
715 IShellFolder_Release(desktop
);
718 static void test_IFolderView(void)
720 IShellFolder
*desktop
, *folder
;
721 FOLDERSETTINGS settings
;
723 IShellBrowser
*browser
;
727 HWND hwnd_view
, hwnd_list
;
734 create_interfaces(&desktop
, &view
);
736 hr
= IShellView_QueryInterface(view
, &IID_IFolderView
, (void**)&fv
);
739 win_skip("IFolderView not supported by desktop folder\n");
740 destroy_interfaces(desktop
, view
);
744 /* call methods before window creation */
745 hr
= IFolderView_GetSpacing(fv
, NULL
);
746 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win7 */, "got (0x%08lx)\n", hr
);
748 pidl
= (void*)0xdeadbeef;
749 hr
= IFolderView_Item(fv
, 0, &pidl
);
750 ok(hr
== E_INVALIDARG
|| broken(hr
== E_FAIL
) /* < Vista */, "got (0x%08lx)\n", hr
);
751 ok(pidl
== 0 || broken(pidl
== (void*)0xdeadbeef) /* < Vista */, "got %p\n", pidl
);
755 /* crashes on Vista and Win2k8 - List not created yet case */
756 IFolderView_GetSpacing(fv
, &pt
);
759 IFolderView_GetSelectionMarkedItem(fv
, NULL
);
760 IFolderView_GetFocusedItem(fv
, NULL
);
762 /* crashes on Vista+ */
763 IFolderView_Item(fv
, 0, NULL
);
766 browser
= IShellBrowserImpl_Construct();
768 settings
.ViewMode
= FVM_ICON
;
770 hwnd_view
= (HWND
)0xdeadbeef;
771 SetRect(&r
, 0, 0, 100, 100);
772 hr
= IShellView_CreateViewWindow(view
, NULL
, &settings
, browser
, &r
, &hwnd_view
);
773 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
774 ok(IsWindow(hwnd_view
), "got %p\n", hwnd_view
);
776 hwnd_list
= subclass_listview(hwnd_view
);
779 win_skip("Failed to subclass ListView control\n");
780 IShellBrowser_Release(browser
);
781 IFolderView_Release(fv
);
782 destroy_interfaces(desktop
, view
);
786 /* IFolderView::GetSpacing */
787 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
788 hr
= IFolderView_GetSpacing(fv
, NULL
);
789 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
790 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, empty_seq
, "IFolderView::GetSpacing, empty", FALSE
);
792 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
793 hr
= IFolderView_GetSpacing(fv
, &pt
);
794 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
795 /* fails with empty sequence on win7 for unknown reason */
796 if (sequences
[LISTVIEW_SEQ_INDEX
]->count
)
798 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_getspacing_seq
, "IFolderView::GetSpacing", FALSE
);
799 ok(pt
.x
> 0, "got %ld\n", pt
.x
);
800 ok(pt
.y
> 0, "got %ld\n", pt
.y
);
801 ret
= SendMessageA(hwnd_list
, LVM_GETITEMSPACING
, 0, 0);
802 ok(pt
.x
== LOWORD(ret
) && pt
.y
== HIWORD(ret
), "got (%d, %d)\n", LOWORD(ret
), HIWORD(ret
));
805 /* IFolderView::ItemCount */
809 IFolderView_ItemCount(fv
, SVGIO_ALLVIEW
, NULL
);
812 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
813 IFolderView_ItemCount(fv
, SVGIO_ALLVIEW
, &count
);
815 /* IFolderView::GetSelectionMarkedItem */
819 IFolderView_GetSelectionMarkedItem(fv
, NULL
);
822 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
823 hr
= IFolderView_GetSelectionMarkedItem(fv
, &ret
);
825 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
827 ok(hr
== S_FALSE
, "got (0x%08lx)\n", hr
);
828 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_getselectionmarked_seq
,
829 "IFolderView::GetSelectionMarkedItem", FALSE
);
831 /* IFolderView::GetFocusedItem */
832 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
833 hr
= IFolderView_GetFocusedItem(fv
, &ret
);
835 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
837 ok(hr
== S_FALSE
, "got (0x%08lx)\n", hr
);
838 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_getfocused_seq
,
839 "IFolderView::GetFocusedItem", FALSE
);
841 /* IFolderView::GetFolder, just return pointer */
845 IFolderView_GetFolder(fv
, NULL
, (void**)&folder
);
846 IFolderView_GetFolder(fv
, NULL
, NULL
);
849 hr
= IFolderView_GetFolder(fv
, &IID_IShellFolder
, NULL
);
850 ok(hr
== E_POINTER
, "got (0x%08lx)\n", hr
);
852 hr
= IFolderView_GetFolder(fv
, &IID_IShellFolder
, (void**)&folder
);
853 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
854 ok(desktop
== folder
, "\n");
855 if (folder
) IShellFolder_Release(folder
);
857 hr
= IFolderView_GetFolder(fv
, &IID_IUnknown
, (void**)&unk
);
858 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
859 if (unk
) IUnknown_Release(unk
);
861 hr
= IFolderView_QueryInterface(fv
, &IID_IFolderView2
, (void**)&fv2
);
863 win_skip("IFolderView2 is not supported.\n");
864 if (fv2
) IFolderView2_Release(fv2
);
866 hr
= IShellView_DestroyViewWindow(view
);
867 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
868 ok(!IsWindow(hwnd_view
), "hwnd %p still valid\n", hwnd_view
);
870 IShellBrowser_Release(browser
);
871 IFolderView_Release(fv
);
872 destroy_interfaces(desktop
, view
);
875 static void test_GetItemObject(void)
877 IShellFolder
*desktop
;
882 create_interfaces(&desktop
, &view
);
884 /* from documentation three interfaces are supported for SVGIO_BACKGROUND:
885 IContextMenu, IDispatch, IPersistHistory */
886 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IContextMenu
, (void**)&unk
);
887 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
888 IUnknown_Release(unk
);
891 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&unk
);
892 ok(hr
== S_OK
|| broken(hr
== E_NOTIMPL
) /* NT4 */, "got (0x%08lx)\n", hr
);
893 if (unk
) IUnknown_Release(unk
);
896 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IPersistHistory
, (void**)&unk
);
897 todo_wine
ok(hr
== S_OK
|| broken(hr
== E_NOTIMPL
) /* W9x, NT4 */, "got (0x%08lx)\n", hr
);
898 if (unk
) IUnknown_Release(unk
);
900 /* example of unsupported interface, base for IPersistHistory */
901 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IPersist
, (void**)&unk
);
902 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
) /* W2K */, "got (0x%08lx)\n", hr
);
904 destroy_interfaces(desktop
, view
);
907 static void test_IShellFolderView(void)
909 IShellFolderView
*folderview
;
910 IShellFolder
*desktop
;
916 create_interfaces(&desktop
, &view
);
918 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderView
, (void**)&folderview
);
921 win_skip("IShellView doesn't provide IShellFolderView on this platform\n");
922 destroy_interfaces(desktop
, view
);
927 obj
= IDataObjectImpl_Construct();
928 hr
= IShellFolderView_MoveIcons(folderview
, obj
);
929 ok(hr
== E_NOTIMPL
|| broken(hr
== S_OK
) /* W98 */, "got (0x%08lx)\n", hr
);
930 IDataObject_Release(obj
);
932 /* ::SetRedraw without list created */
933 hr
= IShellFolderView_SetRedraw(folderview
, TRUE
);
934 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
937 hr
= IShellFolderView_QuerySupport(folderview
, NULL
);
938 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
940 hr
= IShellFolderView_QuerySupport(folderview
, &i
);
941 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
942 ok(i
== 0xdeadbeef, "got %d\n", i
);
946 hr
= IShellFolderView_RemoveObject(folderview
, NULL
, &i
);
947 ok(hr
== S_OK
|| hr
== E_FAIL
, "got (0x%08lx)\n", hr
);
948 if (hr
== S_OK
) ok(i
== 0 || broken(i
== 0xdeadbeef) /* Vista, 2k8 */,
951 IShellFolderView_Release(folderview
);
953 destroy_interfaces(desktop
, view
);
956 static void test_IOleWindow(void)
958 IShellFolder
*desktop
;
963 create_interfaces(&desktop
, &view
);
965 hr
= IShellView_QueryInterface(view
, &IID_IOleWindow
, (void**)&wnd
);
966 ok(hr
== E_NOINTERFACE
, "got (0x%08lx)\n", hr
);
968 /* IShellView::ContextSensitiveHelp */
969 hr
= IShellView_ContextSensitiveHelp(view
, TRUE
);
970 ok(hr
== E_NOTIMPL
, "got (0x%08lx)\n", hr
);
971 hr
= IShellView_ContextSensitiveHelp(view
, FALSE
);
972 ok(hr
== E_NOTIMPL
, "got (0x%08lx)\n", hr
);
974 destroy_interfaces(desktop
, view
);
977 static const struct message folderview_setcurrentviewmode1_2_prevista
[] = {
978 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_ICON
},
979 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
980 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
982 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
983 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
984 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
985 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
986 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
987 { LVM_ARRANGE
, sent
},
988 { LVM_ARRANGE
, sent
|optional
}, /* WinXP */
992 static const struct message folderview_setcurrentviewmode3_prevista
[] = {
993 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_LIST
},
994 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
995 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
997 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
998 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
999 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
1000 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
1001 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
1005 static const struct message folderview_setcurrentviewmode4_prevista
[] = {
1006 { LVM_GETHEADER
, sent
},
1007 { LVM_GETITEMCOUNT
, sent
|optional
},
1008 { LVM_SETSELECTEDCOLUMN
, sent
},
1009 { WM_NOTIFY
, sent
},
1010 { WM_NOTIFY
, sent
},
1011 { WM_NOTIFY
, sent
},
1012 { WM_NOTIFY
, sent
},
1013 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_DETAILS
},
1014 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
1015 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
1017 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
1018 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
1019 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
1020 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
1021 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
1025 /* XP, SetCurrentViewMode(5)
1026 108e - LVM_SETVIEW (LV_VIEW_ICON);
1027 1036 - LVM_SETEXTEDEDLISTVIEWSTYLE (0x8000, 0)
1028 100c/104c repeated X times
1029 1003 - LVM_SETIMAGELIST
1030 1035 - LVM_SETICONSPACING
1031 1004 - LVM_GETITEMCOUNT
1037 /* XP, SetCurrentViewMode(6)
1038 1036 - LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0)
1039 1035 - LVM_SETICONSPACING
1040 1003 - LVM_SETIMAGELIST
1041 1003 - LVM_SETIMAGELIST
1042 100c/104c repeated X times
1043 10a2 - LVM_SETTILEVIEWINFO
1044 108e - LVM_SETVIEW (LV_VIEW_TILE)
1045 1003 - LVM_SETIMAGELIST
1051 /* XP, SetCurrentViewMode (7)
1052 10a2 - LVM_SETTILEVIEWINFO
1053 108e - LVM_SETVIEW (LV_VIEW_ICON)
1054 1004/10a4 (LVM_GETITEMCOUNT/LVM_SETTILEINFO) X times
1058 LVM_SETEXTENDEDLISTVIEWSTYLE (0x40000, 0x40000)
1060 LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0x8000)
1063 static void test_GetSetCurrentViewMode(void)
1065 IShellFolder
*desktop
;
1068 IShellBrowser
*browser
;
1072 RECT rc
= {0, 0, 10, 10};
1075 static const int winxp_res
[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1076 static const int win2k3_res
[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0};
1077 static const int vista_res
[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0};
1078 static const int win7_res
[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8};
1080 create_interfaces(&desktop
, &sview
);
1082 hr
= IShellView_QueryInterface(sview
, &IID_IFolderView
, (void **)&fview
);
1083 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1085 viewmode
= 0xdeadbeef;
1086 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1087 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1088 ok(viewmode
== FVM_TILE
|| broken(viewmode
== 0) /* pre win7 */, "Got view mode %u.\n", viewmode
);
1092 browser
= IShellBrowserImpl_Construct();
1093 hr
= IShellView_CreateViewWindow(sview
, NULL
, &fs
, browser
, &rc
, &hwnd
);
1094 ok(hr
== S_OK
|| broken(hr
== S_FALSE
/*Win2k*/ ), "got (0x%08lx)\n", hr
);
1103 /* Crashes under Win7/WinXP */
1104 IFolderView_GetCurrentViewMode(fview
, NULL
);
1107 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1108 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1109 ok(viewmode
== 1, "ViewMode was %d\n", viewmode
);
1111 hr
= IFolderView_SetCurrentViewMode(fview
, FVM_AUTO
);
1112 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1113 viewmode
= 0xdeadbeef;
1114 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1115 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1116 ok(viewmode
== FVM_ICON
|| broken(viewmode
== FVM_AUTO
) /* pre vista */, "Got view mode %d.\n", viewmode
);
1118 hr
= IFolderView_SetCurrentViewMode(fview
, FVM_LIST
);
1119 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1120 viewmode
= 0xdeadbeef;
1121 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1122 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1123 ok(viewmode
== FVM_LIST
, "Got view mode %d.\n", viewmode
);
1124 hr
= IFolderView_SetCurrentViewMode(fview
, 0);
1125 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* pre win7 */, "Got hr %#lx.\n", hr
);
1126 viewmode
= 0xdeadbeef;
1127 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1128 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1129 ok(viewmode
== FVM_LIST
|| broken(viewmode
== 0) /* pre vista */, "Got view mode %d.\n", viewmode
);
1131 for(i
= 1; i
< 9; i
++)
1133 hr
= IFolderView_SetCurrentViewMode(fview
, i
);
1134 ok(hr
== S_OK
|| (i
== 8 && hr
== E_INVALIDARG
/*Vista*/),
1135 "(%d) got (0x%08lx)\n", i
, hr
);
1137 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1138 ok(hr
== S_OK
, "(%d) got (0x%08lx)\n", i
, hr
);
1140 /* Wine currently behaves like winxp here. */
1141 ok((viewmode
== win7_res
[i
]) || (viewmode
== vista_res
[i
]) ||
1142 (viewmode
== win2k3_res
[i
]) || (viewmode
== winxp_res
[i
]),
1143 "(%d) got %d\n",i
, viewmode
);
1146 hr
= IFolderView_SetCurrentViewMode(fview
, 9);
1147 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* pre win7 */, "Got hr %#lx.\n", hr
);
1148 viewmode
= 0xdeadbeef;
1149 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1150 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1151 ok(viewmode
== FVM_CONTENT
|| broken(viewmode
== 9) /* pre vista */ ||
1152 broken(viewmode
== FVM_THUMBSTRIP
) /* vista */, "Got view mode %d.\n", viewmode
);
1155 hwnd_lv
= subclass_listview(hwnd
);
1156 ok(hwnd_lv
!= NULL
, "Failed to subclass listview\n");
1159 /* Vista seems to set the viewmode by other means than
1160 sending messages. At least no related messages are
1161 captured by subclassing.
1163 BOOL vista_plus
= FALSE
;
1164 static const UINT vista_plus_msgs
[] = {
1165 WM_SETREDRAW
, WM_NOTIFY
, WM_NOTIFYFORMAT
, WM_QUERYUISTATE
,
1166 WM_MENUCHAR
, WM_WINDOWPOSCHANGING
, WM_NCCALCSIZE
, WM_WINDOWPOSCHANGED
,
1167 WM_PARENTNOTIFY
, LVM_GETHEADER
, 0 };
1169 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1170 hr
= IFolderView_SetCurrentViewMode(fview
, 1);
1171 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1173 /* WM_SETREDRAW is not sent in versions before Vista. */
1174 vista_plus
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, WM_SETREDRAW
);
1176 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1178 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode1_2_prevista
,
1179 "IFolderView::SetCurrentViewMode(1)", TRUE
);
1181 hr
= IFolderView_SetCurrentViewMode(fview
, 2);
1182 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1184 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1186 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode1_2_prevista
,
1187 "IFolderView::SetCurrentViewMode(2)", TRUE
);
1189 hr
= IFolderView_SetCurrentViewMode(fview
, 3);
1190 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1192 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1194 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode3_prevista
,
1195 "IFolderView::SetCurrentViewMode(3)", TRUE
);
1197 hr
= IFolderView_SetCurrentViewMode(fview
, 4);
1198 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1200 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1202 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode4_prevista
,
1203 "IFolderView::SetCurrentViewMode(4)", TRUE
);
1205 hr
= IFolderView_SetCurrentViewMode(fview
, 5);
1206 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1211 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1215 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1216 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1217 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1218 ok(count
== 1 || count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1219 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1223 hr
= IFolderView_SetCurrentViewMode(fview
, 6);
1224 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1229 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1233 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1234 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1235 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1236 ok(count
== 1 || count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1237 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1241 hr
= IFolderView_SetCurrentViewMode(fview
, 7);
1242 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1247 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1251 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1252 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1253 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1254 ok(count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1255 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1259 hr
= IFolderView_SetCurrentViewMode(fview
, 8);
1260 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
/* Vista */), "got 0x%08lx\n", hr
);
1265 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1269 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1270 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1271 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1272 ok(count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1273 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1277 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1278 ok(hr
== S_OK
, "Failed to get current viewmode.\n");
1279 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, empty_seq
,
1280 "IFolderView::GetCurrentViewMode", FALSE
);
1283 IFolderView_Release(fview
);
1287 skip("No IFolderView for the desktop folder.\n");
1290 IShellBrowser_Release(browser
);
1291 IShellView_DestroyViewWindow(sview
);
1292 destroy_interfaces(desktop
, sview
);
1295 static void test_IOleCommandTarget(void)
1297 IShellFolder
*psf_desktop
;
1299 IOleCommandTarget
*poct
;
1302 hr
= SHGetDesktopFolder(&psf_desktop
);
1303 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1305 hr
= IShellFolder_CreateViewObject(psf_desktop
, NULL
, &IID_IShellView
, (void**)&psv
);
1306 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1309 hr
= IShellView_QueryInterface(psv
, &IID_IOleCommandTarget
, (void**)&poct
);
1310 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Win95/NT4 */, "Got 0x%08lx\n", hr
);
1315 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 0, NULL
, NULL
);
1316 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1319 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 0, &oc
, NULL
);
1320 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08lx\n", hr
);
1323 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 1, &oc
, NULL
);
1324 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08lx\n", hr
);
1326 hr
= IOleCommandTarget_Exec(poct
, NULL
, 0, 0, NULL
, NULL
);
1327 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08lx\n", hr
);
1329 IOleCommandTarget_Release(poct
);
1332 IShellView_Release(psv
);
1335 IShellFolder_Release(psf_desktop
);
1338 static void test_SHCreateShellFolderView(void)
1340 IShellFolder
*desktop
;
1347 hr
= SHGetDesktopFolder(&desktop
);
1348 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1353 SHCreateShellFolderView(NULL
, NULL
);
1356 psv
= (void *)0xdeadbeef;
1357 hr
= SHCreateShellFolderView(NULL
, &psv
);
1358 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1359 ok(psv
== NULL
, "psv = %p\n", psv
);
1361 memset(&sfvc
, 0, sizeof(sfvc
));
1362 psv
= (void *)0xdeadbeef;
1363 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1364 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1365 ok(psv
== NULL
, "psv = %p\n", psv
);
1367 memset(&sfvc
, 0, sizeof(sfvc
));
1368 sfvc
.cbSize
= sizeof(sfvc
) - 1;
1369 psv
= (void *)0xdeadbeef;
1370 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1371 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1372 ok(psv
== NULL
, "psv = %p\n", psv
);
1374 memset(&sfvc
, 0, sizeof(sfvc
));
1375 sfvc
.cbSize
= sizeof(sfvc
) + 1;
1376 psv
= (void *)0xdeadbeef;
1377 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1378 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1379 ok(psv
== NULL
, "psv = %p\n", psv
);
1383 /* Crashes on NULL 'pshf' on XP/2k3 */
1384 memset(&sfvc
, 0, sizeof(sfvc
));
1385 sfvc
.cbSize
= sizeof(sfvc
);
1386 psv
= (void *)0xdeadbeef;
1387 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1388 ok(hr
== E_UNEXPECTED
, "Got 0x%08lx\n", hr
);
1389 ok(psv
== NULL
, "psv = %p\n", psv
);
1391 memset(&sfvc
, 0, sizeof(sfvc
));
1392 sfvc
.cbSize
= sizeof(sfvc
) - 1;
1393 sfvc
.pshf
= desktop
;
1394 psv
= (void *)0xdeadbeef;
1395 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1396 ok(hr
== E_INVALIDARG
, "Got 0x%08lx\n", hr
);
1397 ok(psv
== NULL
, "psv = %p\n", psv
);
1399 memset(&sfvc
, 0, sizeof(sfvc
));
1400 sfvc
.cbSize
= sizeof(sfvc
);
1401 sfvc
.pshf
= desktop
;
1403 hr
= SHCreateShellFolderView(&sfvc
, &psv
);
1404 ok(hr
== S_OK
, "Got 0x%08lx\n", hr
);
1405 ok(psv
!= NULL
, "psv = %p\n", psv
);
1407 hr
= IShellView_QueryInterface(psv
, &IID_CDefView
, (void **)&unk
);
1408 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1409 ok(unk
== (IUnknown
*)psv
, "got %p\n", unk
);
1410 IUnknown_Release(unk
);
1412 refCount
= IShellView_Release(psv
);
1413 ok(refCount
== 0, "refCount = %lu\n", refCount
);
1415 IShellFolder_Release(desktop
);
1418 static void test_SHCreateShellFolderViewEx(void)
1420 IShellFolder
*desktop
;
1427 hr
= SHGetDesktopFolder(&desktop
);
1428 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1433 SHCreateShellFolderViewEx(NULL
, NULL
);
1434 SHCreateShellFolderViewEx(NULL
, &psv
);
1435 SHCreateShellFolderViewEx(&csfv
, NULL
);
1438 memset(&csfv
, 0, sizeof(csfv
));
1439 csfv
.pshf
= desktop
;
1441 hr
= SHCreateShellFolderViewEx(&csfv
, &psv
);
1442 ok(hr
== S_OK
, "Got 0x%08lx\n", hr
);
1443 ok(psv
!= NULL
, "psv = %p\n", psv
);
1445 hr
= IShellView_QueryInterface(psv
, &IID_CDefView
, (void **)&unk
);
1446 ok(hr
== S_OK
, "got (0x%08lx)\n", hr
);
1447 ok(unk
== (IUnknown
*)psv
, "got %p\n", unk
);
1448 IUnknown_Release(unk
);
1450 refCount
= IShellView_Release(psv
);
1451 ok(refCount
== 0, "refCount = %lu\n", refCount
);
1455 /* Crashes on null shellfolder, on XP/2k3 */
1456 memset(&csfv
, 0, sizeof(csfv
));
1458 psv
= (void *)0xdeadbeef;
1459 hr
= SHCreateShellFolderViewEx(&csfv
, &psv
);
1460 ok(hr
== E_UNEXPECTED
, "Got 0x%08lx\n", hr
);
1461 ok(psv
== NULL
, "psv = %p\n", psv
);
1463 memset(&csfv
, 0, sizeof(csfv
));
1464 csfv
.cbSize
= sizeof(csfv
);
1465 csfv
.pshf
= desktop
;
1467 hr
= SHCreateShellFolderViewEx(&csfv
, &psv
);
1468 ok(hr
== S_OK
, "Got 0x%08lx\n", hr
);
1469 ok(psv
!= NULL
, "psv = %p\n", psv
);
1472 refCount
= IShellView_Release(psv
);
1473 ok(refCount
== 0, "refCount = %lu\n", refCount
);
1476 IShellFolder_Release(desktop
);
1479 static void test_newmenu(void)
1481 CMINVOKECOMMANDINFO invoke_info
= {.cbSize
= sizeof(CMINVOKECOMMANDINFO
)};
1482 IObjectWithSite
*ows
;
1483 WCHAR path
[MAX_PATH
];
1484 IShellExtInit
*init
;
1485 IContextMenu3
*menu
;
1495 hmenu
= CreatePopupMenu();
1497 hr
= CoCreateInstance(&CLSID_NewMenu
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&unk
);
1498 ok(hr
== S_OK
, "Failed to create NewMenu object, hr %#lx.\n", hr
);
1499 hr
= IUnknown_QueryInterface(unk
, &IID_IShellExtInit
, (void **)&init
);
1500 ok(hr
== S_OK
, "Failed to get IShellExtInit, hr %#lx.\n", hr
);
1501 hr
= IUnknown_QueryInterface(unk
, &IID_IContextMenu3
, (void **)&menu
);
1502 ok(hr
== S_OK
, "Failed to get IContextMenu3, hr %#lx.\n", hr
);
1503 hr
= IUnknown_QueryInterface(unk
, &IID_IObjectWithSite
, (void **)&ows
);
1504 ok(hr
== S_OK
, "Failed to get IObjectWithSite, hr %#lx.\n", hr
);
1506 GetTempPathW(ARRAY_SIZE(path
), path
);
1507 hr
= SHParseDisplayName(path
, NULL
, &pidl
, 0, NULL
);
1508 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1510 hr
= IShellExtInit_Initialize(init
, NULL
, NULL
, NULL
);
1511 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
1513 hr
= IShellExtInit_Initialize(init
, pidl
, NULL
, NULL
);
1514 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1516 hr
= IContextMenu3_QueryContextMenu(menu
, hmenu
, 0, 1, 1000, CMF_EXPLORE
);
1517 ok(hr
== 0x40, "Got hr %#lx.\n", hr
);
1519 count
= GetMenuItemCount(hmenu
);
1520 ok(count
== 1, "Got count %d.\n", count
);
1522 info
.cbSize
= sizeof(info
);
1523 info
.fMask
= MIIM_ID
| MIIM_FTYPE
| MIIM_SUBMENU
;
1524 ret
= GetMenuItemInfoA(hmenu
, 0, TRUE
, &info
);
1525 ok(ret
== TRUE
, "Got error %lu.\n", GetLastError());
1526 ok(info
.wID
== 1, "Got ID %u.\n", info
.wID
);
1527 ok(!info
.fType
, "Got type %#x.\n", info
.fType
);
1528 ok(!!info
.hSubMenu
, "Got sub-menu %p.\n", info
.hSubMenu
);
1530 invoke_info
.lpVerb
= (const char *)1234;
1531 hr
= IContextMenu3_InvokeCommand(menu
, &invoke_info
);
1532 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
1535 IObjectWithSite_Release(ows
);
1536 IContextMenu3_Release(menu
);
1537 IShellExtInit_Release(init
);
1538 ref
= IUnknown_Release(unk
);
1539 ok(!ref
, "Got refcount %ld.\n", ref
);
1541 /* Test with a virtual folder that can't create new items. */
1543 hmenu
= CreatePopupMenu();
1545 hr
= CoCreateInstance(&CLSID_NewMenu
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&unk
);
1546 ok(hr
== S_OK
, "Failed to create NewMenu object, hr %#lx.\n", hr
);
1547 hr
= IUnknown_QueryInterface(unk
, &IID_IShellExtInit
, (void **)&init
);
1548 ok(hr
== S_OK
, "Failed to get IShellExtInit, hr %#lx.\n", hr
);
1549 hr
= IUnknown_QueryInterface(unk
, &IID_IContextMenu3
, (void **)&menu
);
1550 ok(hr
== S_OK
, "Failed to get IContextMenu3, hr %#lx.\n", hr
);
1552 hr
= SHGetKnownFolderIDList(&FOLDERID_ComputerFolder
, 0, NULL
, &pidl
);
1553 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1555 hr
= IShellExtInit_Initialize(init
, pidl
, NULL
, NULL
);
1556 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1558 hr
= IContextMenu3_QueryContextMenu(menu
, hmenu
, 0, 1, 1000, CMF_EXPLORE
);
1559 ok(hr
== 0, "Got hr %#lx.\n", hr
);
1561 count
= GetMenuItemCount(hmenu
);
1562 ok(!count
, "Got count %d.\n", count
);
1565 IContextMenu3_Release(menu
);
1566 IShellExtInit_Release(init
);
1567 ref
= IUnknown_Release(unk
);
1568 ok(!ref
, "Got refcount %ld.\n", ref
);
1571 static void test_folder_flags(void)
1573 IFolderView2
*folderview
;
1574 FOLDERSETTINGS settings
;
1575 IShellFolder
*desktop
;
1576 IShellView
*shellview
;
1586 { FWF_USESEARCHFOLDER
, FWF_NONE
, FWF_NONE
},
1587 { FWF_NONE
, FWF_AUTOARRANGE
, FWF_NONE
},
1588 { FWF_AUTOARRANGE
, FWF_AUTOARRANGE
, FWF_AUTOARRANGE
},
1589 { FWF_OWNERDATA
, FWF_AUTOARRANGE
, FWF_NONE
},
1590 { FWF_AUTOARRANGE
, FWF_OWNERDATA
| FWF_AUTOARRANGE
, FWF_AUTOARRANGE
},
1591 { ~FWF_NONE
, FWF_AUTOARRANGE
, FWF_AUTOARRANGE
},
1594 create_interfaces(&desktop
, &shellview
);
1596 hr
= IShellView_GetCurrentInfo(shellview
, &settings
);
1597 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1598 ok(settings
.ViewMode
== FVM_TILE
|| broken(!settings
.ViewMode
) /* pre win7 */,
1599 "Got view mode %u.\n", settings
.ViewMode
);
1600 ok(settings
.fFlags
== FWF_USESEARCHFOLDER
|| broken(!settings
.fFlags
) /* pre vista */,
1601 "Got flags %#x.\n", settings
.fFlags
);
1603 hr
= IShellView_QueryInterface(shellview
, &IID_IFolderView2
, (void **)&folderview
);
1604 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* pre vista */, "Got hr %#lx.\n", hr
);
1607 win_skip("No IFolderView2 for the desktop folder.\n");
1608 destroy_interfaces(desktop
, shellview
);
1612 hr
= IFolderView2_GetCurrentFolderFlags(folderview
, NULL
);
1613 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1616 hr
= IFolderView2_GetCurrentFolderFlags(folderview
, &flags
);
1617 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1618 ok(flags
== FWF_USESEARCHFOLDER
, "Got flags %#lx.\n", flags
);
1620 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1622 hr
= IFolderView2_SetCurrentFolderFlags(folderview
, tests
[i
].mask
, tests
[i
].flags
);
1623 ok(hr
== S_OK
, "Test %u: Got hr %#lx.\n", i
, hr
);
1625 hr
= IFolderView2_GetCurrentFolderFlags(folderview
, &flags
);
1626 ok(hr
== S_OK
, "Test %u: Got hr %#lx.\n", i
, hr
);
1627 ok(flags
== tests
[i
].expected
, "Test %u: Got flags %#lx.\n", i
, flags
);
1629 hr
= IFolderView2_SetCurrentFolderFlags(folderview
, ~FWF_NONE
, FWF_NONE
);
1630 ok(hr
== S_OK
, "Test %u: Got hr %#lx.\n", i
, hr
);
1633 IFolderView2_Release(folderview
);
1634 destroy_interfaces(desktop
, shellview
);
1639 OleInitialize(NULL
);
1641 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1643 test_CreateViewWindow();
1645 test_GetItemObject();
1646 test_IShellFolderView();
1648 test_GetSetCurrentViewMode();
1649 test_IOleCommandTarget();
1650 test_SHCreateShellFolderView();
1651 test_SHCreateShellFolderViewEx();
1653 test_folder_flags();