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
26 #include "wine/test.h"
32 /* "Intended for internal use" */
33 #define TVS_EX_NOSINGLECOLLAPSE 0x1
35 static HRESULT (WINAPI
*pSHCreateShellItem
)(LPCITEMIDLIST
,IShellFolder
*,LPCITEMIDLIST
,IShellItem
**);
36 static HRESULT (WINAPI
*pSHGetIDListFromObject
)(IUnknown
*, PIDLIST_ABSOLUTE
*);
37 static HRESULT (WINAPI
*pSHCreateItemFromParsingName
)(PCWSTR
,IBindCtx
*,REFIID
,void**);
38 static HRESULT (WINAPI
*pSHGetSpecialFolderLocation
)(HWND
, int, LPITEMIDLIST
*);
40 #define NUM_MSG_SEQUENCES 1
41 #define TREEVIEW_SEQ_INDEX 0
43 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
45 /* Keep a copy of the last structure passed by TVM_SETITEMW */
46 static TVITEMEXW last_tvi
;
49 static void init_function_pointers(void)
53 hmod
= GetModuleHandleA("shell32.dll");
54 pSHCreateShellItem
= (void*)GetProcAddress(hmod
, "SHCreateShellItem");
55 pSHGetIDListFromObject
= (void*)GetProcAddress(hmod
, "SHGetIDListFromObject");
56 pSHCreateItemFromParsingName
= (void*)GetProcAddress(hmod
, "SHCreateItemFromParsingName");
57 pSHGetSpecialFolderLocation
= (void*)GetProcAddress(hmod
, "SHGetSpecialFolderLocation");
60 /*******************************************************
61 * INameSpaceTreeControlEvents implementation.
63 enum { OnItemClick
= 0, OnPropertyItemCommit
, OnItemStateChanging
, OnItemStateChanged
,
64 OnSelectionChanged
, OnKeyboardInput
, OnBeforeExpand
, OnAfterExpand
, OnBeginLabelEdit
,
65 OnEndLabelEdit
, OnGetToolTip
, OnBeforeItemDelete
, OnItemAdded
, OnItemDeleted
,
66 OnBeforeContextMenu
, OnAfterContextMenu
, OnBeforeStateImageChange
, OnGetDefaultIconIndex
,
70 const INameSpaceTreeControlEventsVtbl
*lpVtbl
;
71 UINT qi_called_count
; /* Keep track of calls to QueryInterface */
72 BOOL qi_enable_events
; /* If FALSE, QueryInterface returns only E_NOINTERFACE */
73 UINT count
[LastEvent
]; /* Keep track of calls to all On* functions. */
75 } INameSpaceTreeControlEventsImpl
;
77 #define NSTCE_IMPL(iface) \
78 ((INameSpaceTreeControlEventsImpl*)iface)
80 static HRESULT WINAPI
NSTCEvents_fnQueryInterface(
81 INameSpaceTreeControlEvents
* iface
,
85 NSTCE_IMPL(iface
)->qi_called_count
++;
87 if(NSTCE_IMPL(iface
)->qi_enable_events
&&
88 IsEqualIID(riid
, &IID_INameSpaceTreeControlEvents
))
90 IUnknown_AddRef(iface
);
98 static ULONG WINAPI
NSTCEvents_fnAddRef(
99 INameSpaceTreeControlEvents
* iface
)
101 return InterlockedIncrement(&NSTCE_IMPL(iface
)->ref
);
104 static ULONG WINAPI
NSTCEvents_fnRelease(
105 INameSpaceTreeControlEvents
* iface
)
107 return InterlockedDecrement(&NSTCE_IMPL(iface
)->ref
);
110 static HRESULT WINAPI
NSTCEvents_fnOnItemClick(
111 INameSpaceTreeControlEvents
* iface
,
113 NSTCEHITTEST nstceHitTest
,
114 NSTCECLICKTYPE nstceClickType
)
116 ok(psi
!= NULL
, "NULL IShellItem\n");
117 NSTCE_IMPL(iface
)->count
[OnItemClick
]++;
121 static HRESULT WINAPI
NSTCEvents_fnOnPropertyItemCommit(
122 INameSpaceTreeControlEvents
* iface
,
125 ok(psi
!= NULL
, "NULL IShellItem\n");
126 NSTCE_IMPL(iface
)->count
[OnPropertyItemCommit
]++;
130 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanging(
131 INameSpaceTreeControlEvents
* iface
,
133 NSTCITEMSTATE nstcisMask
,
134 NSTCITEMSTATE nstcisState
)
136 ok(psi
!= NULL
, "NULL IShellItem\n");
137 NSTCE_IMPL(iface
)->count
[OnItemStateChanging
]++;
141 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanged(
142 INameSpaceTreeControlEvents
* iface
,
144 NSTCITEMSTATE nstcisMask
,
145 NSTCITEMSTATE nstcisState
)
147 ok(psi
!= NULL
, "NULL IShellItem\n");
148 NSTCE_IMPL(iface
)->count
[OnItemStateChanged
]++;
152 static HRESULT WINAPI
NSTCEvents_fnOnSelectionChanged(
153 INameSpaceTreeControlEvents
* iface
,
154 IShellItemArray
*psiaSelection
)
156 ok(psiaSelection
!= NULL
, "IShellItemArray was NULL.\n");
160 DWORD count
= 0xdeadbeef;
161 hr
= IShellItemArray_GetCount(psiaSelection
, &count
);
162 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
163 ok(count
== 1, "Got count 0x%x\n", count
);
165 NSTCE_IMPL(iface
)->count
[OnSelectionChanged
]++;
169 static HRESULT WINAPI
NSTCEvents_fnOnKeyboardInput(
170 INameSpaceTreeControlEvents
* iface
,
175 NSTCE_IMPL(iface
)->count
[OnKeyboardInput
]++;
176 ok(wParam
== 0x1234, "Got unexpected wParam %lx\n", wParam
);
177 ok(lParam
== 0x1234, "Got unexpected lParam %lx\n", lParam
);
181 static HRESULT WINAPI
NSTCEvents_fnOnBeforeExpand(
182 INameSpaceTreeControlEvents
* iface
,
185 ok(psi
!= NULL
, "NULL IShellItem\n");
186 NSTCE_IMPL(iface
)->count
[OnBeforeExpand
]++;
190 static HRESULT WINAPI
NSTCEvents_fnOnAfterExpand(
191 INameSpaceTreeControlEvents
* iface
,
194 ok(psi
!= NULL
, "NULL IShellItem\n");
195 NSTCE_IMPL(iface
)->count
[OnAfterExpand
]++;
199 static HRESULT WINAPI
NSTCEvents_fnOnBeginLabelEdit(
200 INameSpaceTreeControlEvents
* iface
,
203 ok(psi
!= NULL
, "NULL IShellItem\n");
204 NSTCE_IMPL(iface
)->count
[OnBeginLabelEdit
]++;
208 static HRESULT WINAPI
NSTCEvents_fnOnEndLabelEdit(
209 INameSpaceTreeControlEvents
* iface
,
212 ok(psi
!= NULL
, "NULL IShellItem\n");
213 NSTCE_IMPL(iface
)->count
[OnEndLabelEdit
]++;
217 static HRESULT WINAPI
NSTCEvents_fnOnGetToolTip(
218 INameSpaceTreeControlEvents
* iface
,
223 ok(psi
!= NULL
, "NULL IShellItem\n");
224 NSTCE_IMPL(iface
)->count
[OnGetToolTip
]++;
228 static HRESULT WINAPI
NSTCEvents_fnOnBeforeItemDelete(
229 INameSpaceTreeControlEvents
* iface
,
232 ok(psi
!= NULL
, "NULL IShellItem\n");
233 NSTCE_IMPL(iface
)->count
[OnBeforeItemDelete
]++;
237 static HRESULT WINAPI
NSTCEvents_fnOnItemAdded(
238 INameSpaceTreeControlEvents
* iface
,
242 ok(psi
!= NULL
, "NULL IShellItem\n");
243 NSTCE_IMPL(iface
)->count
[OnItemAdded
]++;
247 static HRESULT WINAPI
NSTCEvents_fnOnItemDeleted(
248 INameSpaceTreeControlEvents
* iface
,
252 ok(psi
!= NULL
, "NULL IShellItem\n");
253 NSTCE_IMPL(iface
)->count
[OnItemDeleted
]++;
257 static HRESULT WINAPI
NSTCEvents_fnOnBeforeContextMenu(
258 INameSpaceTreeControlEvents
* iface
,
263 NSTCE_IMPL(iface
)->count
[OnBeforeContextMenu
]++;
267 static HRESULT WINAPI
NSTCEvents_fnOnAfterContextMenu(
268 INameSpaceTreeControlEvents
* iface
,
274 NSTCE_IMPL(iface
)->count
[OnAfterContextMenu
]++;
278 static HRESULT WINAPI
NSTCEvents_fnOnBeforeStateImageChange(
279 INameSpaceTreeControlEvents
* iface
,
282 ok(psi
!= NULL
, "NULL IShellItem\n");
283 NSTCE_IMPL(iface
)->count
[OnBeforeStateImageChange
]++;
287 static HRESULT WINAPI
NSTCEvents_fnOnGetDefaultIconIndex(
288 INameSpaceTreeControlEvents
* iface
,
293 ok(psi
!= NULL
, "NULL IShellItem\n");
294 NSTCE_IMPL(iface
)->count
[OnGetDefaultIconIndex
]++;
298 const INameSpaceTreeControlEventsVtbl vt_NSTCEvents
= {
299 NSTCEvents_fnQueryInterface
,
301 NSTCEvents_fnRelease
,
302 NSTCEvents_fnOnItemClick
,
303 NSTCEvents_fnOnPropertyItemCommit
,
304 NSTCEvents_fnOnItemStateChanging
,
305 NSTCEvents_fnOnItemStateChanged
,
306 NSTCEvents_fnOnSelectionChanged
,
307 NSTCEvents_fnOnKeyboardInput
,
308 NSTCEvents_fnOnBeforeExpand
,
309 NSTCEvents_fnOnAfterExpand
,
310 NSTCEvents_fnOnBeginLabelEdit
,
311 NSTCEvents_fnOnEndLabelEdit
,
312 NSTCEvents_fnOnGetToolTip
,
313 NSTCEvents_fnOnBeforeItemDelete
,
314 NSTCEvents_fnOnItemAdded
,
315 NSTCEvents_fnOnItemDeleted
,
316 NSTCEvents_fnOnBeforeContextMenu
,
317 NSTCEvents_fnOnAfterContextMenu
,
318 NSTCEvents_fnOnBeforeStateImageChange
,
319 NSTCEvents_fnOnGetDefaultIconIndex
323 static INameSpaceTreeControlEventsImpl
*create_nstc_events(void)
325 INameSpaceTreeControlEventsImpl
*This
;
326 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(INameSpaceTreeControlEventsImpl
));
327 This
->lpVtbl
= &vt_NSTCEvents
;
333 /*********************************************************************
334 * Event count checking
336 static void ok_no_events_(INameSpaceTreeControlEventsImpl
*impl
,
337 const char *file
, int line
)
340 for(i
= 0; i
< LastEvent
; i
++)
343 (!impl
->count
[i
], "Got event %d, count %d\n", i
, impl
->count
[i
]);
347 #define ok_no_events(impl) \
348 ok_no_events_(impl, __FILE__, __LINE__)
350 #define ok_event_count_broken(impl, event, c, b) \
351 do { ok(impl->count[event] == c || broken(impl->count[event] == b), \
352 "Got event %d, count %d\n", event, impl->count[event]); \
353 impl->count[event] = 0; \
356 #define ok_event_count(impl, event, c) \
357 ok_event_count_broken(impl, event, c, -1)
359 #define ok_event_broken(impl, event) \
360 do { ok(impl->count[event] || broken(!impl->count[event]), \
362 impl->count[event] = 0; \
365 #define ok_event(impl, event) \
366 do { ok(impl->count[event], "No event %d.\n", event); \
367 impl->count[event] = 0; \
370 /* Process some messages */
371 static void process_msgs(void)
378 while(PeekMessage( &msg
, NULL
, 0, 0, PM_REMOVE
))
380 TranslateMessage(&msg
);
381 DispatchMessage(&msg
);
386 /* There seem to be a timer that sometimes fires after about
387 500ms, we need to wait for it. Failing to wait can result in
388 seemingly sporadic selection change events. (Timer ID is 87,
389 sending WM_TIMER manually does not seem to help us.) */
392 while(PeekMessage( &msg
, NULL
, 0, 0, PM_REMOVE
))
394 TranslateMessage(&msg
);
395 DispatchMessage(&msg
);
399 /** Some functions from shell32/tests/shlfolder.c */
400 /* creates a file with the specified name for tests */
401 static void CreateTestFile(const CHAR
*name
)
406 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
407 if (file
!= INVALID_HANDLE_VALUE
)
409 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
410 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
414 /* initializes the tests */
415 static void CreateFilesFolders(void)
417 CreateDirectoryA(".\\testdir", NULL
);
418 CreateTestFile (".\\testdir\\test1.txt ");
419 CreateTestFile (".\\testdir\\test2.txt ");
420 CreateTestFile (".\\testdir\\test3.txt ");
421 CreateDirectoryA(".\\testdir\\testdir2 ", NULL
);
422 CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL
);
425 /* cleans after tests */
426 static void Cleanup(void)
428 DeleteFileA(".\\testdir\\test1.txt");
429 DeleteFileA(".\\testdir\\test2.txt");
430 DeleteFileA(".\\testdir\\test3.txt");
431 RemoveDirectoryA(".\\testdir\\testdir2\\subdir");
432 RemoveDirectoryA(".\\testdir\\testdir2");
433 RemoveDirectoryA(".\\testdir");
436 /* Based on PathAddBackslashW from dlls/shlwapi/path.c */
437 static LPWSTR
myPathAddBackslashW( LPWSTR lpszPath
)
441 if (!lpszPath
|| (iLen
= lstrlenW(lpszPath
)) >= MAX_PATH
)
447 if (lpszPath
[-1] != '\\')
456 static HWND
get_treeview_hwnd(INameSpaceTreeControl
*pnstc
)
460 HWND treeview
= NULL
;
462 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
463 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
467 hr
= IOleWindow_GetWindow(pow
, &host
);
468 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
470 treeview
= FindWindowExW(host
, NULL
, WC_TREEVIEWW
, NULL
);
471 IOleWindow_Release(pow
);
477 static LRESULT WINAPI
treeview_subclass_proc(HWND hwnd_tv
, UINT message
, WPARAM wParam
, LPARAM lParam
)
479 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrW(hwnd_tv
, GWLP_USERDATA
);
480 static LONG defwndproc_counter
= 0;
484 msg
.message
= message
;
485 msg
.flags
= sent
|wparam
|lparam
;
486 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
490 add_message(sequences
, TREEVIEW_SEQ_INDEX
, &msg
);
492 if(message
== TVM_SETITEMW
)
494 memcpy(&last_tvi
, (void*)lParam
, sizeof(TVITEMEXW
));
498 defwndproc_counter
++;
499 ret
= CallWindowProcW(oldproc
, hwnd_tv
, message
, wParam
, lParam
);
500 defwndproc_counter
--;
504 static BOOL
subclass_treeview(INameSpaceTreeControl
*pnstc
)
507 WNDPROC oldproc
= NULL
;
509 hwnd_tv
= get_treeview_hwnd(pnstc
);
512 oldproc
= (WNDPROC
)SetWindowLongPtrW(hwnd_tv
, GWLP_WNDPROC
,
513 (LONG_PTR
)treeview_subclass_proc
);
514 SetWindowLongPtrW(hwnd_tv
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
515 ok(oldproc
!= NULL
, "Failed to subclass.\n");
518 return oldproc
?TRUE
:FALSE
;
521 static UINT
get_msg_count(struct msg_sequence
**seq
, int sequence_index
, UINT message
)
523 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
526 for(i
= 0; i
< msg_seq
->count
; i
++)
527 if(msg_seq
->sequence
[i
].message
== message
)
533 /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
534 static BOOL
test_initialization(void)
536 INameSpaceTreeControl
*pnstc
;
544 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
545 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
546 ok(hr
== S_OK
|| hr
== REGDB_E_CLASSNOTREG
, "Got 0x%08x\n", hr
);
552 hr
= INameSpaceTreeControl_Initialize(pnstc
, NULL
, NULL
, 0);
553 ok(hr
== HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD
), "Got (0x%08x)\n", hr
);
555 hr
= INameSpaceTreeControl_Initialize(pnstc
, (HWND
)0xDEADBEEF, NULL
, 0);
556 ok(hr
== HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE
), "Got (0x%08x)\n", hr
);
558 ZeroMemory(&rc
, sizeof(RECT
));
559 hr
= INameSpaceTreeControl_Initialize(pnstc
, NULL
, &rc
, 0);
560 ok(hr
== HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD
), "Got (0x%08x)\n", hr
);
562 hr
= INameSpaceTreeControl_Initialize(pnstc
, (HWND
)0xDEADBEEF, &rc
, 0);
563 ok(hr
== HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE
), "Got (0x%08x)\n", hr
);
565 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
566 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
569 hr
= IOleWindow_GetWindow(pow
, &hwnd_host1
);
570 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
571 ok(hwnd_host1
== NULL
, "hwnd is not null.\n");
573 hr
= IOleWindow_ContextSensitiveHelp(pow
, TRUE
);
574 ok(hr
== E_NOTIMPL
, "Got (0x%08x)\n", hr
);
575 hr
= IOleWindow_ContextSensitiveHelp(pow
, FALSE
);
576 ok(hr
== E_NOTIMPL
, "Got (0x%08x)\n", hr
);
577 IOleWindow_Release(pow
);
580 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, NULL
, 0);
581 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
582 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
583 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
586 static const CHAR namespacetree
[] = "NamespaceTreeControl";
588 LONG style
, expected_style
;
590 hr
= IOleWindow_GetWindow(pow
, &hwnd_host1
);
591 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
592 ok(hwnd_host1
!= NULL
, "hwnd_host1 is null.\n");
594 GetClassNameA(hwnd_host1
, buf
, 1024);
595 ok(!lstrcmpA(namespacetree
, buf
), "Class name was %s\n", buf
);
597 expected_style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
598 style
= GetWindowLongPtrW(hwnd_host1
, GWL_STYLE
);
599 ok(style
== expected_style
, "Got style %08x\n", style
);
602 style
= GetWindowLongPtrW(hwnd_host1
, GWL_EXSTYLE
);
603 ok(style
== expected_style
, "Got style %08x\n", style
);
606 style
= SendMessageW(hwnd_host1
, TVM_GETEXTENDEDSTYLE
, 0, 0);
607 ok(style
== expected_style
, "Got 0x%08x\n", style
);
609 hwnd_tv
= FindWindowExW(hwnd_host1
, NULL
, WC_TREEVIEWW
, NULL
);
610 ok(hwnd_tv
!= NULL
, "Failed to get treeview hwnd.\n");
613 expected_style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
|
614 WS_CLIPCHILDREN
| WS_TABSTOP
| TVS_NOHSCROLL
|
615 TVS_NONEVENHEIGHT
| TVS_INFOTIP
| TVS_TRACKSELECT
| TVS_EDITLABELS
;
616 style
= GetWindowLongPtrW(hwnd_tv
, GWL_STYLE
);
617 ok(style
== expected_style
, "Got style %08x\n", style
);
620 style
= GetWindowLongPtrW(hwnd_tv
, GWL_EXSTYLE
);
621 ok(style
== expected_style
, "Got style %08x\n", style
);
623 expected_style
= TVS_EX_NOSINGLECOLLAPSE
| TVS_EX_DOUBLEBUFFER
|
624 TVS_EX_RICHTOOLTIP
| TVS_EX_DRAWIMAGEASYNC
;
625 style
= SendMessageW(hwnd_tv
, TVM_GETEXTENDEDSTYLE
, 0, 0);
626 todo_wine
ok(style
== expected_style
, "Got 0x%08x\n", style
);
629 IOleWindow_Release(pow
);
634 /* The control can be initialized again without crashing, but
635 * the reference counting will break. */
636 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, &rc
, 0);
637 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
638 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
642 hr
= IOleWindow_GetWindow(pow
, &hwnd_host2
);
643 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
644 ok(hwnd_host1
!= hwnd_host2
, "Same hwnd.\n");
645 IOleWindow_Release(pow
);
649 /* Some "random" interfaces */
650 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceObject
, (void**)&punk
);
651 ok(hr
== E_NOINTERFACE
|| hr
== S_OK
/* vista, w2k8 */, "Got (0x%08x)\n", hr
);
652 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
653 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceActiveObject
, (void**)&punk
);
654 ok(hr
== E_NOINTERFACE
|| hr
== S_OK
/* vista, w2k8 */, "Got (0x%08x)\n", hr
);
655 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
656 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceObjectWindowless
, (void**)&punk
);
657 ok(hr
== E_NOINTERFACE
|| hr
== S_OK
/* vista, w2k8 */, "Got (0x%08x)\n", hr
);
658 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
660 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceUIWindow
, (void**)&punk
);
661 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
662 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceFrame
, (void**)&punk
);
663 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
664 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSite
, (void**)&punk
);
665 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
666 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSiteEx
, (void**)&punk
);
667 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
668 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleInPlaceSiteWindowless
, (void**)&punk
);
669 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
671 /* On windows, the reference count won't go to zero until the
672 * window is destroyed. */
673 INameSpaceTreeControl_AddRef(pnstc
);
674 lres
= INameSpaceTreeControl_Release(pnstc
);
675 ok(lres
> 1, "Reference count was (%d).\n", lres
);
677 DestroyWindow(hwnd_host1
);
678 lres
= INameSpaceTreeControl_Release(pnstc
);
679 ok(!lres
, "lres was %d\n", lres
);
684 static void verify_root_order_(INameSpaceTreeControl
*pnstc
, IShellItem
**roots
,
685 const char *file
, int line
)
688 IShellItemArray
*psia
;
690 hr
= INameSpaceTreeControl_GetRootItems(pnstc
, &psia
);
691 ok_(file
,line
) (hr
== S_OK
, "GetRootItems: got (0x%08x)\n", hr
);
694 DWORD i
, expected
, count
= -1;
695 hr
= IShellItemArray_GetCount(psia
, &count
);
696 ok_(file
,line
) (hr
== S_OK
, "Got (0x%08x)\n", hr
);
698 for(expected
= 0; roots
[expected
] != NULL
; expected
++);
699 ok_(file
,line
) (count
== expected
, "Got %d roots, expected %d\n", count
, expected
);
701 for(i
= 0; i
< count
&& roots
[i
] != NULL
; i
++)
704 hr
= IShellItemArray_GetItemAt(psia
, i
, &psi
);
705 ok_(file
,line
) (hr
== S_OK
, "GetItemAt %i: got 0x%08x\n", i
, hr
);
709 hr
= IShellItem_Compare(psi
, roots
[i
], SICHINT_DISPLAY
, &cmp
);
710 ok_(file
,line
) (hr
== S_OK
, "Compare %i: got 0x%08x\n", i
, hr
);
711 IShellItem_Release(psi
);
714 IShellItem_Release(psia
);
717 #define verify_root_order(pnstc, psi_a) \
718 verify_root_order_(pnstc, psi_a, __FILE__, __LINE__)
720 static void test_basics(void)
722 INameSpaceTreeControl
*pnstc
;
723 INameSpaceTreeControl2
*pnstc2
;
724 IShellItemArray
*psia
;
725 IShellFolder
*psfdesktop
;
727 IShellItem
*psidesktop
, *psidesktop2
;
728 IShellItem
*psitestdir
, *psitestdir2
, *psitest1
;
730 LPITEMIDLIST pidl_desktop
;
731 NSTCITEMSTATE istate
;
736 IShellItem
*roots
[10];
739 WCHAR curdirW
[MAX_PATH
];
741 static const WCHAR testdirW
[] = {'t','e','s','t','d','i','r',0};
742 static const WCHAR testdir2W
[] =
743 {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','2',0};
744 static const WCHAR test1W
[] =
745 {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
746 static const WCHAR explorerW
[] = {'E','x','p','l','o','r','e','r',0};
747 static const WCHAR randomW
[] = {'_','_','h','e','l','l','o',0};
749 /* These should exist on platforms supporting the NSTC */
750 ok(pSHCreateShellItem
!= NULL
, "No SHCreateShellItem.\n");
751 ok(pSHCreateItemFromParsingName
!= NULL
, "No SHCreateItemFromParsingName\n");
752 ok(pSHGetIDListFromObject
!= NULL
, "No SHCreateShellItem.\n");
753 ok(pSHCreateItemFromParsingName
!= NULL
, "No SHCreateItemFromParsingName\n");
755 /* Create ShellItems for testing. */
756 SHGetDesktopFolder(&psfdesktop
);
757 hr
= pSHGetIDListFromObject((IUnknown
*)psfdesktop
, &pidl_desktop
);
758 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
761 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop
);
762 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
765 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop2
);
766 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
767 if(FAILED(hr
)) IShellItem_Release(psidesktop
);
769 ILFree(pidl_desktop
);
771 ok(psidesktop
!= psidesktop2
, "psidesktop == psidesktop2\n");
772 IShellFolder_Release(psfdesktop
);
776 win_skip("Test setup failed.\n");
780 CreateFilesFolders();
781 GetCurrentDirectoryW(MAX_PATH
, curdirW
);
782 ok(lstrlenW(curdirW
), "Got 0 length string.\n");
784 lstrcpyW(buf
, curdirW
);
785 myPathAddBackslashW(buf
);
786 lstrcatW(buf
, testdirW
);
787 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitestdir
);
788 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
789 if(FAILED(hr
)) goto cleanup
;
790 lstrcpyW(buf
, curdirW
);
791 myPathAddBackslashW(buf
);
792 lstrcatW(buf
, testdir2W
);
793 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitestdir2
);
794 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
795 if(FAILED(hr
)) goto cleanup
;
796 lstrcpyW(buf
, curdirW
);
797 myPathAddBackslashW(buf
);
798 lstrcatW(buf
, test1W
);
799 hr
= pSHCreateItemFromParsingName(buf
, NULL
, &IID_IShellItem
, (void**)&psitest1
);
800 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
801 if(FAILED(hr
)) goto cleanup
;
803 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
804 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
805 ok(hr
== S_OK
, "Failed to initialize control (0x%08x)\n", hr
);
807 /* Some tests on an uninitialized control */
808 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
809 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
810 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
811 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
812 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, NULL
);
813 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
814 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_NONFOLDERS
, 0, NULL
);
815 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
818 /* Initialize the control */
819 rc
.top
= rc
.left
= 0; rc
.right
= rc
.bottom
= 200;
820 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, &rc
, 0);
821 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
824 /* Set/GetControlStyle(2) */
825 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_INameSpaceTreeControl2
, (void**)&pnstc2
);
826 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
), "Got 0x%08x\n", hr
);
832 static const NSTCSTYLE2 styles2
[] =
833 { NSTCS2_INTERRUPTNOTIFICATIONS
,NSTCS2_SHOWNULLSPACEMENU
,
834 NSTCS2_DISPLAYPADDING
,NSTCS2_DISPLAYPINNEDONLY
,
835 NTSCS2_NOSINGLETONAUTOEXPAND
,NTSCS2_NEVERINSERTNONENUMERATED
, 0};
838 /* We can use this to differentiate between two versions of
839 * this interface. Windows 7 returns hr == S_OK. */
840 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0, 0);
841 ok(hr
== S_OK
|| broken(hr
== E_FAIL
), "Got 0x%08x\n", hr
);
844 static const NSTCSTYLE styles_setable
[] =
845 { NSTCS_HASEXPANDOS
,NSTCS_HASLINES
,NSTCS_SINGLECLICKEXPAND
,
846 NSTCS_FULLROWSELECT
,NSTCS_HORIZONTALSCROLL
,
847 NSTCS_ROOTHASEXPANDO
,NSTCS_SHOWSELECTIONALWAYS
,NSTCS_NOINFOTIP
,
848 NSTCS_EVENHEIGHT
,NSTCS_NOREPLACEOPEN
,NSTCS_DISABLEDRAGDROP
,
849 NSTCS_NOORDERSTREAM
,NSTCS_BORDER
,NSTCS_NOEDITLABELS
,
850 NSTCS_TABSTOP
,NSTCS_FAVORITESMODE
,NSTCS_EMPTYTEXT
,NSTCS_CHECKBOXES
,
851 NSTCS_ALLOWJUNCTIONS
,NSTCS_SHOWTABSBUTTON
,NSTCS_SHOWDELETEBUTTON
,
852 NSTCS_SHOWREFRESHBUTTON
, 0};
853 static const NSTCSTYLE styles_nonsetable
[] =
854 { NSTCS_SPRINGEXPAND
, NSTCS_RICHTOOLTIP
, NSTCS_AUTOHSCROLL
,
855 NSTCS_FADEINOUTEXPANDOS
,
856 NSTCS_PARTIALCHECKBOXES
, NSTCS_EXCLUSIONCHECKBOXES
,
857 NSTCS_DIMMEDCHECKBOXES
, NSTCS_NOINDENTCHECKS
,0};
859 /* Set/GetControlStyle */
860 style
= style2
= 0xdeadbeef;
861 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
862 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
863 ok(style
== 0, "Got style %x\n", style
);
865 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0, 0xFFFFFFF);
866 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
868 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0xFFFFFFFF, 0);
869 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
870 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, 0xFFFFFFFF, 0xFFFFFFFF);
871 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
874 for(i
= 0; styles_setable
[i
] != 0; i
++)
876 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles_setable
[i
], styles_setable
[i
]);
877 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles_setable
[i
]);
878 if(SUCCEEDED(hr
)) tmp
|= styles_setable
[i
];
880 for(i
= 0; styles_nonsetable
[i
] != 0; i
++)
882 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles_nonsetable
[i
], styles_nonsetable
[i
]);
883 ok(hr
== E_FAIL
, "Got 0x%08x (%x)\n", hr
, styles_nonsetable
[i
]);
886 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
887 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
888 ok(style
== tmp
, "Got style %x (expected %x)\n", style
, tmp
);
892 for(i
= 0; styles_setable
[i
] != 0; i
++)
894 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, styles_setable
[i
], &tmp2
);
895 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
896 ok(tmp2
== (style
& styles_setable
[i
]), "Got %x\n", tmp2
);
900 for(i
= 0; styles_setable
[i
] != 0; i
++)
902 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles_setable
[i
], 0);
903 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles_setable
[i
]);
905 for(i
= 0; styles_nonsetable
[i
] != 0; i
++)
907 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles_nonsetable
[i
], 0);
908 ok(hr
== E_FAIL
, "Got 0x%08x (%x)\n", hr
, styles_nonsetable
[i
]);
910 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
911 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
912 ok(style
== 0, "Got style %x\n", style
);
914 /* Set/GetControlStyle2 */
915 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
916 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
917 ok(style2
== 0, "Got style %x\n", style2
);
919 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0, 0);
920 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
921 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0, 0xFFFFFFFF);
922 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
924 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0);
925 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
926 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0xFFFFFFFF);
927 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
929 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFFFFFFFF, 0);
930 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
931 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
932 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
933 ok(style2
== 0x00000000, "Got style %x\n", style2
);
935 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
936 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
937 ok(style2
== 0, "Got style %x\n", style2
);
940 for(i
= 0; styles2
[i
] != 0; i
++)
942 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], styles2
[i
]);
943 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
944 if(SUCCEEDED(hr
)) tmp
|= styles2
[i
];
947 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
948 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
949 ok(style2
== tmp
, "Got style %x (expected %x)\n", style2
, tmp
);
953 for(i
= 0; styles2
[i
] != 0; i
++)
955 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, styles2
[i
], &tmp2
);
956 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
957 ok(tmp2
== (style2
& styles2
[i
]), "Got %x\n", tmp2
);
961 for(i
= 0; styles2
[i
] != 0; i
++)
963 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], 0);
964 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
966 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFF, &style2
);
967 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
968 ok(style2
== 0, "Got style %x (expected 0)\n", style2
);
972 /* 64-bit Windows Vista (others?) seems to have a somewhat
973 * different idea of how the methods of this interface
976 static const NSTCSTYLE styles
[] =
977 { NSTCS_HASEXPANDOS
,NSTCS_HASLINES
,NSTCS_SINGLECLICKEXPAND
,
978 NSTCS_FULLROWSELECT
,NSTCS_SPRINGEXPAND
,NSTCS_HORIZONTALSCROLL
,
979 NSTCS_RICHTOOLTIP
, NSTCS_AUTOHSCROLL
,
980 NSTCS_FADEINOUTEXPANDOS
,
981 NSTCS_PARTIALCHECKBOXES
,NSTCS_EXCLUSIONCHECKBOXES
,
982 NSTCS_DIMMEDCHECKBOXES
, NSTCS_NOINDENTCHECKS
,
983 NSTCS_ROOTHASEXPANDO
,NSTCS_SHOWSELECTIONALWAYS
,NSTCS_NOINFOTIP
,
984 NSTCS_EVENHEIGHT
,NSTCS_NOREPLACEOPEN
,NSTCS_DISABLEDRAGDROP
,
985 NSTCS_NOORDERSTREAM
,NSTCS_BORDER
,NSTCS_NOEDITLABELS
,
986 NSTCS_TABSTOP
,NSTCS_FAVORITESMODE
,NSTCS_EMPTYTEXT
,NSTCS_CHECKBOXES
,
987 NSTCS_ALLOWJUNCTIONS
,NSTCS_SHOWTABSBUTTON
,NSTCS_SHOWDELETEBUTTON
,
988 NSTCS_SHOWREFRESHBUTTON
, 0};
989 trace("Detected broken INameSpaceTreeControl2.\n");
992 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, 0xFFFFFFFF, &style
);
993 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
994 ok(style
== 0xdeadbeef, "Got style %x\n", style
);
996 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
997 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
998 ok(style2
== 0, "Got style %x\n", style2
);
1001 for(i
= 0; styles
[i
] != 0; i
++)
1003 hr
= INameSpaceTreeControl2_SetControlStyle(pnstc2
, styles
[i
], styles
[i
]);
1004 ok(hr
== E_FAIL
|| ((styles
[i
] & NSTCS_SPRINGEXPAND
) && hr
== S_OK
),
1005 "Got 0x%08x (%x)\n", hr
, styles
[i
]);
1006 if(SUCCEEDED(hr
)) tmp
|= styles
[i
];
1010 hr
= INameSpaceTreeControl2_GetControlStyle(pnstc2
, tmp
, &style
);
1011 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1012 ok(style
== 0xdeadbeef, "Got style %x\n", style
);
1015 for(i
= 0; styles2
[i
] != 0; i
++)
1017 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, styles2
[i
], styles2
[i
]);
1018 ok(hr
== S_OK
, "Got 0x%08x (%x)\n", hr
, styles2
[i
]);
1019 if(SUCCEEDED(hr
)) tmp
|= styles2
[i
];
1022 style2
= 0xdeadbeef;
1023 hr
= INameSpaceTreeControl2_GetControlStyle2(pnstc2
, 0xFFFFFFFF, &style2
);
1024 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1025 ok(style2
== tmp
, "Got style %x\n", style2
);
1029 INameSpaceTreeControl2_Release(pnstc2
);
1033 skip("INameSpaceTreeControl2 missing.\n");
1036 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, NULL
);
1037 ok(hr
== E_NOINTERFACE
, "Got (0x%08x)\n", hr
);
1039 /* Append / Insert root */
1042 /* Crashes under Windows 7 */
1043 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, NULL
, SHCONTF_FOLDERS
, 0, NULL
);
1044 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 0, NULL
, SHCONTF_FOLDERS
, 0, NULL
);
1047 /* Note the usage of psidesktop and psidesktop2 */
1048 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1049 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1050 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1051 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1052 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop2
, SHCONTF_FOLDERS
, 0, NULL
);
1053 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1056 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1057 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1058 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1059 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1060 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1061 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1063 hr
= INameSpaceTreeControl_RemoveRoot(pnstc
, psidesktop
);
1064 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1065 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1066 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
1068 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1069 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1070 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1071 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1073 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 0, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1074 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1075 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1076 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1077 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1078 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1079 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 50, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1080 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1081 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 1, psidesktop
, SHCONTF_FOLDERS
, 0, NULL
);
1082 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1084 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1085 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1090 /* Crashes on native. */
1091 hr
= INameSpaceTreeControl_GetRootItems(pnstc
, NULL
);
1094 hr
= INameSpaceTreeControl_GetRootItems(pnstc
, &psia
);
1095 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
1097 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, 0, 0, NULL
);
1098 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1099 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop2
, 0, 0, NULL
);
1100 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1101 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
, 0, 0, NULL
);
1102 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1103 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, 0, 0, NULL
);
1104 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1106 roots
[0] = psidesktop
;
1107 roots
[1] = psidesktop2
;
1108 roots
[2] = psitestdir
;
1109 roots
[3] = psitestdir2
;
1111 verify_root_order(pnstc
, roots
);
1113 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 0, psitestdir2
, 0, 0, NULL
);
1114 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1116 roots
[0] = psitestdir2
;
1117 roots
[1] = psidesktop
;
1118 roots
[2] = psidesktop2
;
1119 roots
[3] = psitestdir
;
1120 roots
[4] = psitestdir2
;
1122 verify_root_order(pnstc
, roots
);
1124 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 5, psidesktop
, 0, 0, NULL
);
1125 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1127 roots
[5] = psidesktop
;
1129 verify_root_order(pnstc
, roots
);
1131 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, 3, psitestdir2
, 0, 0, NULL
);
1132 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1134 roots
[3] = psitestdir2
;
1135 roots
[4] = psitestdir
;
1136 roots
[5] = psitestdir2
;
1137 roots
[6] = psidesktop
;
1139 verify_root_order(pnstc
, roots
);
1141 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, 0, 0, NULL
);
1142 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1144 roots
[7] = psitestdir2
;
1146 verify_root_order(pnstc
, roots
);
1148 hr
= INameSpaceTreeControl_InsertRoot(pnstc
, -1, psidesktop
, 0, 0, NULL
);
1149 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1151 roots
[0] = psidesktop
;
1152 roots
[1] = psitestdir2
;
1153 roots
[2] = psidesktop
;
1154 roots
[3] = psidesktop2
;
1155 roots
[4] = psitestdir2
;
1156 roots
[5] = psitestdir
;
1157 roots
[6] = psitestdir2
;
1158 roots
[7] = psidesktop
;
1159 roots
[8] = psitestdir2
;
1161 verify_root_order(pnstc
, roots
);
1164 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
1165 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1167 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1168 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1170 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
1171 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1173 /* SetItemState message checks */
1174 res
= subclass_treeview(pnstc
);
1175 ok(res
, "Failed to subclass treeview.\n");
1178 UINT isMask
, isFlags
;
1180 hr
= INameSpaceTreeControl_AppendRoot(
1181 pnstc
, psidesktop
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, 0, NULL
);
1182 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1183 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1186 * The first expansion results in an "unrelated" TVM_SETITEMW being sent
1187 * (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) )
1190 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
1191 NSTCIS_EXPANDED
, NSTCIS_EXPANDED
);
1192 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1195 ok(tvi_count
== 1, "Got %d\n", tvi_count
);
1196 ok(last_tvi
.mask
== 0x50, "Got mask %x, expected 0x50\n", last_tvi
.mask
);
1200 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
1201 NSTCIS_EXPANDED
, NSTCIS_EXPANDED
);
1202 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1203 ok(tvi_count
== 0, "Got %d\n", tvi_count
);
1205 /* Test all the combinations of NSTCIS_SELECTED to NSTCIS_SELECTEDNOEXPAND */
1206 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1207 for(isMask
= 0; isMask
<= 0x1f; isMask
++)
1209 for(isFlags
= 0; isFlags
<= 0x1f; isFlags
++)
1211 UINT select_sent
, select_sent_vista
, ensurev_sent
, expand_sent
;
1215 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1218 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, isMask
, isFlags
);
1219 ok(hr
== S_OK
, "(%x|%x)Got 0x%08x\n", isMask
, isFlags
, hr
);
1221 /*****************************/
1222 /* Calculate expected values */
1223 /*****************************/
1225 /* Number of TVM_SELECTITEM/TVM_ENSUREVISIBLE and TVM_EXPAND sent */
1226 select_sent
= ((isMask
&isFlags
) & NSTCIS_SELECTED
)?1:0;
1227 select_sent_vista
= ensurev_sent
= select_sent
;
1229 select_sent
+= ((isMask
&isFlags
) & NSTCIS_SELECTEDNOEXPAND
)?1:0;
1230 select_sent_vista
+= ((isMask
&isFlags
) & NSTCIS_EXPANDED
)?1:0;
1231 expand_sent
= ((isMask
|isFlags
) & NSTCIS_EXPANDED
)?1:0;
1233 /* Possible TWM_SETITEMW message and its contents */
1234 if(isMask
& NSTCIS_DISABLED
)
1235 tviexp
.mask
= TVIF_STATE
| TVIF_STATEEX
;
1236 else if( ((isMask
^isFlags
) & (NSTCIS_SELECTED
|NSTCIS_EXPANDED
|NSTCIS_SELECTEDNOEXPAND
)) ||
1237 ((isMask
|isFlags
) & NSTCIS_BOLD
) || (isFlags
& NSTCIS_DISABLED
) )
1238 tviexp
.mask
= TVIF_STATE
;
1244 tviexp
.stateMask
= tviexp
.state
= 0;
1245 tviexp
.stateMask
|= ((isMask
^isFlags
)&NSTCIS_SELECTED
) ? TVIS_SELECTED
: 0;
1246 tviexp
.stateMask
|= (isMask
|isFlags
)&NSTCIS_BOLD
? TVIS_BOLD
:0;
1247 tviexp
.state
|= (isMask
&isFlags
)&NSTCIS_BOLD
? TVIS_BOLD
:0;
1249 if((isMask
&NSTCIS_EXPANDED
)^(isFlags
&NSTCIS_EXPANDED
))
1251 tviexp
.stateMask
= 0;
1254 tviexp
.uStateEx
= (isFlags
&isMask
)&NSTCIS_DISABLED
?TVIS_EX_DISABLED
:0;
1258 /* Make sure that no tests accidentally succeeded
1259 * (and avoid a gcc warning) */
1260 tviexp
.stateMask
= tviexp
.state
= tviexp
.uStateEx
= -1;
1263 /*****************************/
1264 /* Check the values. */
1265 /*****************************/
1267 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_SELECTITEM
);
1268 ok(msg_count
== select_sent
|| broken(msg_count
== select_sent_vista
),
1269 "(%x|%x) Got msg_count %d, expected %d (%d)\n",
1270 isMask
, isFlags
, msg_count
, select_sent
, select_sent_vista
);
1271 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_ENSUREVISIBLE
);
1272 ok(msg_count
== ensurev_sent
|| broken(msg_count
== 0 /* Vista */),
1273 "(%x|%x) Got msg_count %d, expected %d\n",
1274 isMask
, isFlags
, msg_count
, ensurev_sent
);
1275 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_EXPAND
);
1276 ok(msg_count
== expand_sent
, "(%x|%x) Got msg_count %d, expected %d\n",
1277 isMask
, isFlags
, msg_count
, expand_sent
);
1279 msg_count
= get_msg_count(sequences
, TREEVIEW_SEQ_INDEX
, TVM_SETITEMW
);
1282 /* Four special cases for vista */
1283 BOOL vista_check
= ( (isMask
== 0x10 && isFlags
== 0x10) ||
1284 (isMask
== 0x11 && isFlags
== 0x11) ||
1285 (isMask
== 0x12 && isFlags
== 0x12) ||
1286 (isMask
== 0x13 && isFlags
== 0x13) );
1288 ok(msg_count
== 0 || broken(msg_count
== 1 && vista_check
),
1289 "(%x|%x) Got msg_count %d (tviexp.mask %x)\n",
1290 isMask
, isFlags
, msg_count
, tviexp
.mask
);
1294 ok(msg_count
== 1, "(%x|%x) Got msg_count %d, expected 1\n",
1295 isMask
, isFlags
, msg_count
);
1296 ok(last_tvi
.mask
== tviexp
.mask
,
1297 "(%x|%x) Got mask %x, expected %x\n",
1298 isMask
, isFlags
, last_tvi
.mask
, tviexp
.mask
);
1299 ok(last_tvi
.stateMask
== tviexp
.stateMask
,
1300 "(%x|%x) Got stateMask %x, expected %x\n",
1301 isMask
, isFlags
, last_tvi
.stateMask
, tviexp
.stateMask
);
1302 ok(last_tvi
.state
== tviexp
.state
,
1303 "(%x|%x) Got state %x, expected %x\n",
1304 isMask
, isFlags
, last_tvi
.state
, tviexp
.state
);
1305 ok(last_tvi
.uStateEx
== tviexp
.uStateEx
,
1306 "(%x|%x) Got uStateEx %x, expected %x\n",
1307 isMask
, isFlags
, last_tvi
.uStateEx
, tviexp
.uStateEx
);
1311 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1312 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1315 /* GetSelectedItems */
1318 /* Crashes under Windows 7 */
1319 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, NULL
);
1322 psia
= (void*)0xdeadbeef;
1323 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1324 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1325 ok(psia
== (void*)0xdeadbeef, "Got %p\n", psia
);
1327 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
, SHCONTF_FOLDERS
, 0, NULL
);
1328 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1331 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
, SHCONTF_FOLDERS
, 0, NULL
);
1332 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1335 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitestdir
,
1336 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1337 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1339 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1340 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1344 hr
= IShellItemArray_GetCount(psia
, &count
);
1345 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1346 ok(count
== 1, "Got %d selected items.\n", count
);
1349 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1350 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1354 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1355 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1356 IShellItem_Release(psi
);
1359 IShellItemArray_Release(psia
);
1362 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitestdir2
,
1363 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1364 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1367 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1368 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1372 hr
= IShellItemArray_GetCount(psia
, &count
);
1373 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1374 ok(count
== 1, "Got %d selected items.\n", count
);
1377 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1378 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1382 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1383 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1384 IShellItem_Release(psi
);
1387 IShellItemArray_Release(psia
);
1390 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psitest1
,
1391 NSTCIS_SELECTED
, NSTCIS_SELECTED
);
1392 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1393 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1394 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1398 hr
= IShellItemArray_GetCount(psia
, &count
);
1399 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1400 ok(count
== 1, "Got %d selected items.\n", count
);
1403 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1404 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1408 hr
= IShellItem_Compare(psi
, psitest1
, SICHINT_DISPLAY
, &cmp
);
1409 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1410 IShellItem_Release(psi
);
1413 IShellItemArray_Release(psia
);
1416 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1417 ok(hr
== S_OK
|| broken(hr
== E_FAIL
), "Got 0x%08x\n", hr
);
1420 /* For some reason, Vista fails to properly remove both the
1421 * roots here on the first try. */
1422 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1423 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1426 /* Adding without NSTCRS_EXPANDED does not set the selection */
1427 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1428 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1430 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1433 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir
, 0xFF, &istate
);
1434 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1435 ok(!(istate
& NSTCIS_SELECTED
), "Got 0x%08x\n", istate
);
1436 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1437 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1438 if(SUCCEEDED(hr
)) IShellItemArray_Release(psia
);
1440 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1441 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1443 /* Adding with NSTCRS_EXPANDED sets the selection */
1444 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1445 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1446 NSTCRS_EXPANDED
, NULL
);
1447 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1450 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir
, 0xFF, &istate
);
1451 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1452 todo_wine
ok(istate
& NSTCIS_SELECTED
, "Got 0x%08x\n", istate
);
1453 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1454 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1459 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1463 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1464 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1466 IShellItem_Release(psi
);
1469 IShellItemArray_Release(psia
);
1472 /* Adding a second root with NSTCRS_EXPANDED does not change the selection */
1473 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir2
,
1474 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1475 NSTCRS_EXPANDED
, NULL
);
1476 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1479 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psitestdir2
, 0xFF, &istate
);
1480 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1481 ok(!(istate
& NSTCIS_SELECTED
), "Got 0x%08x\n", istate
);
1482 hr
= INameSpaceTreeControl_GetSelectedItems(pnstc
, &psia
);
1483 todo_wine
ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1488 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
1492 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1493 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1495 IShellItem_Release(psi
);
1498 IShellItemArray_Release(psia
);
1501 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1502 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1505 rc
.top
= rc
.left
= rc
.bottom
= rc
.right
= 0;
1508 /* Crashes under win 7 */
1509 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, NULL
, NULL
);
1510 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, NULL
);
1511 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, NULL
, &rc
);
1514 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, &rc
);
1515 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
1517 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1518 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1519 NSTCRS_EXPANDED
, NULL
);
1520 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1523 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir
, &rc
);
1524 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1525 ok(rc
.top
!= rc
.bottom
, "Got 0 height.\n");
1526 ok(rc
.left
!= rc
.bottom
, "Got 0 width.\n");
1529 hwnd_tv
= get_treeview_hwnd(pnstc
);
1532 HTREEITEM hroot
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_ROOT
, 0);
1533 ok(hroot
!= NULL
, "Failed to get root.\n");
1539 *(HTREEITEM
*)&tv_rc
= hroot
;
1540 bret
= SendMessageW(hwnd_tv
, TVM_GETITEMRECT
, FALSE
, (LPARAM
)&tv_rc
);
1541 ok(bret
, "TVM_GETITEMRECT failed.\n");
1543 /* The NamespaceTreeControl returns screen coordinates. */
1544 MapWindowPoints(NULL
, hwnd
, (POINT
*)&rc
, 2);
1545 ok(rc
.left
== tv_rc
.left
, "Differed, got %d and %d\n", rc
.left
, tv_rc
.left
);
1546 ok(rc
.top
== tv_rc
.top
, "Differed, got %d and %d\n", rc
.top
, tv_rc
.top
);
1547 ok(rc
.right
== tv_rc
.right
, "Differed, got %d and %d\n", rc
.right
, tv_rc
.right
);
1548 ok(rc
.bottom
== tv_rc
.bottom
, "Differed, got %d and %d\n", rc
.bottom
, tv_rc
.bottom
);
1550 /* Save the height and compare to that of other items.
1551 Observed values: 18, 19, 21 */
1552 height
= rc
.bottom
- rc
.top
;
1553 trace("height: %d\n", height
);
1557 win_skip("Skipping some GetItemRect tests.\n");
1559 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1560 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1563 hr
= INameSpaceTreeControl_HitTest(pnstc
, NULL
, NULL
);
1564 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1565 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, NULL
);
1566 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1567 hr
= INameSpaceTreeControl_HitTest(pnstc
, NULL
, &psi
);
1568 ok(hr
== E_POINTER
, "Got 0x%08x\n", hr
);
1570 psi
= (void*)0xdeadbeef;
1571 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1572 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
1573 ok(psi
== NULL
, "Got psi %p\n", psi
);
1575 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1576 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1577 NSTCRS_EXPANDED
, NULL
);
1578 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1582 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1583 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1587 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1588 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1589 ok(!cmp
, "Got cmp %d\n", cmp
);
1590 IShellItem_Release(psi
);
1594 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1595 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1599 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1600 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1601 ok(!cmp
, "Got cmp %d\n", cmp
);
1602 IShellItem_Release(psi
);
1606 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1607 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1613 hr
= IShellItem_Compare(psi
, psitestdir
, SICHINT_DISPLAY
, &cmp
);
1614 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
1615 ok(cmp
, "no cmp value.\n");
1616 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1617 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1618 ok(!cmp
, "Got cmp %d\n", cmp
);
1620 IShellItem_Release(psi
);
1623 hr
= INameSpaceTreeControl_GetItemRect(pnstc
, psitestdir2
, &rc
);
1624 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1627 MapWindowPoints(NULL
, hwnd
, (POINT
*)&rc
, 2);
1628 pt
.x
= rc
.left
; pt
.y
= rc
.top
;
1630 hr
= INameSpaceTreeControl_HitTest(pnstc
, &pt
, &psi
);
1631 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1635 hr
= IShellItem_Compare(psi
, psitestdir2
, SICHINT_DISPLAY
, &cmp
);
1636 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1637 ok(!cmp
, "Got cmp %d\n", cmp
);
1638 IShellItem_Release(psi
);
1642 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1643 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1645 /* GetItemCustomState / SetItemCustomState */
1648 /* Crashes under Windows 7 */
1649 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, NULL
, NULL
);
1650 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, NULL
, &cbstate
);
1651 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, NULL
);
1652 hr
= INameSpaceTreeControl_SetItemCustomState(pnstc
, NULL
, 0);
1655 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psitestdir
,
1656 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
,
1659 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1664 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1665 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1666 ok(cbstate
== BST_UNCHECKED
|| broken(cbstate
== BST_CHECKED
/* Vista x64 */),
1667 "Got %d\n", cbstate
);
1669 hr
= INameSpaceTreeControl_SetItemCustomState(pnstc
, psitestdir
, BST_CHECKED
);
1670 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1673 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1674 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1675 ok(cbstate
== BST_CHECKED
, "Got %d\n", cbstate
);
1677 hr
= INameSpaceTreeControl_SetItemCustomState(pnstc
, psitestdir
, 0xFFF);
1678 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1681 hr
= INameSpaceTreeControl_GetItemCustomState(pnstc
, psitestdir
, &cbstate
);
1682 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1683 ok(cbstate
== 0xF, "Got %d\n", cbstate
);
1689 hr
= INameSpaceTreeControl_SetTheme(pnstc
, NULL
);
1690 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1691 hr
= INameSpaceTreeControl_SetTheme(pnstc
, explorerW
);
1692 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1693 hr
= INameSpaceTreeControl_SetTheme(pnstc
, randomW
);
1694 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1697 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1698 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1700 IShellItem_Release(psidesktop
);
1701 IShellItem_Release(psidesktop2
);
1702 IShellItem_Release(psitestdir
);
1703 IShellItem_Release(psitestdir2
);
1704 IShellItem_Release(psitest1
);
1706 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
1707 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1711 hr
= IOleWindow_GetWindow(pow
, &hwnd_nstc
);
1712 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1713 DestroyWindow(hwnd_nstc
);
1714 IOleWindow_Release(pow
);
1717 res
= INameSpaceTreeControl_Release(pnstc
);
1718 ok(!res
, "res was %d!\n", res
);
1724 static void test_events(void)
1726 INameSpaceTreeControl
*pnstc
;
1727 INameSpaceTreeControlEventsImpl
*pnstceimpl
, *pnstceimpl2
;
1728 INameSpaceTreeControlEvents
*pnstce
, *pnstce2
;
1729 IShellFolder
*psfdesktop
;
1730 IShellItem
*psidesktop
;
1732 LPITEMIDLIST pidl_desktop
;
1733 LPITEMIDLIST pidl_drives
;
1734 NSTCITEMSTATE itemstate
;
1736 DWORD cookie1
, cookie2
;
1741 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
1742 &IID_INameSpaceTreeControl
, (void**)&pnstc
);
1743 ok(hr
== S_OK
, "Failed to initialize control (0x%08x)\n", hr
);
1745 ok(pSHCreateShellItem
!= NULL
, "No SHCreateShellItem.\n");
1746 ok(pSHGetIDListFromObject
!= NULL
, "No SHCreateShellItem.\n");
1748 SHGetDesktopFolder(&psfdesktop
);
1749 hr
= pSHGetIDListFromObject((IUnknown
*)psfdesktop
, &pidl_desktop
);
1750 IShellFolder_Release(psfdesktop
);
1751 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1752 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psidesktop
);
1753 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1754 ILFree(pidl_desktop
);
1756 /* Create two instances of INameSpaceTreeControlEvents */
1757 pnstceimpl
= create_nstc_events();
1758 pnstce
= (INameSpaceTreeControlEvents
*)pnstceimpl
;
1759 ZeroMemory(&pnstceimpl
->count
, sizeof(UINT
)*LastEvent
);
1760 pnstceimpl2
= create_nstc_events();
1761 pnstce2
= (INameSpaceTreeControlEvents
*)pnstceimpl2
;
1765 /* Crashes native */
1766 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, NULL
, NULL
);
1767 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, NULL
, &cookie1
);
1768 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, NULL
);
1771 /* TreeAdvise in NameSpaceTreeController seems to support only one
1772 * client at the time.
1775 /* First, respond with E_NOINTERFACE to all QI's */
1776 pnstceimpl
->qi_enable_events
= FALSE
;
1777 pnstceimpl
->qi_called_count
= 0;
1778 cookie1
= 0xDEADBEEF;
1779 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie1
);
1780 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1781 ok(cookie1
== 0, "cookie now (0x%08x)\n", cookie1
);
1784 ok(pnstceimpl
->qi_called_count
== 7 || pnstceimpl
->qi_called_count
== 4 /* Vista */,
1785 "QueryInterface called %d times.\n",
1786 pnstceimpl
->qi_called_count
);
1788 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1790 /* Accept query for IID_INameSpaceTreeControlEvents */
1791 pnstceimpl
->qi_enable_events
= TRUE
;
1792 pnstceimpl
->qi_called_count
= 0;
1793 cookie1
= 0xDEADBEEF;
1794 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie1
);
1795 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1796 ok(cookie1
== 1, "cookie now (0x%08x)\n", cookie1
);
1799 ok(pnstceimpl
->qi_called_count
== 7 || pnstceimpl
->qi_called_count
== 4 /* Vista */,
1800 "QueryInterface called %d times.\n",
1801 pnstceimpl
->qi_called_count
);
1803 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1805 /* A second time, query interface will not be called at all. */
1806 pnstceimpl
->qi_enable_events
= TRUE
;
1807 pnstceimpl
->qi_called_count
= 0;
1808 cookie2
= 0xDEADBEEF;
1809 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie2
);
1810 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1811 ok(cookie2
== 0, "cookie now (0x%08x)\n", cookie2
);
1812 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1813 pnstceimpl
->qi_called_count
);
1814 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1816 /* Using another "instance" does not help. */
1817 pnstceimpl2
->qi_enable_events
= TRUE
;
1818 pnstceimpl2
->qi_called_count
= 0;
1819 cookie2
= 0xDEADBEEF;
1820 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce2
, &cookie2
);
1821 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
1822 ok(cookie2
== 0, "cookie now (0x%08x)\n", cookie2
);
1823 ok(!pnstceimpl2
->qi_called_count
, "QueryInterface called %d times.\n",
1824 pnstceimpl2
->qi_called_count
);
1825 ok(pnstceimpl2
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1827 /* Unadvise with bogus cookie (will actually unadvise properly) */
1828 pnstceimpl
->qi_enable_events
= TRUE
;
1829 pnstceimpl
->qi_called_count
= 0;
1830 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, 1234);
1831 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1832 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1833 pnstceimpl
->qi_called_count
);
1834 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1836 /* Unadvise "properly" (will have no additional effect) */
1837 pnstceimpl
->qi_enable_events
= TRUE
;
1838 pnstceimpl
->qi_called_count
= 0;
1839 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, cookie1
);
1840 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1841 ok(!pnstceimpl
->qi_called_count
, "QueryInterface called %d times.\n",
1842 pnstceimpl
->qi_called_count
);
1843 ok(pnstceimpl
->ref
== 1, "refcount was %d\n", pnstceimpl
->ref
);
1845 /* Advise again.. */
1846 pnstceimpl
->qi_enable_events
= 1;
1847 pnstceimpl
->qi_called_count
= 0;
1848 hr
= INameSpaceTreeControl_TreeAdvise(pnstc
, (IUnknown
*)pnstce
, &cookie2
);
1849 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1850 ok(cookie2
== 1, "Cookie is %d\n", cookie2
);
1851 ok(cookie1
== cookie2
, "Old cookie differs from old cookie.\n");
1854 ok(pnstceimpl
->qi_called_count
== 7 || pnstceimpl
->qi_called_count
== 4 /* Vista */,
1855 "QueryInterface called %d times.\n",
1856 pnstceimpl
->qi_called_count
);
1858 ok(pnstceimpl
->ref
== 2, "refcount was %d\n", pnstceimpl
->ref
);
1860 /* Initialize the control */
1861 hr
= INameSpaceTreeControl_Initialize(pnstc
, hwnd
, NULL
, 0);
1862 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1863 ok_no_events(pnstceimpl
);
1865 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
1866 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
1867 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1869 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
1870 ok_event_count(pnstceimpl
, OnGetDefaultIconIndex
, 0);
1871 ok_no_events(pnstceimpl
);
1873 hwnd_tv
= get_treeview_hwnd(pnstc
);
1874 ok(hwnd_tv
!= NULL
, "Failed to get hwnd_tv HWND.\n");
1877 HTREEITEM hroot
, hitem
;
1879 static const UINT kbd_msgs_event
[] = {
1880 WM_KEYDOWN
, WM_KEYUP
, WM_CHAR
, WM_SYSKEYDOWN
, WM_SYSKEYUP
,
1882 static const UINT kbd_msgs_noevent
[] ={
1883 WM_DEADCHAR
, WM_SYSDEADCHAR
, WM_UNICHAR
, 0 };
1885 /* Test On*Expand */
1886 hroot
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_ROOT
, 0);
1887 SendMessage(hwnd_tv
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)hroot
);
1889 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
1890 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
1891 ok_event_broken(pnstceimpl
, OnItemAdded
); /* No event on Vista */
1892 todo_wine
ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
1893 ok_no_events(pnstceimpl
);
1894 SendMessage(hwnd_tv
, TVM_EXPAND
, TVE_COLLAPSE
, (LPARAM
)hroot
);
1896 ok_no_events(pnstceimpl
);
1897 SendMessage(hwnd_tv
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)hroot
);
1899 ok_no_events(pnstceimpl
);
1901 /* Test OnSelectionChanged */
1902 hitem
= (HTREEITEM
)SendMessageW(hwnd_tv
, TVM_GETNEXTITEM
, TVGN_CHILD
, (LPARAM
)hroot
);
1903 SendMessageW(hwnd_tv
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
)hitem
);
1905 ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
1906 ok_no_events(pnstceimpl
);
1908 /* Test OnKeyboardInput */
1909 for(i
= 0; kbd_msgs_event
[i
] != 0; i
++)
1911 SendMessageW(hwnd_tv
, kbd_msgs_event
[i
], 0x1234, 0x1234);
1912 ok(pnstceimpl
->count
[OnKeyboardInput
] == 1,
1913 "%d (%x): Got count %d\n",
1914 kbd_msgs_event
[i
], kbd_msgs_event
[i
], pnstceimpl
->count
[OnKeyboardInput
]);
1915 pnstceimpl
->count
[OnKeyboardInput
] = 0;
1918 for(i
= 0; kbd_msgs_noevent
[i
] != 0; i
++)
1920 SendMessageW(hwnd_tv
, kbd_msgs_noevent
[i
], 0x1234, 0x1234);
1921 ok(pnstceimpl
->count
[OnKeyboardInput
] == 0,
1922 "%d (%x): Got count %d\n",
1923 kbd_msgs_noevent
[i
], kbd_msgs_noevent
[i
], pnstceimpl
->count
[OnKeyboardInput
]);
1924 pnstceimpl
->count
[OnKeyboardInput
] = 0;
1926 ok_no_events(pnstceimpl
);
1929 skip("Skipping some tests.\n");
1931 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1933 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1934 ok_event(pnstceimpl
, OnItemDeleted
);
1935 ok_no_events(pnstceimpl
);
1937 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
1938 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
1939 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1941 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
1942 ok_no_events(pnstceimpl
);
1944 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
1945 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1946 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
1948 ok_no_events(pnstceimpl
);
1950 /* Expand the root */
1951 itemstate
|= NSTCIS_EXPANDED
;
1952 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, itemstate
);
1953 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1955 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
1956 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
1957 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
1960 ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /* Vista*/);
1962 ok_no_events(pnstceimpl
);
1964 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
1965 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1966 ok(itemstate
& NSTCIS_EXPANDED
, "Item not expanded.\n");
1969 ok(itemstate
== (NSTCIS_SELECTED
| NSTCIS_EXPANDED
)||
1970 broken(itemstate
== NSTCIS_EXPANDED
) /* Vista */,
1971 "itemstate is 0x%08x\n", itemstate
);
1973 ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /* Vista*/);
1975 ok_no_events(pnstceimpl
);
1977 /* Deselect the root */
1978 itemstate
&= ~NSTCIS_SELECTED
;
1979 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, itemstate
);
1980 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1982 ok_no_events(pnstceimpl
);
1984 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
1985 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1986 ok(itemstate
== (NSTCIS_EXPANDED
), "itemstate is 0x%08x\n", itemstate
);
1987 ok_no_events(pnstceimpl
);
1989 hr
= INameSpaceTreeControl_CollapseAll(pnstc
);
1990 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1991 ok_no_events(pnstceimpl
);
1993 /* Delete all roots */
1994 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
1995 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
1996 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
1997 ok_no_events(pnstceimpl
);
1999 /* Get/SetItemState */
2002 /* Crashes on Windows 7 */
2003 hr
= INameSpaceTreeControl_SetItemState(pnstc
, NULL
, 0, 0);
2004 hr
= INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, NULL
);
2005 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0, NULL
);
2006 hr
= INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, &itemstate
);
2007 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0, NULL
);
2008 hr
= INameSpaceTreeControl_GetItemState(pnstc
, NULL
, 0, &itemstate
);
2011 itemstate
= 0xDEADBEEF;
2012 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2013 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2014 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2015 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2016 ok_no_events(pnstceimpl
);
2018 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
,
2019 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2020 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2022 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2023 ok_no_events(pnstceimpl
);
2025 itemstate
= 0xDEADBEEF;
2026 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2027 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2028 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2029 ok_no_events(pnstceimpl
);
2031 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0, 0xffff);
2032 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2036 ok_event_count(pnstceimpl
, OnBeforeExpand
, 0);
2037 ok_event_count(pnstceimpl
, OnAfterExpand
, 0);
2038 ok_event_count(pnstceimpl
, OnItemAdded
, 0);
2040 ok_no_events(pnstceimpl
);
2042 itemstate
= 0xDEADBEEF;
2043 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2044 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2046 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2047 ok_no_events(pnstceimpl
);
2049 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2050 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2052 ok_no_events(pnstceimpl
);
2054 itemstate
= 0xDEADBEEF;
2055 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2056 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2057 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2058 ok_no_events(pnstceimpl
);
2060 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_SELECTED
);
2061 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2063 ok_event_count(pnstceimpl
, OnSelectionChanged
, 1);
2064 ok_no_events(pnstceimpl
);
2066 itemstate
= 0xDEADBEEF;
2067 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2068 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2069 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2070 ok_no_events(pnstceimpl
);
2072 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_EXPANDED
, NSTCIS_SELECTED
);
2073 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2075 ok_no_events(pnstceimpl
);
2077 itemstate
= 0xDEADBEEF;
2078 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2079 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2080 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2081 ok_no_events(pnstceimpl
);
2083 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2084 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2086 ok_no_events(pnstceimpl
);
2088 itemstate
= 0xDEADBEEF;
2089 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2090 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2091 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2092 ok_no_events(pnstceimpl
);
2094 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_SELECTEDNOEXPAND
);
2095 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2097 ok_no_events(pnstceimpl
);
2099 itemstate
= 0xDEADBEEF;
2100 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2101 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2102 ok(itemstate
== NSTCIS_SELECTED
, "itemstate is 0x%08x\n", itemstate
);
2103 ok_no_events(pnstceimpl
);
2105 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, NSTCIS_EXPANDED
);
2106 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2110 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
2111 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
2112 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
2114 ok_no_events(pnstceimpl
);
2116 itemstate
= 0xDEADBEEF;
2117 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2118 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2119 ok(itemstate
== NSTCIS_EXPANDED
, "itemstate is 0x%08x\n", itemstate
);
2120 ok_no_events(pnstceimpl
);
2122 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0);
2123 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2125 ok_no_events(pnstceimpl
);
2127 itemstate
= 0xDEADBEEF;
2128 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2129 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2130 ok(itemstate
== NSTCIS_NONE
, "itemstate is 0x%08x\n", itemstate
);
2131 ok_no_events(pnstceimpl
);
2133 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff, 0xffff);
2134 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2136 ok_no_events(pnstceimpl
);
2138 itemstate
= 0xDEADBEEF;
2139 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2140 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2143 ok(itemstate
== (NSTCIS_EXPANDED
| NSTCIS_BOLD
| NSTCIS_DISABLED
),
2144 "itemstate is 0x%08x\n", itemstate
);
2146 ok_no_events(pnstceimpl
);
2148 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_SELECTED
, NSTCIS_SELECTED
);
2149 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2151 ok_no_events(pnstceimpl
);
2153 itemstate
= 0xDEADBEEF;
2154 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2155 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2158 ok(itemstate
== (NSTCIS_EXPANDED
| NSTCIS_BOLD
| NSTCIS_DISABLED
),
2159 "itemstate is 0x%08x\n", itemstate
);
2161 ok_no_events(pnstceimpl
);
2163 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
,
2164 NSTCIS_SELECTED
| NSTCIS_DISABLED
, 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
);
2172 ok(itemstate
== (NSTCIS_BOLD
| NSTCIS_EXPANDED
),
2173 "itemstate is 0x%08x\n", itemstate
);
2174 ok_no_events(pnstceimpl
);
2176 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_SELECTED
, NSTCIS_SELECTED
);
2177 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2179 ok_no_events(pnstceimpl
);
2181 itemstate
= 0xDEADBEEF;
2182 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2183 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2184 ok(itemstate
== (NSTCIS_BOLD
| NSTCIS_EXPANDED
),
2185 "itemstate is 0x%08x\n", itemstate
);
2186 ok_no_events(pnstceimpl
);
2188 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, 0xffff & ~NSTCIS_DISABLED
, 0);
2189 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2191 ok_no_events(pnstceimpl
);
2193 itemstate
= 0xDEADBEEF;
2194 hr
= INameSpaceTreeControl_GetItemState(pnstc
, psidesktop
, 0xffff, &itemstate
);
2195 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2196 ok(itemstate
== (NSTCIS_BOLD
), "itemstate is 0x%08x\n", itemstate
);
2197 ok_no_events(pnstceimpl
);
2199 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2200 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2201 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
2202 ok_no_events(pnstceimpl
);
2205 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, NULL
, 0, NULL
);
2206 ok(hr
== E_POINTER
, "Got (0x%08x)\n", hr
);
2207 ok_no_events(pnstceimpl
);
2209 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, 0, NULL
);
2210 ok(hr
== E_POINTER
, "Got (0x%08x)\n", hr
);
2211 ok_no_events(pnstceimpl
);
2213 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, NULL
, 0, &psi
);
2214 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2215 ok_no_events(pnstceimpl
);
2217 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, 0, &psi
);
2218 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2219 ok_no_events(pnstceimpl
);
2221 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2222 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2224 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2225 ok_no_events(pnstceimpl
);
2227 /* Get child from unexpanded and unfilled parent */
2228 psi
= (void*)0xDEADBEEF;
2229 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, NSTCGNI_CHILD
, &psi
);
2230 ok(hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2231 ok(psi
== NULL
, "psi is %p\n", psi
);
2233 ok_no_events(pnstceimpl
);
2235 /* Expand and try again */
2236 hr
= INameSpaceTreeControl_SetItemState(pnstc
, psidesktop
, NSTCIS_EXPANDED
, 0xffff);
2237 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2239 ok_event_count(pnstceimpl
, OnBeforeExpand
, 1);
2240 ok_event_broken(pnstceimpl
, OnItemAdded
); /* Does not fire on Vista */
2241 ok_event_count(pnstceimpl
, OnAfterExpand
, 1);
2242 todo_wine
ok_event_count_broken(pnstceimpl
, OnSelectionChanged
, 1, 0 /*Vista */);
2243 ok_no_events(pnstceimpl
);
2244 psi
= (void*)0xDEADBEEF;
2245 hr
= INameSpaceTreeControl_GetNextItem(pnstc
, psidesktop
, NSTCGNI_CHILD
, &psi
);
2246 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2247 ok((psi
!= NULL
) && (psi
!= (void*)0xDEADBEEF), "psi is %p\n", psi
);
2249 ok_no_events(pnstceimpl
);
2250 if(SUCCEEDED(hr
)) IShellItem_Release(psi
);
2252 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2253 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2254 ok_event_count(pnstceimpl
, OnItemDeleted
, 1);
2255 ok_no_events(pnstceimpl
);
2257 /* EnsureItemVisible */
2260 /* Crashes on Windows 7 */
2261 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, NULL
);
2264 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2265 ok(hr
== E_INVALIDARG
|| hr
== E_FAIL
, "Got (0x%08x)\n", hr
);
2266 ok_no_events(pnstceimpl
);
2268 hr
= pSHGetSpecialFolderLocation(NULL
, CSIDL_DRIVES
, &pidl_drives
);
2269 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2272 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_drives
, &psi
);
2273 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2276 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psi
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2277 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2279 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2280 ok_no_events(pnstceimpl
);
2282 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2283 ok(hr
== E_INVALIDARG
, "Got (0x%08x)\n", hr
);
2284 ok_no_events(pnstceimpl
);
2286 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psi
);
2287 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2288 ok_no_events(pnstceimpl
);
2290 hr
= INameSpaceTreeControl_AppendRoot(pnstc
, psidesktop
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, 0, NULL
);
2291 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2293 ok_event_count_broken(pnstceimpl
, OnItemAdded
, 1, 0 /* Vista */);
2294 ok_no_events(pnstceimpl
);
2296 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psidesktop
);
2297 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2298 ok_no_events(pnstceimpl
);
2300 hr
= INameSpaceTreeControl_EnsureItemVisible(pnstc
, psi
);
2301 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2302 ok_no_events(pnstceimpl
);
2306 skip("Failed to create shellitem.\n");
2308 ILFree(pidl_drives
);
2311 skip("Failed to get pidl for CSIDL_DRIVES.\n");
2313 hr
= INameSpaceTreeControl_RemoveAllRoots(pnstc
);
2314 ok(hr
== S_OK
, "Got (0x%08x)\n", hr
);
2315 ok_event_count(pnstceimpl
, OnItemDeleted
, 2);
2316 ok_no_events(pnstceimpl
);
2318 hr
= INameSpaceTreeControl_QueryInterface(pnstc
, &IID_IOleWindow
, (void**)&pow
);
2319 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2323 hr
= IOleWindow_GetWindow(pow
, &hwnd_nstc
);
2324 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2325 DestroyWindow(hwnd_nstc
);
2326 IOleWindow_Release(pow
);
2329 hr
= INameSpaceTreeControl_TreeUnadvise(pnstc
, cookie2
);
2330 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2332 res
= INameSpaceTreeControl_Release(pnstc
);
2333 ok(!res
, "res was %d!\n", res
);
2337 /* Freeing these prematurely causes a crash. */
2338 HeapFree(GetProcessHeap(), 0, pnstceimpl
);
2339 HeapFree(GetProcessHeap(), 0, pnstceimpl2
);
2343 static void setup_window(void)
2346 static const char nstctest_wnd_name
[] = "nstctest_wnd";
2348 ZeroMemory(&wc
, sizeof(WNDCLASSA
));
2349 wc
.lpfnWndProc
= DefWindowProcA
;
2350 wc
.lpszClassName
= nstctest_wnd_name
;
2351 RegisterClassA(&wc
);
2352 hwnd
= CreateWindowA(nstctest_wnd_name
, NULL
, WS_TABSTOP
,
2353 0, 0, 200, 200, NULL
, 0, 0, NULL
);
2354 ok(hwnd
!= NULL
, "Failed to create window for test (lasterror: %d).\n",
2358 static void destroy_window(void)
2360 DestroyWindow(hwnd
);
2365 OleInitialize(NULL
);
2367 init_function_pointers();
2368 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
2370 if(test_initialization())
2377 win_skip("No NamespaceTreeControl (or instantiation failed).\n");