2 * Unit tests for the NamespaceTree Control
4 * Copyright 2010 David Hedberg
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
27 #include "wine/test.h"
33 static HRESULT (WINAPI
*pSHCreateShellItem
)(LPCITEMIDLIST
,IShellFolder
*,LPCITEMIDLIST
,IShellItem
**);
34 static HRESULT (WINAPI
*pSHGetIDListFromObject
)(IUnknown
*, PIDLIST_ABSOLUTE
*);
35 static HRESULT (WINAPI
*pSHCreateItemFromParsingName
)(PCWSTR
,IBindCtx
*,REFIID
,void**);
36 static HRESULT (WINAPI
*pSHGetSpecialFolderLocation
)(HWND
, int, LPITEMIDLIST
*);
38 #define NUM_MSG_SEQUENCES 1
39 #define TREEVIEW_SEQ_INDEX 0
41 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
43 /* Keep a copy of the last structure passed by TVM_SETITEMW */
44 static TVITEMEXW last_tvi
;
47 static void init_function_pointers(void)
51 hmod
= GetModuleHandleA("shell32.dll");
52 pSHCreateShellItem
= (void*)GetProcAddress(hmod
, "SHCreateShellItem");
53 pSHGetIDListFromObject
= (void*)GetProcAddress(hmod
, "SHGetIDListFromObject");
54 pSHCreateItemFromParsingName
= (void*)GetProcAddress(hmod
, "SHCreateItemFromParsingName");
55 pSHGetSpecialFolderLocation
= (void*)GetProcAddress(hmod
, "SHGetSpecialFolderLocation");
58 /*******************************************************
59 * INameSpaceTreeControlEvents implementation.
61 enum { OnItemClick
= 0, OnPropertyItemCommit
, OnItemStateChanging
, OnItemStateChanged
,
62 OnSelectionChanged
, OnKeyboardInput
, OnBeforeExpand
, OnAfterExpand
, OnBeginLabelEdit
,
63 OnEndLabelEdit
, OnGetToolTip
, OnBeforeItemDelete
, OnItemAdded
, OnItemDeleted
,
64 OnBeforeContextMenu
, OnAfterContextMenu
, OnBeforeStateImageChange
, OnGetDefaultIconIndex
,
68 INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface
;
69 UINT qi_called_count
; /* Keep track of calls to QueryInterface */
70 BOOL qi_enable_events
; /* If FALSE, QueryInterface returns only E_NOINTERFACE */
71 UINT count
[LastEvent
]; /* Keep track of calls to all On* functions. */
73 } INameSpaceTreeControlEventsImpl
;
75 static inline INameSpaceTreeControlEventsImpl
*impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents
*iface
)
77 return CONTAINING_RECORD(iface
, INameSpaceTreeControlEventsImpl
, INameSpaceTreeControlEvents_iface
);
80 static HRESULT WINAPI
NSTCEvents_fnQueryInterface(
81 INameSpaceTreeControlEvents
* iface
,
85 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
87 This
->qi_called_count
++;
89 if(This
->qi_enable_events
&& IsEqualIID(riid
, &IID_INameSpaceTreeControlEvents
))
91 INameSpaceTreeControlEvents_AddRef(iface
);
99 static ULONG WINAPI
NSTCEvents_fnAddRef(
100 INameSpaceTreeControlEvents
* iface
)
102 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
104 return InterlockedIncrement(&This
->ref
);
107 static ULONG WINAPI
NSTCEvents_fnRelease(
108 INameSpaceTreeControlEvents
* iface
)
110 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
112 return InterlockedDecrement(&This
->ref
);
115 static HRESULT WINAPI
NSTCEvents_fnOnItemClick(
116 INameSpaceTreeControlEvents
* iface
,
118 NSTCEHITTEST nstceHitTest
,
119 NSTCECLICKTYPE nstceClickType
)
121 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
123 ok(psi
!= NULL
, "NULL IShellItem\n");
124 This
->count
[OnItemClick
]++;
128 static HRESULT WINAPI
NSTCEvents_fnOnPropertyItemCommit(
129 INameSpaceTreeControlEvents
* iface
,
132 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
134 ok(psi
!= NULL
, "NULL IShellItem\n");
135 This
->count
[OnPropertyItemCommit
]++;
139 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanging(
140 INameSpaceTreeControlEvents
* iface
,
142 NSTCITEMSTATE nstcisMask
,
143 NSTCITEMSTATE nstcisState
)
145 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
147 ok(psi
!= NULL
, "NULL IShellItem\n");
148 This
->count
[OnItemStateChanging
]++;
152 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanged(
153 INameSpaceTreeControlEvents
* iface
,
155 NSTCITEMSTATE nstcisMask
,
156 NSTCITEMSTATE nstcisState
)
158 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
160 ok(psi
!= NULL
, "NULL IShellItem\n");
161 This
->count
[OnItemStateChanged
]++;
165 static HRESULT WINAPI
NSTCEvents_fnOnSelectionChanged(
166 INameSpaceTreeControlEvents
* iface
,
167 IShellItemArray
*psiaSelection
)
169 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
171 ok(psiaSelection
!= NULL
, "IShellItemArray was NULL.\n");
175 DWORD count
= 0xdeadbeef;
176 hr
= IShellItemArray_GetCount(psiaSelection
, &count
);
177 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
178 ok(count
== 1, "Got count 0x%x\n", count
);
180 This
->count
[OnSelectionChanged
]++;
184 static HRESULT WINAPI
NSTCEvents_fnOnKeyboardInput(
185 INameSpaceTreeControlEvents
* iface
,
190 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
192 This
->count
[OnKeyboardInput
]++;
193 ok(wParam
== 0x1234, "Got unexpected wParam %lx\n", wParam
);
194 ok(lParam
== 0x1234, "Got unexpected lParam %lx\n", lParam
);
198 static HRESULT WINAPI
NSTCEvents_fnOnBeforeExpand(
199 INameSpaceTreeControlEvents
* iface
,
202 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
204 ok(psi
!= NULL
, "NULL IShellItem\n");
205 This
->count
[OnBeforeExpand
]++;
209 static HRESULT WINAPI
NSTCEvents_fnOnAfterExpand(
210 INameSpaceTreeControlEvents
* iface
,
213 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
215 ok(psi
!= NULL
, "NULL IShellItem\n");
216 This
->count
[OnAfterExpand
]++;
220 static HRESULT WINAPI
NSTCEvents_fnOnBeginLabelEdit(
221 INameSpaceTreeControlEvents
* iface
,
224 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
226 ok(psi
!= NULL
, "NULL IShellItem\n");
227 This
->count
[OnBeginLabelEdit
]++;
231 static HRESULT WINAPI
NSTCEvents_fnOnEndLabelEdit(
232 INameSpaceTreeControlEvents
* iface
,
235 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
237 ok(psi
!= NULL
, "NULL IShellItem\n");
238 This
->count
[OnEndLabelEdit
]++;
242 static HRESULT WINAPI
NSTCEvents_fnOnGetToolTip(
243 INameSpaceTreeControlEvents
* iface
,
248 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
250 ok(psi
!= NULL
, "NULL IShellItem\n");
251 This
->count
[OnGetToolTip
]++;
255 static HRESULT WINAPI
NSTCEvents_fnOnBeforeItemDelete(
256 INameSpaceTreeControlEvents
* iface
,
259 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
261 ok(psi
!= NULL
, "NULL IShellItem\n");
262 This
->count
[OnBeforeItemDelete
]++;
266 static HRESULT WINAPI
NSTCEvents_fnOnItemAdded(
267 INameSpaceTreeControlEvents
* iface
,
271 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
273 ok(psi
!= NULL
, "NULL IShellItem\n");
274 This
->count
[OnItemAdded
]++;
278 static HRESULT WINAPI
NSTCEvents_fnOnItemDeleted(
279 INameSpaceTreeControlEvents
* iface
,
283 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
285 ok(psi
!= NULL
, "NULL IShellItem\n");
286 This
->count
[OnItemDeleted
]++;
290 static HRESULT WINAPI
NSTCEvents_fnOnBeforeContextMenu(
291 INameSpaceTreeControlEvents
* iface
,
296 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
298 This
->count
[OnBeforeContextMenu
]++;
302 static HRESULT WINAPI
NSTCEvents_fnOnAfterContextMenu(
303 INameSpaceTreeControlEvents
* iface
,
309 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
311 This
->count
[OnAfterContextMenu
]++;
315 static HRESULT WINAPI
NSTCEvents_fnOnBeforeStateImageChange(
316 INameSpaceTreeControlEvents
* iface
,
319 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
321 ok(psi
!= NULL
, "NULL IShellItem\n");
322 This
->count
[OnBeforeStateImageChange
]++;
326 static HRESULT WINAPI
NSTCEvents_fnOnGetDefaultIconIndex(
327 INameSpaceTreeControlEvents
* iface
,
332 INameSpaceTreeControlEventsImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
334 ok(psi
!= NULL
, "NULL IShellItem\n");
335 This
->count
[OnGetDefaultIconIndex
]++;
339 static const INameSpaceTreeControlEventsVtbl vt_NSTCEvents
= {
340 NSTCEvents_fnQueryInterface
,
342 NSTCEvents_fnRelease
,
343 NSTCEvents_fnOnItemClick
,
344 NSTCEvents_fnOnPropertyItemCommit
,
345 NSTCEvents_fnOnItemStateChanging
,
346 NSTCEvents_fnOnItemStateChanged
,
347 NSTCEvents_fnOnSelectionChanged
,
348 NSTCEvents_fnOnKeyboardInput
,
349 NSTCEvents_fnOnBeforeExpand
,
350 NSTCEvents_fnOnAfterExpand
,
351 NSTCEvents_fnOnBeginLabelEdit
,
352 NSTCEvents_fnOnEndLabelEdit
,
353 NSTCEvents_fnOnGetToolTip
,
354 NSTCEvents_fnOnBeforeItemDelete
,
355 NSTCEvents_fnOnItemAdded
,
356 NSTCEvents_fnOnItemDeleted
,
357 NSTCEvents_fnOnBeforeContextMenu
,
358 NSTCEvents_fnOnAfterContextMenu
,
359 NSTCEvents_fnOnBeforeStateImageChange
,
360 NSTCEvents_fnOnGetDefaultIconIndex
363 static INameSpaceTreeControlEventsImpl
*create_nstc_events(void)
365 INameSpaceTreeControlEventsImpl
*This
;
367 This
= heap_alloc(sizeof(*This
));
368 This
->INameSpaceTreeControlEvents_iface
.lpVtbl
= &vt_NSTCEvents
;
374 /*********************************************************************
375 * Event count checking
377 static void ok_no_events_(INameSpaceTreeControlEventsImpl
*impl
,
378 const char *file
, int line
)
381 for(i
= 0; i
< LastEvent
; i
++)
384 (!impl
->count
[i
], "Got event %d, count %d\n", i
, impl
->count
[i
]);
388 #define ok_no_events(impl) \
389 ok_no_events_(impl, __FILE__, __LINE__)
391 #define ok_event_count_broken(impl, event, c, b) \
392 do { ok(impl->count[event] == c || broken(impl->count[event] == b), \
393 "Got event %d, count %d\n", event, impl->count[event]); \
394 impl->count[event] = 0; \
397 #define ok_event_count(impl, event, c) \
398 ok_event_count_broken(impl, event, c, -1)
400 #define ok_event_broken(impl, event) \
401 do { ok(impl->count[event] || broken(!impl->count[event]), \
403 impl->count[event] = 0; \
406 #define ok_event(impl, event) \
407 do { ok(impl->count[event], "No event %d.\n", event); \
408 impl->count[event] = 0; \
411 /* Process some messages */
412 static void process_msgs(void)
419 while(PeekMessageW( &msg
, NULL
, 0, 0, PM_REMOVE
))
421 TranslateMessage(&msg
);
422 DispatchMessageW(&msg
);
427 /* There seem to be a timer that sometimes fires after about
428 500ms, we need to wait for it. Failing to wait can result in
429 seemingly sporadic selection change events. (Timer ID is 87,
430 sending WM_TIMER manually does not seem to help us.) */
433 while(PeekMessageW( &msg
, NULL
, 0, 0, PM_REMOVE
))
435 TranslateMessage(&msg
);
436 DispatchMessageW(&msg
);
440 /** Some functions from shell32/tests/shlfolder.c */
441 /* creates a file with the specified name for tests */
442 static void CreateTestFile(const CHAR
*name
)
447 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
448 if (file
!= INVALID_HANDLE_VALUE
)
450 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
451 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
455 /* initializes the tests */
456 static void CreateFilesFolders(void)
458 CreateDirectoryA(".\\testdir", NULL
);
459 CreateTestFile (".\\testdir\\test1.txt ");
460 CreateTestFile (".\\testdir\\test2.txt ");
461 CreateTestFile (".\\testdir\\test3.txt ");
462 CreateDirectoryA(".\\testdir\\testdir2 ", NULL
);
463 CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL
);
466 /* cleans after tests */
467 static void Cleanup(void)
469 DeleteFileA(".\\testdir\\test1.txt");
470 DeleteFileA(".\\testdir\\test2.txt");
471 DeleteFileA(".\\testdir\\test3.txt");
472 RemoveDirectoryA(".\\testdir\\testdir2\\subdir");
473 RemoveDirectoryA(".\\testdir\\testdir2");
474 RemoveDirectoryA(".\\testdir");
477 /* Based on PathAddBackslashW from dlls/shlwapi/path.c */
478 static LPWSTR
myPathAddBackslashW( LPWSTR lpszPath
)
482 if (!lpszPath
|| (iLen
= lstrlenW(lpszPath
)) >= MAX_PATH
)
488 if (lpszPath
[-1] != '\\')
497 static HWND
get_treeview_hwnd(INameSpaceTreeControl
*pnstc
)
501 HWND treeview
= NULL
;
503 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
504 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
508 hr
= IOleWindow_GetWindow(pow
, &host
);
509 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
511 treeview
= FindWindowExW(host
, NULL
, WC_TREEVIEWW
, NULL
);
512 IOleWindow_Release(pow
);
518 static LRESULT WINAPI
treeview_subclass_proc(HWND hwnd_tv
, UINT message
, WPARAM wParam
, LPARAM lParam
)
520 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrW(hwnd_tv
, GWLP_USERDATA
);
521 static LONG defwndproc_counter
= 0;
525 msg
.message
= message
;
526 msg
.flags
= sent
|wparam
|lparam
;
527 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
531 add_message(sequences
, TREEVIEW_SEQ_INDEX
, &msg
);
533 if(message
== TVM_SETITEMW
)
535 memcpy(&last_tvi
, (void*)lParam
, sizeof(TVITEMEXW
));
539 defwndproc_counter
++;
540 ret
= CallWindowProcW(oldproc
, hwnd_tv
, message
, wParam
, lParam
);
541 defwndproc_counter
--;
545 static BOOL
subclass_treeview(INameSpaceTreeControl
*pnstc
)
548 WNDPROC oldproc
= NULL
;
550 hwnd_tv
= get_treeview_hwnd(pnstc
);
553 oldproc
= (WNDPROC
)SetWindowLongPtrW(hwnd_tv
, GWLP_WNDPROC
,
554 (LONG_PTR
)treeview_subclass_proc
);
555 SetWindowLongPtrW(hwnd_tv
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
556 ok(oldproc
!= NULL
, "Failed to subclass.\n");
562 static UINT
get_msg_count(struct msg_sequence
**seq
, int sequence_index
, UINT message
)
564 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
567 for(i
= 0; i
< msg_seq
->count
; i
++)
568 if(msg_seq
->sequence
[i
].message
== message
)
574 /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
575 static BOOL
test_initialization(void)
577 INameSpaceTreeControl
*pnstc
;
585 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
586 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
587 ok(hr
== S_OK
|| hr
== REGDB_E_CLASSNOTREG
, "Got 0x%08x\n", hr
);
593 hr
= INameSpaceTreeControl_Initialize(pnstc
, NULL
, NULL
, 0);
594 ok(hr
== HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD
), "Got (0x%08x)\n", hr
);
596 hr
= INameSpaceTreeControl_Initialize(pnstc
, (HWND
)0xDEADBEEF, NULL
, 0);
597 ok(hr
== HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE
), "Got (0x%08x)\n", hr
);
599 ZeroMemory(&rc
, sizeof(RECT
));
600 hr
= INameSpaceTreeControl_Initialize(pnstc
, NULL
, &rc
, 0);
601 ok(hr
== HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD
), "Got (0x%08x)\n", hr
);
603 hr
= INameSpaceTreeControl_Initialize(pnstc
, (HWND
)0xDEADBEEF, &rc
, 0);
604 ok(hr
== HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE
), "Got (0x%08x)\n", hr
);
606 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
607 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
610 hr
= IOleWindow_GetWindow(pow
, &hwnd_host1
);
611 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
612 ok(hwnd_host1
== NULL
, "hwnd is not null.\n");
614 hr
= IOleWindow_ContextSensitiveHelp(pow
, TRUE
);
615 ok(hr
== E_NOTIMPL
, "Got (0x%08x)\n", hr
);
616 hr
= IOleWindow_ContextSensitiveHelp(pow
, FALSE
);
617 ok(hr
== E_NOTIMPL
, "Got (0x%08x)\n", hr
);
618 IOleWindow_Release(pow
);
621 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, NULL
, 0);
622 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
623 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
624 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
627 static const CHAR namespacetree
[] = "NamespaceTreeControl";
629 LONG style
, expected_style
;
631 hr
= IOleWindow_GetWindow(pow
, &hwnd_host1
);
632 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
633 ok(hwnd_host1
!= NULL
, "hwnd_host1 is null.\n");
635 GetClassNameA(hwnd_host1
, buf
, 1024);
636 ok(!lstrcmpA(namespacetree
, buf
), "Class name was %s\n", buf
);
638 expected_style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
639 style
= GetWindowLongPtrW(hwnd_host1
, GWL_STYLE
);
640 ok(style
== expected_style
, "Got style %08x\n", style
);
643 style
= GetWindowLongPtrW(hwnd_host1
, GWL_EXSTYLE
);
644 ok(style
== expected_style
, "Got style %08x\n", style
);
647 style
= SendMessageW(hwnd_host1
, TVM_GETEXTENDEDSTYLE
, 0, 0);
648 ok(style
== expected_style
, "Got 0x%08x\n", style
);
650 hwnd_tv
= FindWindowExW(hwnd_host1
, NULL
, WC_TREEVIEWW
, NULL
);
651 ok(hwnd_tv
!= NULL
, "Failed to get treeview hwnd.\n");
654 expected_style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
|
655 WS_CLIPCHILDREN
| WS_TABSTOP
| TVS_NOHSCROLL
|
656 TVS_NONEVENHEIGHT
| TVS_INFOTIP
| TVS_TRACKSELECT
| TVS_EDITLABELS
;
657 style
= GetWindowLongPtrW(hwnd_tv
, GWL_STYLE
);
658 ok(style
== expected_style
, "Got style %08x\n", style
);
661 style
= GetWindowLongPtrW(hwnd_tv
, GWL_EXSTYLE
);
662 ok(style
== expected_style
, "Got style %08x\n", style
);
664 expected_style
= TVS_EX_NOSINGLECOLLAPSE
| TVS_EX_DOUBLEBUFFER
|
665 TVS_EX_RICHTOOLTIP
| TVS_EX_DRAWIMAGEASYNC
;
666 style
= SendMessageW(hwnd_tv
, TVM_GETEXTENDEDSTYLE
, 0, 0);
667 todo_wine
ok(style
== expected_style
, "Got 0x%08x\n", style
);
670 IOleWindow_Release(pow
);
675 /* The control can be initialized again without crashing, but
676 * the reference counting will break. */
677 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, &rc
, 0);
678 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
679 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
683 hr
= IOleWindow_GetWindow(pow
, &hwnd_host2
);
684 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
685 ok(hwnd_host1
!= hwnd_host2
, "Same hwnd.\n");
686 IOleWindow_Release(pow
);
690 /* Some "random" interfaces */
692 /* Next three are supported on Vista/2k8, but not on newer versions */
693 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceObject
, (void**)&punk
);
694 ok(hr
== E_NOINTERFACE
|| broken(hr
== S_OK
) /* vista, w2k8 */, "Got (0x%08x)\n", hr
);
695 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
696 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceActiveObject
, (void**)&punk
);
697 ok(hr
== E_NOINTERFACE
|| broken(hr
== S_OK
) /* vista, w2k8 */, "Got (0x%08x)\n", hr
);
698 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
699 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceObjectWindowless
, (void**)&punk
);
700 ok(hr
== E_NOINTERFACE
|| broken(hr
== S_OK
) /* vista, w2k8 */, "Got (0x%08x)\n", hr
);
701 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
703 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceUIWindow
, (void**)&punk
);
704 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
705 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceFrame
, (void**)&punk
);
706 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
707 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSite
, (void**)&punk
);
708 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
709 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSiteEx
, (void**)&punk
);
710 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
711 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSiteWindowless
, (void**)&punk
);
712 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
714 /* On windows, the reference count won't go to zero until the
715 * window is destroyed. */
716 INameSpaceTreeControl_AddRef(pnstc
);
717 lres
= INameSpaceTreeControl_Release(pnstc
);
718 ok(lres
> 1, "Reference count was (%d).\n", lres
);
720 DestroyWindow(hwnd_host1
);
721 lres
= INameSpaceTreeControl_Release(pnstc
);
722 ok(!lres
, "lres was %d\n", lres
);
727 static void verify_root_order_(INameSpaceTreeControl
*pnstc
, IShellItem
**roots
,
728 const char *file
, int line
)
731 IShellItemArray
*psia
;
733 hr
= INameSpaceTreeControl_GetRootItems(pnstc
, &psia
);
734 ok_(file
,line
) (hr
== S_OK
, "GetRootItems: got (0x%08x)\n", hr
);
737 DWORD i
, expected
, count
= -1;
738 hr
= IShellItemArray_GetCount(psia
, &count
);
739 ok_(file
,line
) (hr
== S_OK
, "Got (0x%08x)\n", hr
);
741 for(expected
= 0; roots
[expected
] != NULL
; expected
++);
742 ok_(file
,line
) (count
== expected
, "Got %d roots, expected %d\n", count
, expected
);
744 for(i
= 0; i
< count
&& roots
[i
] != NULL
; i
++)
747 hr
= IShellItemArray_GetItemAt(psia
, i
, &psi
);
748 ok_(file
,line
) (hr
== S_OK
, "GetItemAt %i: got 0x%08x\n", i
, hr
);
752 hr
= IShellItem_Compare(psi
, roots
[i
], SICHINT_DISPLAY
, &cmp
);
753 ok_(file
,line
) (hr
== S_OK
, "Compare %i: got 0x%08x\n", i
, hr
);
754 IShellItem_Release(psi
);
757 IShellItemArray_Release(psia
);
760 #define verify_root_order(pnstc, psi_a) \
761 verify_root_order_(pnstc, psi_a, __FILE__, __LINE__)
763 static void test_basics(void)
765 INameSpaceTreeControl
*pnstc
;
766 INameSpaceTreeControl2
*pnstc2
;
767 IShellItemArray
*psia
;
768 IShellFolder
*psfdesktop
;
770 IShellItem
*psidesktop
, *psidesktop2
;
771 IShellItem
*psitestdir
, *psitestdir2
, *psitest1
;
773 LPITEMIDLIST pidl_desktop
;
774 NSTCITEMSTATE istate
;
779 IShellItem
*roots
[10];
782 WCHAR curdirW
[MAX_PATH
];
785 /* These should exist on platforms supporting the NSTC */
786 ok(pSHCreateShellItem
!= NULL
, "No SHCreateShellItem.\n");
787 ok(pSHCreateItemFromParsingName
!= NULL
, "No SHCreateItemFromParsingName\n");
788 ok(pSHGetIDListFromObject
!= NULL
, "No SHCreateShellItem.\n");
789 ok(pSHCreateItemFromParsingName
!= NULL
, "No SHCreateItemFromParsingName\n");
791 /* Create ShellItems for testing. */
792 SHGetDesktopFolder(&psfdesktop
);
793 hr
= pSHGetIDListFromObject((IUnknown
*)psfdesktop
, &pidl_desktop
);
794 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
797 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop
);
798 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
801 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop2
);
802 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
803 if(FAILED(hr
)) IShellItem_Release(psidesktop
);
805 ILFree(pidl_desktop
);
807 IShellFolder_Release(psfdesktop
);
811 win_skip("Test setup failed.\n");
815 ok(psidesktop
!= psidesktop2
, "psidesktop == psidesktop2\n");
817 CreateFilesFolders();
818 GetCurrentDirectoryW(MAX_PATH
, curdirW
);
819 ok(lstrlenW(curdirW
), "Got 0 length string.\n");
821 lstrcpyW(buf
, curdirW
);
822 myPathAddBackslashW(buf
);
823 lstrcatW(buf
, L
"testdir");
824 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitestdir
);
825 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
826 if(FAILED(hr
)) goto cleanup
;
827 lstrcpyW(buf
, curdirW
);
828 myPathAddBackslashW(buf
);
829 lstrcatW(buf
, L
"testdir\\testdir2");
830 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitestdir2
);
831 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
832 if(FAILED(hr
)) goto cleanup
;
833 lstrcpyW(buf
, curdirW
);
834 myPathAddBackslashW(buf
);
835 lstrcatW(buf
, L
"testdir\\test1.txt");
836 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitest1
);
837 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
838 if(FAILED(hr
)) goto cleanup
;
840 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
841 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
842 ok(hr
== S_OK
, "Failed to initialize control (0x%08x)\n", hr
);
844 /* Some tests on an uninitialized control */
845 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
846 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
847 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
848 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
849 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, NULL
);
850 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
851 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_NONFOLDERS
, 0, NULL
);
852 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
855 /* Initialize the control */
856 SetRect(&rc
, 0, 0, 200, 200);
857 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, &rc
, 0);
858 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
861 /* Set/GetControlStyle(2) */
862 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_INameSpaceTreeControl2
, (void**)&pnstc2
);
863 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
), "Got 0x%08x\n", hr
);
869 static const NSTCSTYLE2 styles2
[] =
870 { NSTCS2_INTERRUPTNOTIFICATIONS
,NSTCS2_SHOWNULLSPACEMENU
,
871 NSTCS2_DISPLAYPADDING
,NSTCS2_DISPLAYPINNEDONLY
,
872 NTSCS2_NOSINGLETONAUTOEXPAND
,NTSCS2_NEVERINSERTNONENUMERATED
, 0};
875 /* We can use this to differentiate between two versions of
876 * this interface. Windows 7 returns hr == S_OK. */
877 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0, 0);
878 ok(hr
== S_OK
|| broken(hr
== E_FAIL
), "Got 0x%08x\n", hr
);
881 static const NSTCSTYLE styles
[] =
882 { NSTCS_HASEXPANDOS
,NSTCS_HASLINES
,NSTCS_SINGLECLICKEXPAND
,
883 NSTCS_FULLROWSELECT
,NSTCS_HORIZONTALSCROLL
,
884 NSTCS_ROOTHASEXPANDO
,NSTCS_SHOWSELECTIONALWAYS
,NSTCS_NOINFOTIP
,
885 NSTCS_EVENHEIGHT
,NSTCS_NOREPLACEOPEN
,NSTCS_DISABLEDRAGDROP
,
886 NSTCS_NOORDERSTREAM
,NSTCS_BORDER
,NSTCS_NOEDITLABELS
,
887 NSTCS_TABSTOP
,NSTCS_FAVORITESMODE
,NSTCS_EMPTYTEXT
,NSTCS_CHECKBOXES
,
888 NSTCS_ALLOWJUNCTIONS
,NSTCS_SHOWTABSBUTTON
,NSTCS_SHOWDELETEBUTTON
,
889 NSTCS_SHOWREFRESHBUTTON
, 0};
891 /* Set/GetControlStyle */
892 style
= style2
= 0xdeadbeef;
893 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
894 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
895 ok(style
== 0, "Got style %x\n", style
);
897 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0, 0xFFFFFFF);
898 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
901 for(i
= 0; styles
[i
] != 0; i
++)
903 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles
[i
], styles
[i
]);
904 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles
[i
]);
905 if(SUCCEEDED(hr
)) tmp
|= styles
[i
];
908 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
909 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
910 ok(style
== tmp
, "Got style %x (expected %x)\n", style
, tmp
);
914 for(i
= 0; styles
[i
] != 0; i
++)
916 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, styles
[i
], &tmp2
);
917 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
918 ok(tmp2
== (style
& styles
[i
]), "Got %x\n", tmp2
);
922 for(i
= 0; styles
[i
] != 0; i
++)
924 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles
[i
], 0);
925 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles
[i
]);
927 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
928 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
929 ok(style
== 0, "Got style %x\n", style
);
931 /* Set/GetControlStyle2 */
932 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
933 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
934 ok(style2
== 0, "Got style %x\n", style2
);
936 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0, 0);
937 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
938 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0, 0xFFFFFFFF);
939 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
941 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0);
942 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
943 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0xFFFFFFFF);
944 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
946 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0);
947 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
948 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
949 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
950 ok(style2
== 0x00000000, "Got style %x\n", style2
);
952 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
953 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
954 ok(style2
== 0, "Got style %x\n", style2
);
957 for(i
= 0; styles2
[i
] != 0; i
++)
959 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], styles2
[i
]);
960 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
961 if(SUCCEEDED(hr
)) tmp
|= styles2
[i
];
964 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
965 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
966 ok(style2
== tmp
, "Got style %x (expected %x)\n", style2
, tmp
);
970 for(i
= 0; styles2
[i
] != 0; i
++)
972 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, styles2
[i
], &tmp2
);
973 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
974 ok(tmp2
== (style2
& styles2
[i
]), "Got %x\n", tmp2
);
978 for(i
= 0; styles2
[i
] != 0; i
++)
980 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], 0);
981 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
983 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
984 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
985 ok(style2
== 0, "Got style %x (expected 0)\n", style2
);
989 /* 64-bit Windows Vista (others?) seems to have a somewhat
990 * different idea of how the methods of this interface
993 static const NSTCSTYLE styles
[] =
994 { NSTCS_HASEXPANDOS
,NSTCS_HASLINES
,NSTCS_SINGLECLICKEXPAND
,
995 NSTCS_FULLROWSELECT
,NSTCS_SPRINGEXPAND
,NSTCS_HORIZONTALSCROLL
,
996 NSTCS_RICHTOOLTIP
, NSTCS_AUTOHSCROLL
,
997 NSTCS_FADEINOUTEXPANDOS
,
998 NSTCS_PARTIALCHECKBOXES
,NSTCS_EXCLUSIONCHECKBOXES
,
999 NSTCS_DIMMEDCHECKBOXES
, NSTCS_NOINDENTCHECKS
,
1000 NSTCS_ROOTHASEXPANDO
,NSTCS_SHOWSELECTIONALWAYS
,NSTCS_NOINFOTIP
,
1001 NSTCS_EVENHEIGHT
,NSTCS_NOREPLACEOPEN
,NSTCS_DISABLEDRAGDROP
,
1002 NSTCS_NOORDERSTREAM
,NSTCS_BORDER
,NSTCS_NOEDITLABELS
,
1003 NSTCS_TABSTOP
,NSTCS_FAVORITESMODE
,NSTCS_EMPTYTEXT
,NSTCS_CHECKBOXES
,
1004 NSTCS_ALLOWJUNCTIONS
,NSTCS_SHOWTABSBUTTON
,NSTCS_SHOWDELETEBUTTON
,
1005 NSTCS_SHOWREFRESHBUTTON
, 0};
1006 trace("Detected broken INameSpaceTreeControl2.\n");
1009 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
1010 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1011 ok(style
== 0xdeadbeef, "Got style %x\n", style
);
1013 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
1014 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1015 ok(style2
== 0, "Got style %x\n", style2
);
1018 for(i
= 0; styles
[i
] != 0; i
++)
1020 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles
[i
], styles
[i
]);
1021 ok(hr
== E_FAIL
|| ((styles
[i
] & NSTCS_SPRINGEXPAND
) && hr
== S_OK
),
1022 "Got 0x%08x (%x)\n", hr
, styles
[i
]);
1023 if(SUCCEEDED(hr
)) tmp
|= styles
[i
];
1027 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, tmp
, &style
);
1028 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1029 ok(style
== 0xdeadbeef, "Got style %x\n", style
);
1032 for(i
= 0; styles2
[i
] != 0; i
++)
1034 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], styles2
[i
]);
1035 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
1036 if(SUCCEEDED(hr
)) tmp
|= styles2
[i
];
1039 style2
= 0xdeadbeef;
1040 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
1041 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1042 ok(style2
== tmp
, "Got style %x\n", style2
);
1046 INameSpaceTreeControl2_Release(pnstc2
);
1050 skip("INameSpaceTreeControl2 missing.\n");
1053 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, NULL
);
1054 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
1056 /* Append / Insert root */
1059 /* Crashes under Windows 7 */
1060 INameSpaceTreeControl_AppendRoot(pnstc
, NULL
, SHCONTF_FOLDERS
, 0, NULL
);
1061 INameSpaceTreeControl_InsertRoot(pnstc
, 0, NULL
, SHCONTF_FOLDERS
, 0, NULL
);
1064 /* Note the usage of psidesktop and psidesktop2 */
1065 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1066 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1067 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1068 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1069 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop2
, SHCONTF_FOLDERS
, 0, NULL
);
1070 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1073 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1074 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1075 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1076 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1077 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1078 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1080 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1081 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1082 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1083 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
1085 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1086 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1087 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1088 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1090 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 0, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1091 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1092 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1093 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1094 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1095 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1096 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 50, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1097 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1098 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1099 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1101 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1102 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1107 /* Crashes on native. */
1108 INameSpaceTreeControl_GetRootItems(pnstc
, NULL
);
1111 hr
= INameSpaceTreeControl_GetRootItems(pnstc
, &psia
);
1112 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
1114 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, 0, 0, NULL
);
1115 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1116 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop2
, 0, 0, NULL
);
1117 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1118 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
, 0, 0, NULL
);
1119 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1120 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, 0, 0, NULL
);
1121 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1123 roots
[0] = psidesktop
;
1124 roots
[1] = psidesktop2
;
1125 roots
[2] = psitestdir
;
1126 roots
[3] = psitestdir2
;
1128 verify_root_order(pnstc
, roots
);
1130 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 0, psitestdir2
, 0, 0, NULL
);
1131 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1133 roots
[0] = psitestdir2
;
1134 roots
[1] = psidesktop
;
1135 roots
[2] = psidesktop2
;
1136 roots
[3] = psitestdir
;
1137 roots
[4] = psitestdir2
;
1139 verify_root_order(pnstc
, roots
);
1141 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 5, psidesktop
, 0, 0, NULL
);
1142 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1144 roots
[0] = psitestdir2
;
1145 roots
[1] = psidesktop
;
1146 roots
[2] = psidesktop2
;
1147 roots
[3] = psitestdir
;
1148 roots
[4] = psitestdir2
;
1149 roots
[5] = psidesktop
;
1151 verify_root_order(pnstc
, roots
);
1153 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 3, psitestdir2
, 0, 0, NULL
);
1154 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1156 roots
[0] = psitestdir2
;
1157 roots
[1] = psidesktop
;
1158 roots
[2] = psidesktop2
;
1159 roots
[3] = psitestdir2
;
1160 roots
[4] = psitestdir
;
1161 roots
[5] = psitestdir2
;
1162 roots
[6] = psidesktop
;
1164 verify_root_order(pnstc
, roots
);
1166 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, 0, 0, NULL
);
1167 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1169 roots
[0] = psitestdir2
;
1170 roots
[1] = psidesktop
;
1171 roots
[2] = psidesktop2
;
1172 roots
[3] = psitestdir2
;
1173 roots
[4] = psitestdir
;
1174 roots
[5] = psitestdir2
;
1175 roots
[6] = psidesktop
;
1176 roots
[7] = psitestdir2
;
1178 verify_root_order(pnstc
, roots
);
1180 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, 0, 0, NULL
);
1181 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1183 roots
[0] = psidesktop
;
1184 roots
[1] = psitestdir2
;
1185 roots
[2] = psidesktop
;
1186 roots
[3] = psidesktop2
;
1187 roots
[4] = psitestdir2
;
1188 roots
[5] = psitestdir
;
1189 roots
[6] = psitestdir2
;
1190 roots
[7] = psidesktop
;
1191 roots
[8] = psitestdir2
;
1193 verify_root_order(pnstc
, roots
);
1196 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
1197 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1199 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1200 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1202 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
1203 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1205 /* SetItemState message checks */
1206 res
= subclass_treeview(pnstc
);
1207 ok(res
, "Failed to subclass treeview.\n");
1210 UINT isMask
, isFlags
;
1212 hr
= INameSpaceTreeControl_AppendRoot(
1213 pnstc
, psidesktop
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, 0, NULL
);
1214 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1215 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1218 * The first expansion results in an "unrelated" TVM_SETITEMW being sent
1219 * (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) )
1222 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
1223 NSTCIS_EXPANDED
, NSTCIS_EXPANDED
);
1224 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1227 ok(tvi_count
== 1, "Got %d\n", tvi_count
);
1228 ok(last_tvi
.mask
== 0x50, "Got mask %x, expected 0x50\n", last_tvi
.mask
);
1232 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
1233 NSTCIS_EXPANDED
, NSTCIS_EXPANDED
);
1234 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1235 ok(tvi_count
== 0, "Got %d\n", tvi_count
);
1237 /* Test all the combinations of NSTCIS_SELECTED to NSTCIS_SELECTEDNOEXPAND */
1238 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1239 for(isMask
= 0; isMask
<= 0x1f; isMask
++)
1241 for(isFlags
= 0; isFlags
<= 0x1f; isFlags
++)
1243 UINT select_sent
, select_sent_vista
, ensurev_sent
, expand_sent
;
1247 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1250 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, isMask
, isFlags
);
1251 ok(hr
== S_OK
, "(%x|%x)Got 0x%08x\n", isMask
, isFlags
, hr
);
1253 /*****************************/
1254 /* Calculate expected values */
1255 /*****************************/
1257 /* Number of TVM_SELECTITEM/TVM_ENSUREVISIBLE and TVM_EXPAND sent */
1258 select_sent
= ((isMask
&isFlags
) & NSTCIS_SELECTED
)?1:0;
1259 select_sent_vista
= ensurev_sent
= select_sent
;
1261 select_sent
+= ((isMask
&isFlags
) & NSTCIS_SELECTEDNOEXPAND
)?1:0;
1262 select_sent_vista
+= ((isMask
&isFlags
) & NSTCIS_EXPANDED
)?1:0;
1263 expand_sent
= ((isMask
|isFlags
) & NSTCIS_EXPANDED
)?1:0;
1265 /* Possible TWM_SETITEMW message and its contents */
1266 if(isMask
& NSTCIS_DISABLED
)
1267 tviexp
.mask
= TVIF_STATE
| TVIF_STATEEX
;
1268 else if( ((isMask
^isFlags
) & (NSTCIS_SELECTED
|NSTCIS_EXPANDED
|NSTCIS_SELECTEDNOEXPAND
)) ||
1269 ((isMask
|isFlags
) & NSTCIS_BOLD
) || (isFlags
& NSTCIS_DISABLED
) )
1270 tviexp
.mask
= TVIF_STATE
;
1276 tviexp
.stateMask
= tviexp
.state
= 0;
1277 tviexp
.stateMask
|= ((isMask
^isFlags
)&NSTCIS_SELECTED
) ? TVIS_SELECTED
: 0;
1278 tviexp
.stateMask
|= (isMask
|isFlags
)&NSTCIS_BOLD
? TVIS_BOLD
:0;
1279 tviexp
.state
|= (isMask
&isFlags
)&NSTCIS_BOLD
? TVIS_BOLD
:0;
1281 if((isMask
&NSTCIS_EXPANDED
)^(isFlags
&NSTCIS_EXPANDED
))
1283 tviexp
.stateMask
= 0;
1286 tviexp
.uStateEx
= (isFlags
&isMask
)&NSTCIS_DISABLED
?TVIS_EX_DISABLED
:0;
1290 /* Make sure that no tests accidentally succeeded
1291 * (and avoid a gcc warning) */
1292 tviexp
.stateMask
= tviexp
.state
= tviexp
.uStateEx
= -1;
1295 /*****************************/
1296 /* Check the values. */
1297 /*****************************/
1299 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_SELECTITEM
);
1300 ok(msg_count
== select_sent
|| broken(msg_count
== select_sent_vista
),
1301 "(%x|%x) Got msg_count %d, expected %d (%d)\n",
1302 isMask
, isFlags
, msg_count
, select_sent
, select_sent_vista
);
1303 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_ENSUREVISIBLE
);
1304 ok(msg_count
== ensurev_sent
|| broken(msg_count
== 0 /* Vista */),
1305 "(%x|%x) Got msg_count %d, expected %d\n",
1306 isMask
, isFlags
, msg_count
, ensurev_sent
);
1307 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_EXPAND
);
1308 ok(msg_count
== expand_sent
, "(%x|%x) Got msg_count %d, expected %d\n",
1309 isMask
, isFlags
, msg_count
, expand_sent
);
1311 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_SETITEMW
);
1314 /* Four special cases for vista */
1315 BOOL vista_check
= ( (isMask
== 0x10 && isFlags
== 0x10) ||
1316 (isMask
== 0x11 && isFlags
== 0x11) ||
1317 (isMask
== 0x12 && isFlags
== 0x12) ||
1318 (isMask
== 0x13 && isFlags
== 0x13) );
1320 ok(msg_count
== 0 || broken(msg_count
== 1 && vista_check
),
1321 "(%x|%x) Got msg_count %d (tviexp.mask %x)\n",
1322 isMask
, isFlags
, msg_count
, tviexp
.mask
);
1326 ok(msg_count
== 1, "(%x|%x) Got msg_count %d, expected 1\n",
1327 isMask
, isFlags
, msg_count
);
1328 ok(last_tvi
.mask
== tviexp
.mask
,
1329 "(%x|%x) Got mask %x, expected %x\n",
1330 isMask
, isFlags
, last_tvi
.mask
, tviexp
.mask
);
1331 ok(last_tvi
.stateMask
== tviexp
.stateMask
,
1332 "(%x|%x) Got stateMask %x, expected %x\n",
1333 isMask
, isFlags
, last_tvi
.stateMask
, tviexp
.stateMask
);
1334 ok(last_tvi
.state
== tviexp
.state
,
1335 "(%x|%x) Got state %x, expected %x\n",
1336 isMask
, isFlags
, last_tvi
.state
, tviexp
.state
);
1337 ok(last_tvi
.uStateEx
== tviexp
.uStateEx
,
1338 "(%x|%x) Got uStateEx %x, expected %x\n",
1339 isMask
, isFlags
, last_tvi
.uStateEx
, tviexp
.uStateEx
);
1343 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1344 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1347 /* GetSelectedItems */
1350 /* Crashes under Windows 7 */
1351 INameSpaceTreeControl_GetSelectedItems(pnstc
, NULL
);
1354 psia
= (void*)0xdeadbeef;
1355 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1356 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1357 ok(!psia
|| broken(psia
== (void*)0xdeadbeef /* before Win8 */), "Got %p\n", psia
);
1359 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, SHCONTF_FOLDERS
, 0, NULL
);
1360 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1363 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
, SHCONTF_FOLDERS
, 0, NULL
);
1364 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1367 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitestdir
,
1368 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1369 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1371 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1372 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1376 hr
= IShellItemArray_GetCount(psia
, &count
);
1377 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1378 ok(count
== 1, "Got %d selected items.\n", count
);
1381 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1382 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1386 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1387 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1388 IShellItem_Release(psi
);
1391 IShellItemArray_Release(psia
);
1394 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitestdir2
,
1395 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1396 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1399 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1400 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1404 hr
= IShellItemArray_GetCount(psia
, &count
);
1405 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1406 ok(count
== 1, "Got %d selected items.\n", count
);
1409 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1410 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1414 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1415 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1416 IShellItem_Release(psi
);
1419 IShellItemArray_Release(psia
);
1422 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitest1
,
1423 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1424 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1425 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1426 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1430 hr
= IShellItemArray_GetCount(psia
, &count
);
1431 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1432 ok(count
== 1, "Got %d selected items.\n", count
);
1435 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1436 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1440 hr
= IShellItem_Compare(psi
, psitest1
, SICHINT_DISPLAY
, &cmp
);
1441 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1442 IShellItem_Release(psi
);
1445 IShellItemArray_Release(psia
);
1448 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1449 ok(hr
== S_OK
|| broken(hr
== E_FAIL
), "Got 0x%08x\n", hr
);
1452 /* For some reason, Vista fails to properly remove both the
1453 * roots here on the first try. */
1454 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1455 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1458 /* Adding without NSTCRS_EXPANDED does not set the selection */
1459 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1460 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1462 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1465 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir
, 0xFF, &istate
);
1466 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1467 ok(!(istate
& NSTCIS_SELECTED
), "Got 0x%08x\n", istate
);
1468 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1469 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1470 if(SUCCEEDED(hr
)) IShellItemArray_Release(psia
);
1472 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1473 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1475 /* Adding with NSTCRS_EXPANDED sets the selection */
1476 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1477 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1478 NSTCRS_EXPANDED
, NULL
);
1479 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1482 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir
, 0xFF, &istate
);
1483 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1484 todo_wine
ok(istate
& NSTCIS_SELECTED
, "Got 0x%08x\n", istate
);
1485 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1486 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1491 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1495 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1496 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1498 IShellItem_Release(psi
);
1501 IShellItemArray_Release(psia
);
1504 /* Adding a second root with NSTCRS_EXPANDED does not change the selection */
1505 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
,
1506 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1507 NSTCRS_EXPANDED
, NULL
);
1508 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1511 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir2
, 0xFF, &istate
);
1512 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1513 ok(!(istate
& NSTCIS_SELECTED
), "Got 0x%08x\n", istate
);
1514 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1515 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1520 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1524 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1525 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1527 IShellItem_Release(psi
);
1530 IShellItemArray_Release(psia
);
1533 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1534 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1540 /* Crashes under win 7 */
1541 INameSpaceTreeControl_GetItemRect(pnstc
, NULL
, NULL
);
1542 INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, NULL
);
1543 INameSpaceTreeControl_GetItemRect(pnstc
, NULL
, &rc
);
1546 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, &rc
);
1547 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
1549 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1550 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1551 NSTCRS_EXPANDED
, NULL
);
1552 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1555 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, &rc
);
1556 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1557 ok(rc
.top
!= rc
.bottom
, "Got 0 height.\n");
1558 ok(rc
.left
!= rc
.right
, "Got 0 width.\n");
1561 hwnd_tv
= get_treeview_hwnd(pnstc
);
1564 HTREEITEM hroot
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_ROOT
, 0);
1565 ok(hroot
!= NULL
, "Failed to get root.\n");
1571 *(HTREEITEM
*)&tv_rc
= hroot
;
1572 bret
= SendMessageW(hwnd_tv
, TVM_GETITEMRECT
, FALSE
, (LPARAM
)&tv_rc
);
1573 ok(bret
, "TVM_GETITEMRECT failed.\n");
1575 /* The NamespaceTreeControl returns screen coordinates. */
1576 MapWindowPoints(NULL
, hwnd
, (POINT
*)&rc
, 2);
1577 ok(EqualRect(&rc
, &tv_rc
), "Differed, got %s and %s\n", wine_dbgstr_rect(&rc
),
1578 wine_dbgstr_rect(&tv_rc
));
1580 /* Save the height and compare to that of other items.
1581 Observed values: 18, 19, 21 */
1582 height
= rc
.bottom
- rc
.top
;
1583 trace("height: %d\n", height
);
1587 win_skip("Skipping some GetItemRect tests.\n");
1589 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1590 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1593 hr
= INameSpaceTreeControl_HitTest(pnstc
, NULL
, NULL
);
1594 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1595 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, NULL
);
1596 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1597 hr
= INameSpaceTreeControl_HitTest(pnstc
, NULL
, &psi
);
1598 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1600 psi
= (void*)0xdeadbeef;
1602 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1603 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
1604 ok(psi
== NULL
, "Got psi %p\n", psi
);
1606 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1607 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1608 NSTCRS_EXPANDED
, NULL
);
1609 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1612 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1613 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1617 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1618 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1619 ok(!cmp
, "Got cmp %d\n", cmp
);
1620 IShellItem_Release(psi
);
1624 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1625 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1629 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1630 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1631 ok(!cmp
, "Got cmp %d\n", cmp
);
1632 IShellItem_Release(psi
);
1636 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1637 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1643 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1644 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
1645 ok(cmp
, "no cmp value.\n");
1646 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1647 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1648 ok(!cmp
, "Got cmp %d\n", cmp
);
1650 IShellItem_Release(psi
);
1653 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir2
, &rc
);
1654 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1657 MapWindowPoints(NULL
, hwnd
, (POINT
*)&rc
, 2);
1658 pt
.x
= rc
.left
; pt
.y
= rc
.top
;
1660 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1661 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1665 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1666 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1667 ok(!cmp
, "Got cmp %d\n", cmp
);
1668 IShellItem_Release(psi
);
1672 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1673 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1675 /* GetItemCustomState / SetItemCustomState */
1678 /* Crashes under Windows 7 */
1679 INameSpaceTreeControl_GetItemCustomState(pnstc
, NULL
, NULL
);
1680 INameSpaceTreeControl_GetItemCustomState(pnstc
, NULL
, &cbstate
);
1681 INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, NULL
);
1682 INameSpaceTreeControl_SetItemCustomState(pnstc
, NULL
, 0);
1685 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1686 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1689 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1694 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1695 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1696 ok(cbstate
== BST_UNCHECKED
|| broken(cbstate
== BST_CHECKED
/* Vista x64 */),
1697 "Got %d\n", cbstate
);
1699 hr
= INameSpaceTreeControl_SetItemCustomState(pnstc
, psitestdir
, BST_CHECKED
);
1700 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1703 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1704 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1705 ok(cbstate
== BST_CHECKED
, "Got %d\n", cbstate
);
1707 hr
= INameSpaceTreeControl_SetItemCustomState(pnstc
, psitestdir
, 0xFFF);
1708 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1711 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1712 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1713 ok(cbstate
== 0xF, "Got %d\n", cbstate
);
1719 hr
= INameSpaceTreeControl_SetTheme(pnstc
, NULL
);
1720 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1721 hr
= INameSpaceTreeControl_SetTheme(pnstc
, L
"Explorer");
1722 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1723 hr
= INameSpaceTreeControl_SetTheme(pnstc
, L
"__hello");
1724 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1727 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1728 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1730 IShellItem_Release(psidesktop
);
1731 IShellItem_Release(psidesktop2
);
1732 IShellItem_Release(psitestdir
);
1733 IShellItem_Release(psitestdir2
);
1734 IShellItem_Release(psitest1
);
1736 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
1737 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1741 hr
= IOleWindow_GetWindow(pow
, &hwnd_nstc
);
1742 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1743 DestroyWindow(hwnd_nstc
);
1744 IOleWindow_Release(pow
);
1747 res
= INameSpaceTreeControl_Release(pnstc
);
1748 ok(!res
, "res was %d!\n", res
);
1754 static void test_events(void)
1756 INameSpaceTreeControl
*pnstc
;
1757 INameSpaceTreeControlEventsImpl
*pnstceimpl
, *pnstceimpl2
;
1758 INameSpaceTreeControlEvents
*pnstce
, *pnstce2
;
1759 IShellFolder
*psfdesktop
;
1760 IShellItem
*psidesktop
;
1762 LPITEMIDLIST pidl_desktop
;
1763 LPITEMIDLIST pidl_drives
;
1764 NSTCITEMSTATE itemstate
;
1766 DWORD cookie1
, cookie2
;
1771 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
1772 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
1773 ok(hr
== S_OK
, "Failed to initialize control (0x%08x)\n", hr
);
1775 ok(pSHCreateShellItem
!= NULL
, "No SHCreateShellItem.\n");
1776 ok(pSHGetIDListFromObject
!= NULL
, "No SHCreateShellItem.\n");
1778 SHGetDesktopFolder(&psfdesktop
);
1779 hr
= pSHGetIDListFromObject((IUnknown
*)psfdesktop
, &pidl_desktop
);
1780 IShellFolder_Release(psfdesktop
);
1781 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1782 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop
);
1783 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1784 ILFree(pidl_desktop
);
1786 /* Create two instances of INameSpaceTreeControlEvents */
1787 pnstceimpl
= create_nstc_events();
1788 pnstce
= &pnstceimpl
->INameSpaceTreeControlEvents_iface
;
1789 ZeroMemory(&pnstceimpl
->count
, sizeof(UINT
)*LastEvent
);
1790 pnstceimpl2
= create_nstc_events();
1791 pnstce2
= &pnstceimpl2
->INameSpaceTreeControlEvents_iface
;
1795 /* Crashes native */
1796 INameSpaceTreeControl_TreeAdvise(pnstc
, NULL
, NULL
);
1797 INameSpaceTreeControl_TreeAdvise(pnstc
, NULL
, &cookie1
);
1798 INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, NULL
);
1801 /* TreeAdvise in NameSpaceTreeController seems to support only one
1802 * client at the time.
1805 /* First, respond with E_NOINTERFACE to all QI's */
1806 pnstceimpl
->qi_enable_events
= FALSE
;
1807 pnstceimpl
->qi_called_count
= 0;
1809 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie1
);
1810 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1811 ok(cookie1
== 0, "cookie now (0x%08x)\n", cookie1
);
1812 ok(pnstceimpl
->qi_called_count
> 1, "got %d\n", pnstceimpl
->qi_called_count
);
1813 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1815 /* Accept query for IID_INameSpaceTreeControlEvents */
1816 pnstceimpl
->qi_enable_events
= TRUE
;
1817 pnstceimpl
->qi_called_count
= 0;
1819 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie1
);
1820 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1821 ok(cookie1
== 1, "cookie now (0x%08x)\n", cookie1
);
1822 ok(pnstceimpl
->qi_called_count
> 1, "got %d\n", pnstceimpl
->qi_called_count
);
1823 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1825 /* A second time, query interface will not be called at all. */
1826 pnstceimpl
->qi_enable_events
= TRUE
;
1827 pnstceimpl
->qi_called_count
= 0;
1829 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie2
);
1830 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1831 ok(cookie2
== 0, "cookie now (0x%08x)\n", cookie2
);
1832 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1833 pnstceimpl
->qi_called_count
);
1834 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1836 /* Using another "instance" does not help. */
1837 pnstceimpl2
->qi_enable_events
= TRUE
;
1838 pnstceimpl2
->qi_called_count
= 0;
1840 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce2
, &cookie2
);
1841 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1842 ok(cookie2
== 0, "cookie now (0x%08x)\n", cookie2
);
1843 ok(!pnstceimpl2
->qi_called_count
, "QueryInterface called %d times.\n",
1844 pnstceimpl2
->qi_called_count
);
1845 ok(pnstceimpl2
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1847 /* Unadvise with bogus cookie (will actually unadvise properly) */
1848 pnstceimpl
->qi_enable_events
= TRUE
;
1849 pnstceimpl
->qi_called_count
= 0;
1850 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, 1234);
1851 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1852 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1853 pnstceimpl
->qi_called_count
);
1854 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1856 /* Unadvise "properly" (will have no additional effect) */
1857 pnstceimpl
->qi_enable_events
= TRUE
;
1858 pnstceimpl
->qi_called_count
= 0;
1859 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, cookie1
);
1860 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1861 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1862 pnstceimpl
->qi_called_count
);
1863 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1865 /* Advise again.. */
1866 pnstceimpl
->qi_enable_events
= 1;
1867 pnstceimpl
->qi_called_count
= 0;
1868 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie2
);
1869 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1870 ok(cookie2
== 1, "Cookie is %d\n", cookie2
);
1871 ok(cookie1
== cookie2
, "Old cookie differs from old cookie.\n");
1872 /* several kinds of callbacks are queried for */
1873 ok(pnstceimpl
->qi_called_count
> 1, "got %d\n", pnstceimpl
->qi_called_count
);
1874 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1876 /* Initialize the control */
1877 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, NULL
, 0);
1878 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1879 ok_no_events(pnstceimpl
);
1881 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
1882 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
1883 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1885 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
1886 ok_event_count(pnstceimpl
, OnGetDefaultIconIndex
, 0);
1887 ok_no_events(pnstceimpl
);
1889 hwnd_tv
= get_treeview_hwnd(pnstc
);
1890 ok(hwnd_tv
!= NULL
, "Failed to get hwnd_tv HWND.\n");
1893 HTREEITEM hroot
, hitem
;
1895 static const UINT kbd_msgs_event
[] = {
1896 WM_KEYDOWN
, WM_KEYUP
, WM_CHAR
, WM_SYSKEYDOWN
, WM_SYSKEYUP
,
1898 static const UINT kbd_msgs_noevent
[] ={
1899 WM_DEADCHAR
, WM_SYSDEADCHAR
, WM_UNICHAR
, 0 };
1901 /* Test On*Expand */
1902 hroot
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_ROOT
, 0);
1903 SendMessageW(hwnd_tv
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)hroot
);
1905 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
1906 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
1907 ok_event_broken(pnstceimpl
, OnItemAdded
); /* No event on Vista */
1908 todo_wine
ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
1909 ok_no_events(pnstceimpl
);
1910 SendMessageW(hwnd_tv
, TVM_EXPAND
, TVE_COLLAPSE
, (LPARAM
)hroot
);
1912 ok_no_events(pnstceimpl
);
1913 SendMessageW(hwnd_tv
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)hroot
);
1915 ok_no_events(pnstceimpl
);
1917 /* Test OnSelectionChanged */
1918 hitem
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_CHILD
, (LPARAM
)hroot
);
1919 SendMessageW(hwnd_tv
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
)hitem
);
1921 ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
1922 ok_no_events(pnstceimpl
);
1924 /* Test OnKeyboardInput */
1925 for(i
= 0; kbd_msgs_event
[i
] != 0; i
++)
1927 SendMessageW(hwnd_tv
, kbd_msgs_event
[i
], 0x1234, 0x1234);
1928 ok(pnstceimpl
->count
[OnKeyboardInput
] == 1,
1929 "%d (%x): Got count %d\n",
1930 kbd_msgs_event
[i
], kbd_msgs_event
[i
], pnstceimpl
->count
[OnKeyboardInput
]);
1931 pnstceimpl
->count
[OnKeyboardInput
] = 0;
1934 for(i
= 0; kbd_msgs_noevent
[i
] != 0; i
++)
1936 SendMessageW(hwnd_tv
, kbd_msgs_noevent
[i
], 0x1234, 0x1234);
1937 ok(pnstceimpl
->count
[OnKeyboardInput
] == 0,
1938 "%d (%x): Got count %d\n",
1939 kbd_msgs_noevent
[i
], kbd_msgs_noevent
[i
], pnstceimpl
->count
[OnKeyboardInput
]);
1940 pnstceimpl
->count
[OnKeyboardInput
] = 0;
1942 ok_no_events(pnstceimpl
);
1945 skip("Skipping some tests.\n");
1947 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1949 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1950 ok_event(pnstceimpl
, OnItemDeleted
);
1951 ok_no_events(pnstceimpl
);
1953 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
1954 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
1955 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1957 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
1958 ok_no_events(pnstceimpl
);
1960 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
1961 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1962 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
1964 ok_no_events(pnstceimpl
);
1966 /* Expand the root */
1967 itemstate
|= NSTCIS_EXPANDED
;
1968 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, itemstate
);
1969 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1971 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
1972 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
1973 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
1976 ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /* Vista*/);
1978 ok_no_events(pnstceimpl
);
1980 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
1981 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1982 ok(itemstate
& NSTCIS_EXPANDED
, "Item not expanded.\n");
1985 ok(itemstate
== (NSTCIS_SELECTED
| NSTCIS_EXPANDED
)||
1986 broken(itemstate
== NSTCIS_EXPANDED
) /* Vista */,
1987 "itemstate is 0x%08x\n", itemstate
);
1989 ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /* Vista*/);
1991 ok_no_events(pnstceimpl
);
1993 /* Deselect the root */
1994 itemstate
&= ~NSTCIS_SELECTED
;
1995 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, itemstate
);
1996 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1998 ok_no_events(pnstceimpl
);
2000 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2001 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2002 ok(itemstate
== (NSTCIS_EXPANDED
), "itemstate is 0x%08x\n", itemstate
);
2003 ok_no_events(pnstceimpl
);
2005 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
2006 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2007 ok_no_events(pnstceimpl
);
2009 /* Delete all roots */
2010 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2011 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2012 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
2013 ok_no_events(pnstceimpl
);
2015 /* Get/SetItemState */
2018 /* Crashes on Windows 7 */
2019 INameSpaceTreeControl_SetItemState(pnstc
, NULL
, 0, 0);
2020 INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, NULL
);
2021 INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0, NULL
);
2022 INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, &itemstate
);
2023 INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0, NULL
);
2024 INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, &itemstate
);
2027 itemstate
= 0xDEADBEEF;
2028 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2029 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2030 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2031 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2032 ok_no_events(pnstceimpl
);
2034 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
2035 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2036 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2038 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2039 ok_no_events(pnstceimpl
);
2041 itemstate
= 0xDEADBEEF;
2042 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2043 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2044 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2045 ok_no_events(pnstceimpl
);
2047 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0, 0xffff);
2048 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2052 ok_event_count(pnstceimpl
, OnBeforeExpand
, 0);
2053 ok_event_count(pnstceimpl
, OnAfterExpand
, 0);
2054 ok_event_count(pnstceimpl
, OnItemAdded
, 0);
2056 ok_no_events(pnstceimpl
);
2058 itemstate
= 0xDEADBEEF;
2059 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2060 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2062 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2063 ok_no_events(pnstceimpl
);
2065 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2066 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2068 ok_no_events(pnstceimpl
);
2070 itemstate
= 0xDEADBEEF;
2071 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2072 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2073 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2074 ok_no_events(pnstceimpl
);
2076 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_SELECTED
);
2077 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2079 ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
2080 ok_no_events(pnstceimpl
);
2082 itemstate
= 0xDEADBEEF;
2083 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2084 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2085 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2086 ok_no_events(pnstceimpl
);
2088 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_EXPANDED
, NSTCIS_SELECTED
);
2089 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2091 ok_no_events(pnstceimpl
);
2093 itemstate
= 0xDEADBEEF;
2094 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2095 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2096 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2097 ok_no_events(pnstceimpl
);
2099 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2100 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2102 ok_no_events(pnstceimpl
);
2104 itemstate
= 0xDEADBEEF;
2105 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2106 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2107 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2108 ok_no_events(pnstceimpl
);
2110 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_SELECTEDNOEXPAND
);
2111 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2113 ok_no_events(pnstceimpl
);
2115 itemstate
= 0xDEADBEEF;
2116 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2117 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2118 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2119 ok_no_events(pnstceimpl
);
2121 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_EXPANDED
);
2122 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2126 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
2127 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
2128 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
2130 ok_no_events(pnstceimpl
);
2132 itemstate
= 0xDEADBEEF;
2133 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2134 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2135 ok(itemstate
== NSTCIS_EXPANDED
, "itemstate is 0x%08x\n", itemstate
);
2136 ok_no_events(pnstceimpl
);
2138 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2139 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2141 ok_no_events(pnstceimpl
);
2143 itemstate
= 0xDEADBEEF;
2144 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2145 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2146 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2147 ok_no_events(pnstceimpl
);
2149 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0xffff);
2150 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2152 ok_no_events(pnstceimpl
);
2154 itemstate
= 0xDEADBEEF;
2155 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2156 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2159 ok(itemstate
== (NSTCIS_EXPANDED
| NSTCIS_BOLD
| NSTCIS_DISABLED
),
2160 "itemstate is 0x%08x\n", itemstate
);
2162 ok_no_events(pnstceimpl
);
2164 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_SELECTED
, NSTCIS_SELECTED
);
2165 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2167 ok_no_events(pnstceimpl
);
2169 itemstate
= 0xDEADBEEF;
2170 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2171 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2174 ok(itemstate
== (NSTCIS_EXPANDED
| NSTCIS_BOLD
| NSTCIS_DISABLED
),
2175 "itemstate is 0x%08x\n", itemstate
);
2177 ok_no_events(pnstceimpl
);
2179 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
2180 NSTCIS_SELECTED
| NSTCIS_DISABLED
, NSTCIS_SELECTED
);
2181 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2183 ok_no_events(pnstceimpl
);
2185 itemstate
= 0xDEADBEEF;
2186 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2187 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2188 ok(itemstate
== (NSTCIS_BOLD
| NSTCIS_EXPANDED
),
2189 "itemstate is 0x%08x\n", itemstate
);
2190 ok_no_events(pnstceimpl
);
2192 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_SELECTED
, NSTCIS_SELECTED
);
2193 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2195 ok_no_events(pnstceimpl
);
2197 itemstate
= 0xDEADBEEF;
2198 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2199 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2200 ok(itemstate
== (NSTCIS_BOLD
| NSTCIS_EXPANDED
),
2201 "itemstate is 0x%08x\n", itemstate
);
2202 ok_no_events(pnstceimpl
);
2204 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff & ~NSTCIS_DISABLED
, 0);
2205 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2207 ok_no_events(pnstceimpl
);
2209 itemstate
= 0xDEADBEEF;
2210 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2211 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2212 ok(itemstate
== NSTCIS_BOLD
, "itemstate is 0x%08x\n", itemstate
);
2213 ok_no_events(pnstceimpl
);
2215 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2216 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2217 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
2218 ok_no_events(pnstceimpl
);
2221 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, NULL
, 0, NULL
);
2222 ok(hr
== E_POINTER
, "Got (0x%08x)\n", hr
);
2223 ok_no_events(pnstceimpl
);
2225 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, 0, NULL
);
2226 ok(hr
== E_POINTER
, "Got (0x%08x)\n", hr
);
2227 ok_no_events(pnstceimpl
);
2229 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, NULL
, 0, &psi
);
2230 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2231 ok_no_events(pnstceimpl
);
2233 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, 0, &psi
);
2234 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2235 ok_no_events(pnstceimpl
);
2237 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2238 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2240 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2241 ok_no_events(pnstceimpl
);
2243 /* Get child from unexpanded and unfilled parent */
2244 psi
= (void*)0xDEADBEEF;
2245 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, NSTCGNI_CHILD
, &psi
);
2246 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2247 ok(psi
== NULL
, "psi is %p\n", psi
);
2249 ok_no_events(pnstceimpl
);
2251 /* Expand and try again */
2252 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_EXPANDED
, 0xffff);
2253 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2255 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
2256 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
2257 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
2258 todo_wine
ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /*Vista */);
2259 ok_no_events(pnstceimpl
);
2260 psi
= (void*)0xDEADBEEF;
2261 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, NSTCGNI_CHILD
, &psi
);
2262 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2263 ok((psi
!= NULL
) && (psi
!= (void*)0xDEADBEEF), "psi is %p\n", psi
);
2265 ok_no_events(pnstceimpl
);
2266 if(SUCCEEDED(hr
)) IShellItem_Release(psi
);
2268 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2269 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2270 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
2271 ok_no_events(pnstceimpl
);
2273 /* EnsureItemVisible */
2276 /* Crashes on Windows 7 */
2277 INameSpaceTreeControl_EnsureItemVisible(pnstc
, NULL
);
2280 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2281 ok(hr
== E_INVALIDARG
|| hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2282 ok_no_events(pnstceimpl
);
2284 hr
= pSHGetSpecialFolderLocation(NULL
, CSIDL_DRIVES
, &pidl_drives
);
2285 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2288 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_drives
, &psi
);
2289 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2292 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psi
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2293 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2295 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2296 ok_no_events(pnstceimpl
);
2298 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2299 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2300 ok_no_events(pnstceimpl
);
2302 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psi
);
2303 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2304 ok_no_events(pnstceimpl
);
2306 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2307 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2309 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2310 ok_no_events(pnstceimpl
);
2312 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2313 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2314 ok_no_events(pnstceimpl
);
2316 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psi
);
2317 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2318 ok_no_events(pnstceimpl
);
2322 skip("Failed to create shellitem.\n");
2324 ILFree(pidl_drives
);
2327 skip("Failed to get pidl for CSIDL_DRIVES.\n");
2329 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2330 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2331 ok_event_count(pnstceimpl
, OnItemDeleted
, 2);
2332 ok_no_events(pnstceimpl
);
2334 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
2335 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2339 hr
= IOleWindow_GetWindow(pow
, &hwnd_nstc
);
2340 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2341 DestroyWindow(hwnd_nstc
);
2342 IOleWindow_Release(pow
);
2345 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, cookie2
);
2346 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2348 res
= INameSpaceTreeControl_Release(pnstc
);
2349 ok(!res
, "res was %d!\n", res
);
2353 /* Freeing these prematurely causes a crash. */
2354 heap_free(pnstceimpl
);
2355 heap_free(pnstceimpl2
);
2358 IShellItem_Release(psi
);
2359 IShellItem_Release(psidesktop
);
2362 static void setup_window(void)
2365 static const char nstctest_wnd_name
[] = "nstctest_wnd";
2367 ZeroMemory(&wc
, sizeof(WNDCLASSA
));
2368 wc
.lpfnWndProc
= DefWindowProcA
;
2369 wc
.lpszClassName
= nstctest_wnd_name
;
2370 RegisterClassA(&wc
);
2371 hwnd
= CreateWindowA(nstctest_wnd_name
, NULL
, WS_TABSTOP
,
2372 0, 0, 200, 200, NULL
, 0, 0, NULL
);
2373 ok(hwnd
!= NULL
, "Failed to create window for test (lasterror: %d).\n",
2377 static void destroy_window(void)
2379 DestroyWindow(hwnd
);
2384 OleInitialize(NULL
);
2386 init_function_pointers();
2387 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
2389 if(test_initialization())
2395 win_skip("No NamespaceTreeControl (or instantiation failed).\n");