d3d10/effect: Add a helper to read raw variable values.
[wine.git] / dlls / explorerframe / tests / nstc.c
blob6433b69ebf8e5d1001116c9a8077f0bd6e9fc885
1 /*
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
21 #include <stdio.h>
23 #define COBJMACROS
24 #define CONST_VTABLE
26 #include "shlobj.h"
27 #include "wine/test.h"
29 #include "msg.h"
31 static HWND hwnd;
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;
45 static int tvi_count;
47 static void init_function_pointers(void)
49 HMODULE hmod;
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,
65 LastEvent };
67 typedef struct {
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. */
72 LONG ref;
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,
82 REFIID riid,
83 void **ppvObject)
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);
92 *ppvObject = iface;
93 return S_OK;
96 return E_NOINTERFACE;
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,
117 IShellItem *psi,
118 NSTCEHITTEST nstceHitTest,
119 NSTCECLICKTYPE nstceClickType)
121 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
123 ok(psi != NULL, "NULL IShellItem\n");
124 This->count[OnItemClick]++;
125 return E_NOTIMPL;
128 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(
129 INameSpaceTreeControlEvents* iface,
130 IShellItem *psi)
132 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
134 ok(psi != NULL, "NULL IShellItem\n");
135 This->count[OnPropertyItemCommit]++;
136 return E_NOTIMPL;
139 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(
140 INameSpaceTreeControlEvents* iface,
141 IShellItem *psi,
142 NSTCITEMSTATE nstcisMask,
143 NSTCITEMSTATE nstcisState)
145 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
147 ok(psi != NULL, "NULL IShellItem\n");
148 This->count[OnItemStateChanging]++;
149 return E_NOTIMPL;
152 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(
153 INameSpaceTreeControlEvents* iface,
154 IShellItem *psi,
155 NSTCITEMSTATE nstcisMask,
156 NSTCITEMSTATE nstcisState)
158 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
160 ok(psi != NULL, "NULL IShellItem\n");
161 This->count[OnItemStateChanged]++;
162 return E_NOTIMPL;
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");
172 if(psiaSelection)
174 HRESULT hr;
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]++;
181 return E_NOTIMPL;
184 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(
185 INameSpaceTreeControlEvents* iface,
186 UINT uMsg,
187 WPARAM wParam,
188 LPARAM lParam)
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);
195 return E_NOTIMPL;
198 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(
199 INameSpaceTreeControlEvents* iface,
200 IShellItem *psi)
202 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
204 ok(psi != NULL, "NULL IShellItem\n");
205 This->count[OnBeforeExpand]++;
206 return E_NOTIMPL;
209 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(
210 INameSpaceTreeControlEvents* iface,
211 IShellItem *psi)
213 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
215 ok(psi != NULL, "NULL IShellItem\n");
216 This->count[OnAfterExpand]++;
217 return E_NOTIMPL;
220 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(
221 INameSpaceTreeControlEvents* iface,
222 IShellItem *psi)
224 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
226 ok(psi != NULL, "NULL IShellItem\n");
227 This->count[OnBeginLabelEdit]++;
228 return E_NOTIMPL;
231 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(
232 INameSpaceTreeControlEvents* iface,
233 IShellItem *psi)
235 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
237 ok(psi != NULL, "NULL IShellItem\n");
238 This->count[OnEndLabelEdit]++;
239 return E_NOTIMPL;
242 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(
243 INameSpaceTreeControlEvents* iface,
244 IShellItem *psi,
245 LPWSTR pszTip,
246 int cchTip)
248 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
250 ok(psi != NULL, "NULL IShellItem\n");
251 This->count[OnGetToolTip]++;
252 return E_NOTIMPL;
255 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(
256 INameSpaceTreeControlEvents* iface,
257 IShellItem *psi)
259 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
261 ok(psi != NULL, "NULL IShellItem\n");
262 This->count[OnBeforeItemDelete]++;
263 return E_NOTIMPL;
266 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(
267 INameSpaceTreeControlEvents* iface,
268 IShellItem *psi,
269 BOOL fIsRoot)
271 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
273 ok(psi != NULL, "NULL IShellItem\n");
274 This->count[OnItemAdded]++;
275 return S_OK;
278 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(
279 INameSpaceTreeControlEvents* iface,
280 IShellItem *psi,
281 BOOL fIsRoot)
283 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
285 ok(psi != NULL, "NULL IShellItem\n");
286 This->count[OnItemDeleted]++;
287 return S_OK;
290 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(
291 INameSpaceTreeControlEvents* iface,
292 IShellItem *psi,
293 REFIID riid,
294 void **ppv)
296 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
298 This->count[OnBeforeContextMenu]++;
299 return E_NOTIMPL;
302 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(
303 INameSpaceTreeControlEvents* iface,
304 IShellItem *psi,
305 IContextMenu *pcmIn,
306 REFIID riid,
307 void **ppv)
309 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
311 This->count[OnAfterContextMenu]++;
312 return E_NOTIMPL;
315 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(
316 INameSpaceTreeControlEvents* iface,
317 IShellItem *psi)
319 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
321 ok(psi != NULL, "NULL IShellItem\n");
322 This->count[OnBeforeStateImageChange]++;
323 return E_NOTIMPL;
326 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(
327 INameSpaceTreeControlEvents* iface,
328 IShellItem *psi,
329 int *piDefaultIcon,
330 int *piOpenIcon)
332 INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
334 ok(psi != NULL, "NULL IShellItem\n");
335 This->count[OnGetDefaultIconIndex]++;
336 return E_NOTIMPL;
339 static const INameSpaceTreeControlEventsVtbl vt_NSTCEvents = {
340 NSTCEvents_fnQueryInterface,
341 NSTCEvents_fnAddRef,
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;
369 This->ref = 1;
371 return This;
374 /*********************************************************************
375 * Event count checking
377 static void ok_no_events_(INameSpaceTreeControlEventsImpl *impl,
378 const char *file, int line)
380 UINT i;
381 for(i = 0; i < LastEvent; i++)
383 ok_(file, line)
384 (!impl->count[i], "Got event %d, count %d\n", i, impl->count[i]);
385 impl->count[i] = 0;
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; \
395 } while(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]), \
402 "No event.\n"); \
403 impl->count[event] = 0; \
404 } while(0)
406 #define ok_event(impl, event) \
407 do { ok(impl->count[event], "No event %d.\n", event); \
408 impl->count[event] = 0; \
409 } while(0)
411 /* Process some messages */
412 static void process_msgs(void)
414 MSG msg;
415 BOOL got_msg;
416 do {
417 got_msg = FALSE;
418 Sleep(100);
419 while(PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE))
421 TranslateMessage(&msg);
422 DispatchMessageW(&msg);
423 got_msg = TRUE;
425 } while(got_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.) */
431 Sleep(500);
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)
444 HANDLE file;
445 DWORD written;
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);
452 CloseHandle(file);
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 )
480 size_t iLen;
482 if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH)
483 return NULL;
485 if (iLen)
487 lpszPath += iLen;
488 if (lpszPath[-1] != '\\')
490 *lpszPath++ = '\\';
491 *lpszPath = '\0';
494 return lpszPath;
497 static HWND get_treeview_hwnd(INameSpaceTreeControl *pnstc)
499 IOleWindow *pow;
500 HRESULT hr;
501 HWND treeview = NULL;
503 hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
504 ok(hr == S_OK, "Got 0x%08x\n", hr);
505 if(SUCCEEDED(hr))
507 HWND host;
508 hr = IOleWindow_GetWindow(pow, &host);
509 ok(hr == S_OK, "Got 0x%08x\n", hr);
510 if(SUCCEEDED(hr))
511 treeview = FindWindowExW(host, NULL, WC_TREEVIEWW, NULL);
512 IOleWindow_Release(pow);
515 return treeview;
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;
522 LRESULT ret;
523 struct message msg;
525 msg.message = message;
526 msg.flags = sent|wparam|lparam;
527 if (defwndproc_counter) msg.flags |= defwinproc;
528 msg.wParam = wParam;
529 msg.lParam = lParam;
530 msg.id = 0;
531 add_message(sequences, TREEVIEW_SEQ_INDEX, &msg);
533 if(message == TVM_SETITEMW)
535 memcpy(&last_tvi, (void*)lParam, sizeof(TVITEMEXW));
536 tvi_count++;
539 defwndproc_counter++;
540 ret = CallWindowProcW(oldproc, hwnd_tv, message, wParam, lParam);
541 defwndproc_counter--;
542 return ret;
545 static BOOL subclass_treeview(INameSpaceTreeControl *pnstc)
547 HWND hwnd_tv;
548 WNDPROC oldproc = NULL;
550 hwnd_tv = get_treeview_hwnd(pnstc);
551 if(hwnd_tv)
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");
559 return oldproc != 0;
562 static UINT get_msg_count(struct msg_sequence **seq, int sequence_index, UINT message)
564 struct msg_sequence *msg_seq = seq[sequence_index];
565 UINT i, count = 0;
567 for(i = 0; i < msg_seq->count ; i++)
568 if(msg_seq->sequence[i].message == message)
569 count++;
571 return count;
574 /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
575 static BOOL test_initialization(void)
577 INameSpaceTreeControl *pnstc;
578 IOleWindow *pow;
579 IUnknown *punk;
580 HWND hwnd_host1;
581 LONG lres;
582 HRESULT hr;
583 RECT rc;
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);
588 if(FAILED(hr))
590 return FALSE;
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);
608 if(SUCCEEDED(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);
625 if(SUCCEEDED(hr))
627 static const CHAR namespacetree[] = "NamespaceTreeControl";
628 char buf[1024];
629 LONG style, expected_style;
630 HWND hwnd_tv;
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");
634 buf[0] = '\0';
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);
642 expected_style = 0;
643 style = GetWindowLongPtrW(hwnd_host1, GWL_EXSTYLE);
644 ok(style == expected_style, "Got style %08x\n", style);
646 expected_style = 0;
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");
652 if(hwnd_tv)
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);
660 expected_style = 0;
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);
673 if(0)
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);
680 if(SUCCEEDED(hr))
682 HWND hwnd_host2;
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);
724 return TRUE;
727 static void verify_root_order_(INameSpaceTreeControl *pnstc, IShellItem **roots,
728 const char *file, int line)
730 HRESULT hr;
731 IShellItemArray *psia;
733 hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia);
734 ok_(file,line) (hr == S_OK, "GetRootItems: got (0x%08x)\n", hr);
735 if(SUCCEEDED(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++)
746 IShellItem *psi;
747 hr = IShellItemArray_GetItemAt(psia, i, &psi);
748 ok_(file,line) (hr == S_OK, "GetItemAt %i: got 0x%08x\n", i, hr);
749 if(SUCCEEDED(hr))
751 int cmp;
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;
769 IShellItem *psi;
770 IShellItem *psidesktop, *psidesktop2;
771 IShellItem *psitestdir, *psitestdir2, *psitest1;
772 IOleWindow *pow;
773 LPITEMIDLIST pidl_desktop;
774 NSTCITEMSTATE istate;
775 HRESULT hr;
776 UINT i, res, height;
777 HWND hwnd_tv;
778 RECT rc;
779 IShellItem *roots[10];
780 POINT pt;
781 int cbstate;
782 WCHAR curdirW[MAX_PATH];
783 WCHAR buf[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);
795 if(SUCCEEDED(hr))
797 hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop);
798 ok(hr == S_OK, "Got 0x%08x\n", hr);
799 if(SUCCEEDED(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);
809 if(FAILED(hr))
811 win_skip("Test setup failed.\n");
812 return;
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);
853 process_msgs();
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);
864 if(SUCCEEDED(hr))
866 DWORD tmp;
867 NSTCSTYLE style;
868 NSTCSTYLE2 style2;
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);
879 if(hr == S_OK)
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);
900 tmp = 0;
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);
911 if(SUCCEEDED(hr))
913 DWORD tmp2;
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);
956 tmp = 0;
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);
967 if(SUCCEEDED(hr))
969 DWORD tmp2;
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);
987 else
989 /* 64-bit Windows Vista (others?) seems to have a somewhat
990 * different idea of how the methods of this interface
991 * should behave. */
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");
1008 style = 0xdeadbeef;
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);
1017 tmp = 0;
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];
1026 style = 0xdeadbeef;
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);
1031 tmp = 0;
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);
1048 else
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 */
1057 if(0)
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);
1071 process_msgs();
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);
1104 /* GetRootItems */
1105 if(0)
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;
1127 roots[4] = NULL;
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;
1138 roots[5] = NULL;
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;
1150 roots[6] = NULL;
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;
1163 roots[7] = NULL;
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;
1177 roots[8] = NULL;
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;
1192 roots[9] = NULL;
1193 verify_root_order(pnstc, roots);
1195 /* CollapseAll */
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");
1208 if(res)
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);
1217 /* A special case -
1218 * The first expansion results in an "unrelated" TVM_SETITEMW being sent
1219 * (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) )
1221 tvi_count = 0;
1222 hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop,
1223 NSTCIS_EXPANDED, NSTCIS_EXPANDED);
1224 ok(hr == S_OK, "Got 0x%08x\n", hr);
1225 todo_wine
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);
1231 tvi_count = 0;
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;
1244 TVITEMEXW tviexp;
1245 UINT msg_count;
1247 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1248 tvi_count = 0;
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;
1271 else
1272 tviexp.mask = 0;
1274 if(tviexp.mask)
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;
1288 else
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);
1312 if(!tviexp.mask)
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);
1324 else
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 */
1348 if(0)
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);
1361 process_msgs();
1363 hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, SHCONTF_FOLDERS, 0, NULL);
1364 ok(hr == S_OK, "Got (0x%08x)\n", hr);
1365 process_msgs();
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);
1373 if(SUCCEEDED(hr))
1375 UINT count;
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);
1379 if(count)
1381 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1382 ok(hr == S_OK, "Got 0x%08x\n", hr);
1383 if(SUCCEEDED(hr))
1385 int cmp;
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);
1397 process_msgs();
1399 hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1400 ok(hr == S_OK, "Got 0x%08x\n", hr);
1401 if(SUCCEEDED(hr))
1403 UINT count;
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);
1407 if(count)
1409 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1410 ok(hr == S_OK, "Got 0x%08x\n", hr);
1411 if(SUCCEEDED(hr))
1413 int cmp;
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);
1427 if(SUCCEEDED(hr))
1429 UINT count;
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);
1433 if(count)
1435 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1436 ok(hr == S_OK, "Got 0x%08x\n", hr);
1437 if(SUCCEEDED(hr))
1439 int cmp;
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);
1450 if(hr == E_FAIL)
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,
1461 0, NULL);
1462 ok(hr == S_OK, "Got 0x%08x\n", hr);
1463 process_msgs();
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);
1480 process_msgs();
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);
1487 if(SUCCEEDED(hr))
1489 IShellItem *psi;
1491 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1492 if(SUCCEEDED(hr))
1494 INT cmp;
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);
1509 process_msgs();
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);
1516 if(SUCCEEDED(hr))
1518 IShellItem *psi;
1520 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1521 if(SUCCEEDED(hr))
1523 INT cmp;
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);
1536 /* GetItemRect */
1537 SetRectEmpty(&rc);
1538 if(0)
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);
1553 process_msgs();
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");
1560 height = 0;
1561 hwnd_tv = get_treeview_hwnd(pnstc);
1562 if(hwnd_tv)
1564 HTREEITEM hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
1565 ok(hroot != NULL, "Failed to get root.\n");
1566 if(hroot)
1568 RECT tv_rc;
1569 BOOL bret;
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);
1586 else
1587 win_skip("Skipping some GetItemRect tests.\n");
1589 hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1590 ok(hr == S_OK, "Got (0x%08x)\n", hr);
1592 /* HitTest */
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;
1601 pt.x = pt.y = 0;
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);
1610 process_msgs();
1612 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1613 ok(hr == S_OK, "Got 0x%08x\n", hr);
1614 if(SUCCEEDED(hr))
1616 int cmp;
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);
1623 pt.y += height - 1;
1624 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1625 ok(hr == S_OK, "Got 0x%08x\n", hr);
1626 if(SUCCEEDED(hr))
1628 int cmp;
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);
1635 pt.y += 1;
1636 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1637 ok(hr == S_OK, "Got 0x%08x\n", hr);
1638 if(SUCCEEDED(hr))
1640 int cmp;
1641 todo_wine
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);
1655 if(SUCCEEDED(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);
1662 if(SUCCEEDED(hr))
1664 int cmp;
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 */
1676 if(0)
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,
1687 0, NULL);
1688 process_msgs();
1689 ok(hr == S_OK, "Got 0x%08x\n", hr);
1691 todo_wine
1693 cbstate = -1;
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);
1702 cbstate = -1;
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);
1710 cbstate = -1;
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);
1716 /* SetTheme */
1717 todo_wine
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);
1738 if(SUCCEEDED(hr))
1740 HWND hwnd_nstc;
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);
1750 cleanup:
1751 Cleanup();
1754 static void test_events(void)
1756 INameSpaceTreeControl *pnstc;
1757 INameSpaceTreeControlEventsImpl *pnstceimpl, *pnstceimpl2;
1758 INameSpaceTreeControlEvents *pnstce, *pnstce2;
1759 IShellFolder *psfdesktop;
1760 IShellItem *psidesktop;
1761 IOleWindow *pow;
1762 LPITEMIDLIST pidl_desktop;
1763 LPITEMIDLIST pidl_drives;
1764 NSTCITEMSTATE itemstate;
1765 IShellItem *psi;
1766 DWORD cookie1, cookie2;
1767 HWND hwnd_tv;
1768 HRESULT hr;
1769 UINT res;
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;
1793 if(0)
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;
1808 cookie1 = 1;
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;
1818 cookie1 = 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;
1828 cookie2 = 1;
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;
1839 cookie2 = 1;
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);
1884 process_msgs();
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");
1891 if(hwnd_tv)
1893 HTREEITEM hroot, hitem;
1894 UINT i;
1895 static const UINT kbd_msgs_event[] = {
1896 WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
1897 WM_SYSCHAR, 0 };
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);
1904 process_msgs();
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);
1911 process_msgs();
1912 ok_no_events(pnstceimpl);
1913 SendMessageW(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot);
1914 process_msgs();
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);
1920 process_msgs();
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);
1944 else
1945 skip("Skipping some tests.\n");
1947 hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1948 process_msgs();
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);
1956 process_msgs();
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);
1963 process_msgs();
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);
1970 process_msgs();
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);
1974 todo_wine
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");
1983 todo_wine
1985 ok(itemstate == (NSTCIS_SELECTED | NSTCIS_EXPANDED)||
1986 broken(itemstate == NSTCIS_EXPANDED) /* Vista */,
1987 "itemstate is 0x%08x\n", itemstate);
1988 process_msgs();
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);
1997 process_msgs();
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 */
2016 if(0)
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);
2037 process_msgs();
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);
2049 process_msgs();
2050 todo_wine
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);
2061 todo_wine
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);
2067 process_msgs();
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);
2078 process_msgs();
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);
2090 process_msgs();
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);
2101 process_msgs();
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);
2112 process_msgs();
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);
2123 process_msgs();
2124 todo_wine
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);
2140 process_msgs();
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);
2151 process_msgs();
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);
2157 todo_wine
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);
2166 process_msgs();
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 todo_wine
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);
2182 process_msgs();
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);
2194 process_msgs();
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);
2206 process_msgs();
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);
2220 /* GetNextItem */
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);
2239 process_msgs();
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);
2248 process_msgs();
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);
2254 process_msgs();
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);
2264 process_msgs();
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 */
2274 if(0)
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);
2286 if(SUCCEEDED(hr))
2288 hr = pSHCreateShellItem(NULL, NULL, pidl_drives, &psi);
2289 ok(hr == S_OK, "Got (0x%08x)\n", hr);
2290 if(SUCCEEDED(hr))
2292 hr = INameSpaceTreeControl_AppendRoot(pnstc, psi, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2293 ok(hr == S_OK, "Got (0x%08x)\n", hr);
2294 process_msgs();
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);
2308 process_msgs();
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);
2321 else
2322 skip("Failed to create shellitem.\n");
2324 ILFree(pidl_drives);
2326 else
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);
2336 if(SUCCEEDED(hr))
2338 HWND hwnd_nstc;
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);
2351 if(!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)
2364 WNDCLASSA wc;
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",
2374 GetLastError());
2377 static void destroy_window(void)
2379 DestroyWindow(hwnd);
2382 START_TEST(nstc)
2384 OleInitialize(NULL);
2385 setup_window();
2386 init_function_pointers();
2387 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
2389 if(test_initialization())
2391 test_basics();
2392 test_events();
2394 else
2395 win_skip("No NamespaceTreeControl (or instantiation failed).\n");
2397 destroy_window();
2398 OleUninitialize();