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 IDataObject_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 IShellBrowser_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 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 IFolderView_GetSpacing(fv
, &pt
);
583 IFolderView_GetSelectionMarkedItem(fv
, NULL
);
584 IFolderView_GetFocusedItem(fv
, NULL
);
586 /* crashes on Vista+ */
587 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 IFolderView_ItemCount(fv
, SVGIO_ALLVIEW
, NULL
);
638 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
639 IFolderView_ItemCount(fv
, SVGIO_ALLVIEW
, &count
);
641 /* IFolderView::GetSelectionMarkedItem */
645 IFolderView_GetSelectionMarkedItem(fv
, NULL
);
648 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
649 hr
= IFolderView_GetSelectionMarkedItem(fv
, &ret
);
651 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
653 ok(hr
== S_FALSE
, "got (0x%08x)\n", hr
);
654 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_getselectionmarked_seq
,
655 "IFolderView::GetSelectionMarkedItem", FALSE
);
657 /* IFolderView::GetFocusedItem */
658 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
659 hr
= IFolderView_GetFocusedItem(fv
, &ret
);
661 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
663 ok(hr
== S_FALSE
, "got (0x%08x)\n", hr
);
664 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_getfocused_seq
,
665 "IFolderView::GetFocusedItem", FALSE
);
667 /* IFolderView::GetFolder, just return pointer */
671 IFolderView_GetFolder(fv
, NULL
, (void**)&folder
);
672 IFolderView_GetFolder(fv
, NULL
, NULL
);
675 hr
= IFolderView_GetFolder(fv
, &IID_IShellFolder
, NULL
);
676 ok(hr
== E_POINTER
, "got (0x%08x)\n", hr
);
678 ref1
= IShellFolder_AddRef(desktop
);
679 IShellFolder_Release(desktop
);
680 hr
= IFolderView_GetFolder(fv
, &IID_IShellFolder
, (void**)&folder
);
681 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
682 ref2
= IShellFolder_AddRef(desktop
);
683 IShellFolder_Release(desktop
);
684 ok(ref1
== ref2
|| ref1
+ 1 == ref2
, /* >= vista */
685 "expected same refcount, got %d\n", ref2
);
686 ok(desktop
== folder
, "\n");
688 IShellBrowser_Release(browser
);
689 IFolderView_Release(fv
);
690 IShellView_Release(view
);
691 IShellFolder_Release(desktop
);
694 static void test_GetItemObject(void)
696 IShellFolder
*desktop
;
701 hr
= SHGetDesktopFolder(&desktop
);
702 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
704 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
705 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
707 /* from documentation three interfaces are supported for SVGIO_BACKGROUND:
708 IContextMenu, IDispatch, IPersistHistory */
709 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IContextMenu
, (void**)&unk
);
710 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
711 IUnknown_Release(unk
);
714 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&unk
);
715 todo_wine
ok(hr
== S_OK
|| broken(hr
== E_NOTIMPL
) /* NT4 */, "got (0x%08x)\n", hr
);
716 if (unk
) IUnknown_Release(unk
);
719 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IPersistHistory
, (void**)&unk
);
720 todo_wine
ok(hr
== S_OK
|| broken(hr
== E_NOTIMPL
) /* W9x, NT4 */, "got (0x%08x)\n", hr
);
721 if (unk
) IUnknown_Release(unk
);
723 /* example of unsupported interface, base for IPersistHistory */
724 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IPersist
, (void**)&unk
);
725 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
) /* W2K */, "got (0x%08x)\n", hr
);
727 IShellView_Release(view
);
728 IShellFolder_Release(desktop
);
731 static void test_IShellFolderView(void)
733 IShellFolderView
*folderview
;
734 IShellFolder
*desktop
;
740 hr
= SHGetDesktopFolder(&desktop
);
741 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
743 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
744 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
746 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderView
, (void**)&folderview
);
749 win_skip("IShellView doesn't provide IShellFolderView on this platform\n");
750 IShellView_Release(view
);
751 IShellFolder_Release(desktop
);
756 obj
= IDataObjectImpl_Construct();
757 hr
= IShellFolderView_MoveIcons(folderview
, obj
);
758 ok(hr
== E_NOTIMPL
|| broken(hr
== S_OK
) /* W98 */, "got (0x%08x)\n", hr
);
759 IDataObject_Release(obj
);
761 /* ::SetRedraw without list created */
762 hr
= IShellFolderView_SetRedraw(folderview
, TRUE
);
763 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
766 hr
= IShellFolderView_QuerySupport(folderview
, NULL
);
767 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
769 hr
= IShellFolderView_QuerySupport(folderview
, &i
);
770 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
771 ok(i
== 0xdeadbeef, "got %d\n", i
);
775 hr
= IShellFolderView_RemoveObject(folderview
, NULL
, &i
);
776 ok(hr
== S_OK
|| hr
== E_FAIL
, "got (0x%08x)\n", hr
);
777 if (hr
== S_OK
) ok(i
== 0 || broken(i
== 0xdeadbeef) /* Vista, 2k8 */,
780 IShellFolderView_Release(folderview
);
782 IShellView_Release(view
);
783 IShellFolder_Release(desktop
);
786 static void test_IOleWindow(void)
788 IShellFolder
*desktop
;
792 hr
= SHGetDesktopFolder(&desktop
);
793 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
795 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
796 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
798 /* IShellView::ContextSensitiveHelp */
799 hr
= IShellView_ContextSensitiveHelp(view
, TRUE
);
800 ok(hr
== E_NOTIMPL
, "got (0x%08x)\n", hr
);
801 hr
= IShellView_ContextSensitiveHelp(view
, FALSE
);
802 ok(hr
== E_NOTIMPL
, "got (0x%08x)\n", hr
);
804 IShellView_Release(view
);
805 IShellFolder_Release(desktop
);
808 static const struct message folderview_setcurrentviewmode1_2_prevista
[] = {
809 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_ICON
},
810 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
811 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
813 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
814 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
815 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
816 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
817 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
818 { LVM_ARRANGE
, sent
},
819 { LVM_ARRANGE
, sent
|optional
}, /* WinXP */
823 static const struct message folderview_setcurrentviewmode3_prevista
[] = {
824 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_LIST
},
825 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
826 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
828 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
829 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
830 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
831 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
832 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
836 static const struct message folderview_setcurrentviewmode4_prevista
[] = {
837 { LVM_GETHEADER
, sent
},
838 { LVM_GETITEMCOUNT
, sent
|optional
},
839 { LVM_SETSELECTEDCOLUMN
, sent
},
844 { LVM_SETVIEW
, sent
|wparam
, LV_VIEW_DETAILS
},
845 { LVM_SETIMAGELIST
, sent
|wparam
, 0},
846 { LVM_SETIMAGELIST
, sent
|wparam
, 1},
848 { LVM_SETBKIMAGEW
, sent
|optional
}, /* w2k3 */
849 { LVM_GETBKCOLOR
, sent
|optional
}, /* w2k3 */
850 { LVM_GETTEXTBKCOLOR
, sent
|optional
}, /* w2k3 */
851 { LVM_GETTEXTCOLOR
, sent
|optional
}, /* w2k3 */
852 { LVM_SETEXTENDEDLISTVIEWSTYLE
, sent
|optional
|wparam
, 0xc8}, /* w2k3 */
856 /* XP, SetCurrentViewMode(5)
857 108e - LVM_SETVIEW (LV_VIEW_ICON);
858 1036 - LVM_SETEXTEDEDLISTVIEWSTYLE (0x8000, 0)
859 100c/104c repeated X times
860 1003 - LVM_SETIMAGELIST
861 1035 - LVM_SETICONSPACING
862 1004 - LVM_GETITEMCOUNT
868 /* XP, SetCurrentViewMode(6)
869 1036 - LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0)
870 1035 - LVM_SETICONSPACING
871 1003 - LVM_SETIMAGELIST
872 1003 - LVM_SETIMAGELIST
873 100c/104c repeated X times
874 10a2 - LVM_SETTILEVIEWINFO
875 108e - LVM_SETVIEW (LV_VIEW_TILE)
876 1003 - LVM_SETIMAGELIST
882 /* XP, SetCurrentViewMode (7)
883 10a2 - LVM_SETTILEVIEWINFO
884 108e - LVM_SETVIEW (LV_VIEW_ICON)
885 1004/10a4 (LVM_GETITEMCOUNT/LVM_SETTILEINFO) X times
889 LVM_SETEXTENDEDLISTVIEWSTYLE (0x40000, 0x40000)
891 LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0x8000)
894 static void test_GetSetCurrentViewMode(void)
896 IShellFolder
*desktop
;
899 IShellBrowser
*browser
;
903 RECT rc
= {0, 0, 10, 10};
906 static const int winxp_res
[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
907 static const int win2k3_res
[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0};
908 static const int vista_res
[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0};
909 static const int win7_res
[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8};
911 hr
= SHGetDesktopFolder(&desktop
);
912 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
914 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&sview
);
915 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
919 browser
= IShellBrowserImpl_Construct();
920 hr
= IShellView_CreateViewWindow(sview
, NULL
, &fs
, browser
, &rc
, &hwnd
);
921 ok(hr
== S_OK
|| broken(hr
== S_FALSE
/*Win2k*/ ), "got (0x%08x)\n", hr
);
923 hr
= IShellView_QueryInterface(sview
, &IID_IFolderView
, (void**)&fview
);
924 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
), "got (0x%08x)\n", hr
);
932 /* Crashes under Win7/WinXP */
933 IFolderView_GetCurrentViewMode(fview
, NULL
);
936 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
937 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
938 ok(viewmode
== 1, "ViewMode was %d\n", viewmode
);
940 hr
= IFolderView_SetCurrentViewMode(fview
, FVM_AUTO
);
941 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
943 hr
= IFolderView_SetCurrentViewMode(fview
, 0);
944 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
),
945 "got (0x%08x)\n", hr
);
947 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
948 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
950 for(i
= 1; i
< 9; i
++)
952 hr
= IFolderView_SetCurrentViewMode(fview
, i
);
953 ok(hr
== S_OK
|| (i
== 8 && hr
== E_INVALIDARG
/*Vista*/),
954 "(%d) got (0x%08x)\n", i
, hr
);
956 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
957 ok(hr
== S_OK
, "(%d) got (0x%08x)\n", i
, hr
);
959 /* Wine currently behaves like winxp here. */
960 ok((viewmode
== win7_res
[i
]) || (viewmode
== vista_res
[i
]) ||
961 (viewmode
== win2k3_res
[i
]) || (viewmode
== winxp_res
[i
]),
962 "(%d) got %d\n",i
, viewmode
);
965 hr
= IFolderView_SetCurrentViewMode(fview
, 9);
966 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
),
967 "got (0x%08x)\n", hr
);
970 hwnd_lv
= subclass_listview(hwnd
);
971 ok(hwnd_lv
!= NULL
, "Failed to subclass listview\n");
974 /* Vista seems to set the viewmode by other means than
975 sending messages. At least no related messages are
976 captured by subclassing.
978 BOOL vista_plus
= FALSE
;
979 static const UINT vista_plus_msgs
[] = {
980 WM_SETREDRAW
, WM_NOTIFY
, WM_NOTIFYFORMAT
, WM_QUERYUISTATE
,
981 WM_MENUCHAR
, WM_WINDOWPOSCHANGING
, WM_NCCALCSIZE
, WM_WINDOWPOSCHANGED
,
982 WM_PARENTNOTIFY
, LVM_GETHEADER
, 0 };
984 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
985 hr
= IFolderView_SetCurrentViewMode(fview
, 1);
986 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
988 /* WM_SETREDRAW is not sent in versions before Vista. */
989 vista_plus
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, WM_SETREDRAW
);
991 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
993 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode1_2_prevista
,
994 "IFolderView::SetCurrentViewMode(1)", TRUE
);
996 hr
= IFolderView_SetCurrentViewMode(fview
, 2);
997 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
999 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1001 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode1_2_prevista
,
1002 "IFolderView::SetCurrentViewMode(2)", TRUE
);
1004 hr
= IFolderView_SetCurrentViewMode(fview
, 3);
1005 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1007 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1009 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode3_prevista
,
1010 "IFolderView::SetCurrentViewMode(3)", TRUE
);
1012 hr
= IFolderView_SetCurrentViewMode(fview
, 4);
1013 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1015 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1017 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, folderview_setcurrentviewmode4_prevista
,
1018 "IFolderView::SetCurrentViewMode(4)", TRUE
);
1020 hr
= IFolderView_SetCurrentViewMode(fview
, 5);
1021 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1026 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1030 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1031 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1032 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1033 ok(count
== 1 || count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1034 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1038 hr
= IFolderView_SetCurrentViewMode(fview
, 6);
1039 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1044 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1048 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1049 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1050 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1051 ok(count
== 1 || count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1052 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1056 hr
= IFolderView_SetCurrentViewMode(fview
, 7);
1057 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1062 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1066 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1067 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1068 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1069 ok(count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1070 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1074 hr
= IFolderView_SetCurrentViewMode(fview
, 8);
1075 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
/* Vista */), "got 0x%08x\n", hr
);
1080 verify_msgs_in(sequences
[LISTVIEW_SEQ_INDEX
], vista_plus_msgs
);
1084 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETVIEW
);
1085 ok(count
== 1, "LVM_SETVIEW sent %d times.\n", count
);
1086 count
= get_msg_count(sequences
, LISTVIEW_SEQ_INDEX
, LVM_SETEXTENDEDLISTVIEWSTYLE
);
1087 ok(count
== 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count
);
1088 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1092 hr
= IFolderView_GetCurrentViewMode(fview
, &viewmode
);
1093 ok(hr
== S_OK
, "Failed to get current viewmode.\n");
1094 ok_sequence(sequences
, LISTVIEW_SEQ_INDEX
, empty_seq
,
1095 "IFolderView::GetCurrentViewMode", FALSE
);
1098 IFolderView_Release(fview
);
1102 skip("No IFolderView for the desktop folder.\n");
1105 IShellBrowser_Release(browser
);
1106 IShellView_DestroyViewWindow(sview
);
1107 IShellView_Release(sview
);
1108 IShellFolder_Release(desktop
);
1111 static void test_IOleCommandTarget(void)
1113 IShellFolder
*psf_desktop
;
1115 IOleCommandTarget
*poct
;
1118 hr
= SHGetDesktopFolder(&psf_desktop
);
1119 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
1121 hr
= IShellFolder_CreateViewObject(psf_desktop
, NULL
, &IID_IShellView
, (void**)&psv
);
1122 ok(hr
== S_OK
, "got (0x%08x)\n", hr
);
1125 hr
= IShellView_QueryInterface(psv
, &IID_IOleCommandTarget
, (void**)&poct
);
1126 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Win95/NT4 */, "Got 0x%08x\n", hr
);
1131 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 0, NULL
, NULL
);
1132 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
1135 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 0, &oc
, NULL
);
1136 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08x\n", hr
);
1139 hr
= IOleCommandTarget_QueryStatus(poct
, NULL
, 1, &oc
, NULL
);
1140 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08x\n", hr
);
1142 hr
= IOleCommandTarget_Exec(poct
, NULL
, 0, 0, NULL
, NULL
);
1143 ok(hr
== OLECMDERR_E_UNKNOWNGROUP
, "Got 0x%08x\n", hr
);
1145 IOleCommandTarget_Release(poct
);
1148 IShellView_Release(psv
);
1151 IShellFolder_Release(psf_desktop
);
1156 OleInitialize(NULL
);
1158 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1160 test_IShellView_CreateViewWindow();
1162 test_GetItemObject();
1163 test_IShellFolderView();
1165 test_GetSetCurrentViewMode();
1166 test_IOleCommandTarget();