wer: Add new stubbed wer.dll.
[wine/hramrach.git] / dlls / explorerframe / tests / nstc.c
blobc329311b8c45d60944a1661ba66e59e4f7ba3e33
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
25 #include "shlobj.h"
26 #include "wine/test.h"
28 #include "msg.h"
30 static HWND hwnd;
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;
47 static int tvi_count;
49 static void init_function_pointers(void)
51 HMODULE hmod;
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,
67 LastEvent };
69 typedef struct {
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. */
74 LONG ref;
75 } INameSpaceTreeControlEventsImpl;
77 #define NSTCE_IMPL(iface) \
78 ((INameSpaceTreeControlEventsImpl*)iface)
80 static HRESULT WINAPI NSTCEvents_fnQueryInterface(
81 INameSpaceTreeControlEvents* iface,
82 REFIID riid,
83 void **ppvObject)
85 NSTCE_IMPL(iface)->qi_called_count++;
87 if(NSTCE_IMPL(iface)->qi_enable_events &&
88 IsEqualIID(riid, &IID_INameSpaceTreeControlEvents))
90 IUnknown_AddRef(iface);
91 *ppvObject = iface;
92 return S_OK;
95 return E_NOINTERFACE;
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,
112 IShellItem *psi,
113 NSTCEHITTEST nstceHitTest,
114 NSTCECLICKTYPE nstceClickType)
116 ok(psi != NULL, "NULL IShellItem\n");
117 NSTCE_IMPL(iface)->count[OnItemClick]++;
118 return E_NOTIMPL;
121 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(
122 INameSpaceTreeControlEvents* iface,
123 IShellItem *psi)
125 ok(psi != NULL, "NULL IShellItem\n");
126 NSTCE_IMPL(iface)->count[OnPropertyItemCommit]++;
127 return E_NOTIMPL;
130 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(
131 INameSpaceTreeControlEvents* iface,
132 IShellItem *psi,
133 NSTCITEMSTATE nstcisMask,
134 NSTCITEMSTATE nstcisState)
136 ok(psi != NULL, "NULL IShellItem\n");
137 NSTCE_IMPL(iface)->count[OnItemStateChanging]++;
138 return E_NOTIMPL;
141 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(
142 INameSpaceTreeControlEvents* iface,
143 IShellItem *psi,
144 NSTCITEMSTATE nstcisMask,
145 NSTCITEMSTATE nstcisState)
147 ok(psi != NULL, "NULL IShellItem\n");
148 NSTCE_IMPL(iface)->count[OnItemStateChanged]++;
149 return E_NOTIMPL;
152 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(
153 INameSpaceTreeControlEvents* iface,
154 IShellItemArray *psiaSelection)
156 ok(psiaSelection != NULL, "IShellItemArray was NULL.\n");
157 if(psiaSelection)
159 HRESULT hr;
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]++;
166 return E_NOTIMPL;
169 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(
170 INameSpaceTreeControlEvents* iface,
171 UINT uMsg,
172 WPARAM wParam,
173 LPARAM lParam)
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);
178 return E_NOTIMPL;
181 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(
182 INameSpaceTreeControlEvents* iface,
183 IShellItem *psi)
185 ok(psi != NULL, "NULL IShellItem\n");
186 NSTCE_IMPL(iface)->count[OnBeforeExpand]++;
187 return E_NOTIMPL;
190 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(
191 INameSpaceTreeControlEvents* iface,
192 IShellItem *psi)
194 ok(psi != NULL, "NULL IShellItem\n");
195 NSTCE_IMPL(iface)->count[OnAfterExpand]++;
196 return E_NOTIMPL;
199 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(
200 INameSpaceTreeControlEvents* iface,
201 IShellItem *psi)
203 ok(psi != NULL, "NULL IShellItem\n");
204 NSTCE_IMPL(iface)->count[OnBeginLabelEdit]++;
205 return E_NOTIMPL;
208 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(
209 INameSpaceTreeControlEvents* iface,
210 IShellItem *psi)
212 ok(psi != NULL, "NULL IShellItem\n");
213 NSTCE_IMPL(iface)->count[OnEndLabelEdit]++;
214 return E_NOTIMPL;
217 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(
218 INameSpaceTreeControlEvents* iface,
219 IShellItem *psi,
220 LPWSTR pszTip,
221 int cchTip)
223 ok(psi != NULL, "NULL IShellItem\n");
224 NSTCE_IMPL(iface)->count[OnGetToolTip]++;
225 return E_NOTIMPL;
228 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(
229 INameSpaceTreeControlEvents* iface,
230 IShellItem *psi)
232 ok(psi != NULL, "NULL IShellItem\n");
233 NSTCE_IMPL(iface)->count[OnBeforeItemDelete]++;
234 return E_NOTIMPL;
237 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(
238 INameSpaceTreeControlEvents* iface,
239 IShellItem *psi,
240 BOOL fIsRoot)
242 ok(psi != NULL, "NULL IShellItem\n");
243 NSTCE_IMPL(iface)->count[OnItemAdded]++;
244 return S_OK;
247 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(
248 INameSpaceTreeControlEvents* iface,
249 IShellItem *psi,
250 BOOL fIsRoot)
252 ok(psi != NULL, "NULL IShellItem\n");
253 NSTCE_IMPL(iface)->count[OnItemDeleted]++;
254 return S_OK;
257 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(
258 INameSpaceTreeControlEvents* iface,
259 IShellItem *psi,
260 REFIID riid,
261 void **ppv)
263 NSTCE_IMPL(iface)->count[OnBeforeContextMenu]++;
264 return E_NOTIMPL;
267 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(
268 INameSpaceTreeControlEvents* iface,
269 IShellItem *psi,
270 IContextMenu *pcmIn,
271 REFIID riid,
272 void **ppv)
274 NSTCE_IMPL(iface)->count[OnAfterContextMenu]++;
275 return E_NOTIMPL;
278 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(
279 INameSpaceTreeControlEvents* iface,
280 IShellItem *psi)
282 ok(psi != NULL, "NULL IShellItem\n");
283 NSTCE_IMPL(iface)->count[OnBeforeStateImageChange]++;
284 return E_NOTIMPL;
287 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(
288 INameSpaceTreeControlEvents* iface,
289 IShellItem *psi,
290 int *piDefaultIcon,
291 int *piOpenIcon)
293 ok(psi != NULL, "NULL IShellItem\n");
294 NSTCE_IMPL(iface)->count[OnGetDefaultIconIndex]++;
295 return E_NOTIMPL;
298 const INameSpaceTreeControlEventsVtbl vt_NSTCEvents = {
299 NSTCEvents_fnQueryInterface,
300 NSTCEvents_fnAddRef,
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
321 #undef NSTCE_IMPL
323 static INameSpaceTreeControlEventsImpl *create_nstc_events(void)
325 INameSpaceTreeControlEventsImpl *This;
326 This = HeapAlloc(GetProcessHeap(), 0, sizeof(INameSpaceTreeControlEventsImpl));
327 This->lpVtbl = &vt_NSTCEvents;
328 This->ref = 1;
330 return This;
333 /*********************************************************************
334 * Event count checking
336 static void ok_no_events_(INameSpaceTreeControlEventsImpl *impl,
337 const char *file, int line)
339 UINT i;
340 for(i = 0; i < LastEvent; i++)
342 ok_(file, line)
343 (!impl->count[i], "Got event %d, count %d\n", i, impl->count[i]);
344 impl->count[i] = 0;
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; \
354 } while(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]), \
361 "No event.\n"); \
362 impl->count[event] = 0; \
363 } while(0)
365 #define ok_event(impl, event) \
366 do { ok(impl->count[event], "No event %d.\n", event); \
367 impl->count[event] = 0; \
368 } while(0)
370 /* Process some messages */
371 static void process_msgs(void)
373 MSG msg;
374 BOOL got_msg;
375 do {
376 got_msg = FALSE;
377 Sleep(100);
378 while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
380 TranslateMessage(&msg);
381 DispatchMessage(&msg);
382 got_msg = TRUE;
384 } while(got_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.) */
390 Sleep(500);
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)
403 HANDLE file;
404 DWORD written;
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);
411 CloseHandle(file);
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 )
439 size_t iLen;
441 if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH)
442 return NULL;
444 if (iLen)
446 lpszPath += iLen;
447 if (lpszPath[-1] != '\\')
449 *lpszPath++ = '\\';
450 *lpszPath = '\0';
453 return lpszPath;
456 static HWND get_treeview_hwnd(INameSpaceTreeControl *pnstc)
458 IOleWindow *pow;
459 HRESULT hr;
460 HWND treeview = NULL;
462 hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
463 ok(hr == S_OK, "Got 0x%08x\n", hr);
464 if(SUCCEEDED(hr))
466 HWND host;
467 hr = IOleWindow_GetWindow(pow, &host);
468 ok(hr == S_OK, "Got 0x%08x\n", hr);
469 if(SUCCEEDED(hr))
470 treeview = FindWindowExW(host, NULL, WC_TREEVIEWW, NULL);
471 IOleWindow_Release(pow);
474 return treeview;
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;
481 LRESULT ret;
482 struct message msg;
484 msg.message = message;
485 msg.flags = sent|wparam|lparam;
486 if (defwndproc_counter) msg.flags |= defwinproc;
487 msg.wParam = wParam;
488 msg.lParam = lParam;
489 msg.id = 0;
490 add_message(sequences, TREEVIEW_SEQ_INDEX, &msg);
492 if(message == TVM_SETITEMW)
494 memcpy(&last_tvi, (void*)lParam, sizeof(TVITEMEXW));
495 tvi_count++;
498 defwndproc_counter++;
499 ret = CallWindowProcW(oldproc, hwnd_tv, message, wParam, lParam);
500 defwndproc_counter--;
501 return ret;
504 static BOOL subclass_treeview(INameSpaceTreeControl *pnstc)
506 HWND hwnd_tv;
507 WNDPROC oldproc = NULL;
509 hwnd_tv = get_treeview_hwnd(pnstc);
510 if(hwnd_tv)
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];
524 UINT i, count = 0;
526 for(i = 0; i < msg_seq->count ; i++)
527 if(msg_seq->sequence[i].message == message)
528 count++;
530 return count;
533 /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
534 static BOOL test_initialization(void)
536 INameSpaceTreeControl *pnstc;
537 IOleWindow *pow;
538 IUnknown *punk;
539 HWND hwnd_host1;
540 LONG lres;
541 HRESULT hr;
542 RECT rc;
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);
547 if(FAILED(hr))
549 return FALSE;
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);
567 if(SUCCEEDED(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);
584 if(SUCCEEDED(hr))
586 static const CHAR namespacetree[] = "NamespaceTreeControl";
587 char buf[1024];
588 LONG style, expected_style;
589 HWND hwnd_tv;
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");
593 buf[0] = '\0';
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);
601 expected_style = 0;
602 style = GetWindowLongPtrW(hwnd_host1, GWL_EXSTYLE);
603 ok(style == expected_style, "Got style %08x\n", style);
605 expected_style = 0;
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");
611 if(hwnd_tv)
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);
619 expected_style = 0;
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);
632 if(0)
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);
639 if(SUCCEEDED(hr))
641 HWND hwnd_host2;
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);
681 return TRUE;
684 static void verify_root_order_(INameSpaceTreeControl *pnstc, IShellItem **roots,
685 const char *file, int line)
687 HRESULT hr;
688 IShellItemArray *psia;
690 hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia);
691 ok_(file,line) (hr == S_OK, "GetRootItems: got (0x%08x)\n", hr);
692 if(SUCCEEDED(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++)
703 IShellItem *psi;
704 hr = IShellItemArray_GetItemAt(psia, i, &psi);
705 ok_(file,line) (hr == S_OK, "GetItemAt %i: got 0x%08x\n", i, hr);
706 if(SUCCEEDED(hr))
708 int cmp;
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;
726 IShellItem *psi;
727 IShellItem *psidesktop, *psidesktop2;
728 IShellItem *psitestdir, *psitestdir2, *psitest1;
729 IOleWindow *pow;
730 LPITEMIDLIST pidl_desktop;
731 NSTCITEMSTATE istate;
732 HRESULT hr;
733 UINT i, res, height;
734 HWND hwnd_tv;
735 RECT rc;
736 IShellItem *roots[10];
737 POINT pt;
738 int cbstate;
739 WCHAR curdirW[MAX_PATH];
740 WCHAR buf[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);
759 if(SUCCEEDED(hr))
761 hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop);
762 ok(hr == S_OK, "Got 0x%08x\n", hr);
763 if(SUCCEEDED(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);
774 if(FAILED(hr))
776 win_skip("Test setup failed.\n");
777 return;
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);
816 process_msgs();
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);
827 if(SUCCEEDED(hr))
829 DWORD tmp;
830 NSTCSTYLE style;
831 NSTCSTYLE2 style2;
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);
842 if(hr == S_OK)
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);
873 tmp = 0;
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);
889 if(SUCCEEDED(hr))
891 DWORD tmp2;
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);
939 tmp = 0;
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);
950 if(SUCCEEDED(hr))
952 DWORD tmp2;
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);
970 else
972 /* 64-bit Windows Vista (others?) seems to have a somewhat
973 * different idea of how the methods of this interface
974 * should behave. */
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");
991 style = 0xdeadbeef;
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);
1000 tmp = 0;
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];
1009 style = 0xdeadbeef;
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);
1014 tmp = 0;
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);
1031 else
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 */
1040 if(0)
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);
1054 process_msgs();
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);
1087 /* GetRootItems */
1088 if(0)
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;
1110 roots[4] = NULL;
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;
1121 roots[5] = NULL;
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;
1128 roots[6] = NULL;
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;
1138 roots[7] = NULL;
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;
1145 roots[8] = NULL;
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;
1160 roots[9] = NULL;
1161 verify_root_order(pnstc, roots);
1163 /* CollapseAll */
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");
1176 if(res)
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);
1185 /* A special case -
1186 * The first expansion results in an "unrelated" TVM_SETITEMW being sent
1187 * (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) )
1189 tvi_count = 0;
1190 hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop,
1191 NSTCIS_EXPANDED, NSTCIS_EXPANDED);
1192 ok(hr == S_OK, "Got 0x%08x\n", hr);
1193 todo_wine
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);
1199 tvi_count = 0;
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;
1212 TVITEMEXW tviexp;
1213 UINT msg_count;
1215 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1216 tvi_count = 0;
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;
1239 else
1240 tviexp.mask = 0;
1242 if(tviexp.mask)
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;
1256 else
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);
1280 if(!tviexp.mask)
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);
1292 else
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 */
1316 if(0)
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);
1329 process_msgs();
1331 hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, SHCONTF_FOLDERS, 0, NULL);
1332 ok(hr == S_OK, "Got (0x%08x)\n", hr);
1333 process_msgs();
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);
1341 if(SUCCEEDED(hr))
1343 UINT count;
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);
1347 if(count)
1349 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1350 ok(hr == S_OK, "Got 0x%08x\n", hr);
1351 if(SUCCEEDED(hr))
1353 int cmp;
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);
1365 process_msgs();
1367 hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1368 ok(hr == S_OK, "Got 0x%08x\n", hr);
1369 if(SUCCEEDED(hr))
1371 UINT count;
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);
1375 if(count)
1377 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1378 ok(hr == S_OK, "Got 0x%08x\n", hr);
1379 if(SUCCEEDED(hr))
1381 int cmp;
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);
1395 if(SUCCEEDED(hr))
1397 UINT count;
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);
1401 if(count)
1403 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1404 ok(hr == S_OK, "Got 0x%08x\n", hr);
1405 if(SUCCEEDED(hr))
1407 int cmp;
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);
1418 if(hr == E_FAIL)
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,
1429 0, NULL);
1430 ok(hr == S_OK, "Got 0x%08x\n", hr);
1431 process_msgs();
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);
1448 process_msgs();
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);
1455 if(SUCCEEDED(hr))
1457 IShellItem *psi;
1459 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1460 if(SUCCEEDED(hr))
1462 INT cmp;
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);
1477 process_msgs();
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);
1484 if(SUCCEEDED(hr))
1486 IShellItem *psi;
1488 hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1489 if(SUCCEEDED(hr))
1491 INT cmp;
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);
1504 /* GetItemRect */
1505 rc.top = rc.left = rc.bottom = rc.right = 0;
1506 if(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);
1521 process_msgs();
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");
1528 height = 0;
1529 hwnd_tv = get_treeview_hwnd(pnstc);
1530 if(hwnd_tv)
1532 HTREEITEM hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
1533 ok(hroot != NULL, "Failed to get root.\n");
1534 if(hroot)
1536 RECT tv_rc;
1537 BOOL bret;
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);
1556 else
1557 win_skip("Skipping some GetItemRect tests.\n");
1559 hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1560 ok(hr == S_OK, "Got (0x%08x)\n", hr);
1562 /* HitTest */
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);
1579 process_msgs();
1581 pt.x = pt.y = 0;
1582 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1583 ok(hr == S_OK, "Got 0x%08x\n", hr);
1584 if(SUCCEEDED(hr))
1586 int cmp;
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);
1593 pt.y += height - 1;
1594 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1595 ok(hr == S_OK, "Got 0x%08x\n", hr);
1596 if(SUCCEEDED(hr))
1598 int cmp;
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);
1605 pt.y += 1;
1606 hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1607 ok(hr == S_OK, "Got 0x%08x\n", hr);
1608 if(SUCCEEDED(hr))
1610 int cmp;
1611 todo_wine
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);
1625 if(SUCCEEDED(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);
1632 if(SUCCEEDED(hr))
1634 int cmp;
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 */
1646 if(0)
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,
1657 0, NULL);
1658 process_msgs();
1659 ok(hr == S_OK, "Got 0x%08x\n", hr);
1661 todo_wine
1663 cbstate = -1;
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);
1672 cbstate = -1;
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);
1680 cbstate = -1;
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);
1686 /* SetTheme */
1687 todo_wine
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);
1708 if(SUCCEEDED(hr))
1710 HWND hwnd_nstc;
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);
1720 cleanup:
1721 Cleanup();
1724 static void test_events(void)
1726 INameSpaceTreeControl *pnstc;
1727 INameSpaceTreeControlEventsImpl *pnstceimpl, *pnstceimpl2;
1728 INameSpaceTreeControlEvents *pnstce, *pnstce2;
1729 IShellFolder *psfdesktop;
1730 IShellItem *psidesktop;
1731 IOleWindow *pow;
1732 LPITEMIDLIST pidl_desktop;
1733 LPITEMIDLIST pidl_drives;
1734 NSTCITEMSTATE itemstate;
1735 IShellItem *psi;
1736 DWORD cookie1, cookie2;
1737 HWND hwnd_tv;
1738 HRESULT hr;
1739 UINT res;
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;
1763 if(0)
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);
1782 todo_wine
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);
1797 todo_wine
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");
1852 todo_wine
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);
1868 process_msgs();
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");
1875 if(hwnd_tv)
1877 HTREEITEM hroot, hitem;
1878 UINT i;
1879 static const UINT kbd_msgs_event[] = {
1880 WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
1881 WM_SYSCHAR, 0 };
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);
1888 process_msgs();
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);
1895 process_msgs();
1896 ok_no_events(pnstceimpl);
1897 SendMessage(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot);
1898 process_msgs();
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);
1904 process_msgs();
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);
1928 else
1929 skip("Skipping some tests.\n");
1931 hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1932 process_msgs();
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);
1940 process_msgs();
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);
1947 process_msgs();
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);
1954 process_msgs();
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);
1958 todo_wine
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");
1967 todo_wine
1969 ok(itemstate == (NSTCIS_SELECTED | NSTCIS_EXPANDED)||
1970 broken(itemstate == NSTCIS_EXPANDED) /* Vista */,
1971 "itemstate is 0x%08x\n", itemstate);
1972 process_msgs();
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);
1981 process_msgs();
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 */
2000 if(0)
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);
2021 process_msgs();
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);
2033 process_msgs();
2034 todo_wine
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);
2045 todo_wine
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);
2051 process_msgs();
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);
2062 process_msgs();
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);
2074 process_msgs();
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);
2085 process_msgs();
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);
2096 process_msgs();
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);
2107 process_msgs();
2108 todo_wine
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);
2124 process_msgs();
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);
2135 process_msgs();
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);
2141 todo_wine
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);
2150 process_msgs();
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);
2156 todo_wine
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);
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 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);
2178 process_msgs();
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);
2190 process_msgs();
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);
2204 /* GetNextItem */
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);
2223 process_msgs();
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);
2232 process_msgs();
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);
2238 process_msgs();
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);
2248 process_msgs();
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 */
2258 if(0)
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);
2270 if(SUCCEEDED(hr))
2272 hr = pSHCreateShellItem(NULL, NULL, pidl_drives, &psi);
2273 ok(hr == S_OK, "Got (0x%08x)\n", hr);
2274 if(SUCCEEDED(hr))
2276 hr = INameSpaceTreeControl_AppendRoot(pnstc, psi, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2277 ok(hr == S_OK, "Got (0x%08x)\n", hr);
2278 process_msgs();
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);
2292 process_msgs();
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);
2305 else
2306 skip("Failed to create shellitem.\n");
2308 ILFree(pidl_drives);
2310 else
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);
2320 if(SUCCEEDED(hr))
2322 HWND hwnd_nstc;
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);
2335 if(!res)
2337 /* Freeing these prematurely causes a crash. */
2338 HeapFree(GetProcessHeap(), 0, pnstceimpl);
2339 HeapFree(GetProcessHeap(), 0, pnstceimpl2);
2343 static void setup_window(void)
2345 WNDCLASSA wc;
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",
2355 GetLastError());
2358 static void destroy_window(void)
2360 DestroyWindow(hwnd);
2363 START_TEST(nstc)
2365 OleInitialize(NULL);
2366 setup_window();
2367 init_function_pointers();
2368 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
2370 if(test_initialization())
2372 test_basics();
2373 test_events();
2375 else
2377 win_skip("No NamespaceTreeControl (or instantiation failed).\n");
2380 destroy_window();
2381 OleUninitialize();