ntdll: Add ARM64 cpu info.
[wine] / dlls / explorerframe / tests / nstc.c
1 /*
2  *    Unit tests for the NamespaceTree Control
3  *
4  * Copyright 2010 David Hedberg
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdio.h>
22
23 #define COBJMACROS
24 #define CONST_VTABLE
25
26 #include "shlobj.h"
27 #include "wine/test.h"
28
29 #include "msg.h"
30
31 static HWND hwnd;
32
33 /* "Intended for internal use" */
34 #define TVS_EX_NOSINGLECOLLAPSE 0x1
35
36 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
37 static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
38 static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**);
39 static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
40
41 #define NUM_MSG_SEQUENCES 1
42 #define TREEVIEW_SEQ_INDEX 0
43
44 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
45
46 /* Keep a copy of the last structure passed by TVM_SETITEMW */
47 static TVITEMEXW last_tvi;
48 static int tvi_count;
49
50 static void init_function_pointers(void)
51 {
52     HMODULE hmod;
53
54     hmod = GetModuleHandleA("shell32.dll");
55     pSHCreateShellItem = (void*)GetProcAddress(hmod, "SHCreateShellItem");
56     pSHGetIDListFromObject = (void*)GetProcAddress(hmod, "SHGetIDListFromObject");
57     pSHCreateItemFromParsingName = (void*)GetProcAddress(hmod, "SHCreateItemFromParsingName");
58     pSHGetSpecialFolderLocation = (void*)GetProcAddress(hmod, "SHGetSpecialFolderLocation");
59 }
60
61 /*******************************************************
62  * INameSpaceTreeControlEvents implementation.
63  */
64 enum { OnItemClick = 0, OnPropertyItemCommit, OnItemStateChanging, OnItemStateChanged,
65        OnSelectionChanged, OnKeyboardInput, OnBeforeExpand, OnAfterExpand, OnBeginLabelEdit,
66        OnEndLabelEdit, OnGetToolTip, OnBeforeItemDelete, OnItemAdded, OnItemDeleted,
67        OnBeforeContextMenu, OnAfterContextMenu, OnBeforeStateImageChange, OnGetDefaultIconIndex,
68        LastEvent };
69
70 typedef struct {
71     INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
72     UINT qi_called_count;     /* Keep track of calls to QueryInterface */
73     BOOL qi_enable_events;    /* If FALSE, QueryInterface returns only E_NOINTERFACE */
74     UINT count[LastEvent];    /* Keep track of calls to all On* functions. */
75     LONG ref;
76 } INameSpaceTreeControlEventsImpl;
77
78 static inline INameSpaceTreeControlEventsImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
79 {
80     return CONTAINING_RECORD(iface, INameSpaceTreeControlEventsImpl, INameSpaceTreeControlEvents_iface);
81 }
82
83 static HRESULT WINAPI NSTCEvents_fnQueryInterface(
84     INameSpaceTreeControlEvents* iface,
85     REFIID riid,
86     void **ppvObject)
87 {
88     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
89
90     This->qi_called_count++;
91
92     if(This->qi_enable_events && IsEqualIID(riid, &IID_INameSpaceTreeControlEvents))
93     {
94         IUnknown_AddRef(iface);
95         *ppvObject = iface;
96         return S_OK;
97     }
98
99     return E_NOINTERFACE;
100 }
101
102 static ULONG WINAPI NSTCEvents_fnAddRef(
103     INameSpaceTreeControlEvents* iface)
104 {
105     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
106
107     return InterlockedIncrement(&This->ref);
108 }
109
110 static ULONG WINAPI NSTCEvents_fnRelease(
111     INameSpaceTreeControlEvents* iface)
112 {
113     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
114
115     return InterlockedDecrement(&This->ref);
116 }
117
118 static HRESULT WINAPI NSTCEvents_fnOnItemClick(
119     INameSpaceTreeControlEvents* iface,
120     IShellItem *psi,
121     NSTCEHITTEST nstceHitTest,
122     NSTCECLICKTYPE nstceClickType)
123 {
124     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
125
126     ok(psi != NULL, "NULL IShellItem\n");
127     This->count[OnItemClick]++;
128     return E_NOTIMPL;
129 }
130
131 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(
132     INameSpaceTreeControlEvents* iface,
133     IShellItem *psi)
134 {
135     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
136
137     ok(psi != NULL, "NULL IShellItem\n");
138     This->count[OnPropertyItemCommit]++;
139     return E_NOTIMPL;
140 }
141
142 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(
143     INameSpaceTreeControlEvents* iface,
144     IShellItem *psi,
145     NSTCITEMSTATE nstcisMask,
146     NSTCITEMSTATE nstcisState)
147 {
148     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
149
150     ok(psi != NULL, "NULL IShellItem\n");
151     This->count[OnItemStateChanging]++;
152     return E_NOTIMPL;
153 }
154
155 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(
156     INameSpaceTreeControlEvents* iface,
157     IShellItem *psi,
158     NSTCITEMSTATE nstcisMask,
159     NSTCITEMSTATE nstcisState)
160 {
161     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
162
163     ok(psi != NULL, "NULL IShellItem\n");
164     This->count[OnItemStateChanged]++;
165     return E_NOTIMPL;
166 }
167
168 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(
169     INameSpaceTreeControlEvents* iface,
170     IShellItemArray *psiaSelection)
171 {
172     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
173
174     ok(psiaSelection != NULL, "IShellItemArray was NULL.\n");
175     if(psiaSelection)
176     {
177         HRESULT hr;
178         DWORD count = 0xdeadbeef;
179         hr = IShellItemArray_GetCount(psiaSelection, &count);
180         ok(hr == S_OK, "Got 0x%08x\n", hr);
181         ok(count == 1, "Got count 0x%x\n", count);
182     }
183     This->count[OnSelectionChanged]++;
184     return E_NOTIMPL;
185 }
186
187 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(
188     INameSpaceTreeControlEvents* iface,
189     UINT uMsg,
190     WPARAM wParam,
191     LPARAM lParam)
192 {
193     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
194
195     This->count[OnKeyboardInput]++;
196     ok(wParam == 0x1234, "Got unexpected wParam %lx\n", wParam);
197     ok(lParam == 0x1234, "Got unexpected lParam %lx\n", lParam);
198     return E_NOTIMPL;
199 }
200
201 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(
202     INameSpaceTreeControlEvents* iface,
203     IShellItem *psi)
204 {
205     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
206
207     ok(psi != NULL, "NULL IShellItem\n");
208     This->count[OnBeforeExpand]++;
209     return E_NOTIMPL;
210 }
211
212 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(
213     INameSpaceTreeControlEvents* iface,
214     IShellItem *psi)
215 {
216     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
217
218     ok(psi != NULL, "NULL IShellItem\n");
219     This->count[OnAfterExpand]++;
220     return E_NOTIMPL;
221 }
222
223 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(
224     INameSpaceTreeControlEvents* iface,
225     IShellItem *psi)
226 {
227     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
228
229     ok(psi != NULL, "NULL IShellItem\n");
230     This->count[OnBeginLabelEdit]++;
231     return E_NOTIMPL;
232 }
233
234 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(
235     INameSpaceTreeControlEvents* iface,
236     IShellItem *psi)
237 {
238     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
239
240     ok(psi != NULL, "NULL IShellItem\n");
241     This->count[OnEndLabelEdit]++;
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(
246     INameSpaceTreeControlEvents* iface,
247     IShellItem *psi,
248     LPWSTR pszTip,
249     int cchTip)
250 {
251     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
252
253     ok(psi != NULL, "NULL IShellItem\n");
254     This->count[OnGetToolTip]++;
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(
259     INameSpaceTreeControlEvents* iface,
260     IShellItem *psi)
261 {
262     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
263
264     ok(psi != NULL, "NULL IShellItem\n");
265     This->count[OnBeforeItemDelete]++;
266     return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(
270     INameSpaceTreeControlEvents* iface,
271     IShellItem *psi,
272     BOOL fIsRoot)
273 {
274     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
275
276     ok(psi != NULL, "NULL IShellItem\n");
277     This->count[OnItemAdded]++;
278     return S_OK;
279 }
280
281 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(
282     INameSpaceTreeControlEvents* iface,
283     IShellItem *psi,
284     BOOL fIsRoot)
285 {
286     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
287
288     ok(psi != NULL, "NULL IShellItem\n");
289     This->count[OnItemDeleted]++;
290     return S_OK;
291 }
292
293 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(
294     INameSpaceTreeControlEvents* iface,
295     IShellItem *psi,
296     REFIID riid,
297     void **ppv)
298 {
299     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
300
301     This->count[OnBeforeContextMenu]++;
302     return E_NOTIMPL;
303 }
304
305 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(
306     INameSpaceTreeControlEvents* iface,
307     IShellItem *psi,
308     IContextMenu *pcmIn,
309     REFIID riid,
310     void **ppv)
311 {
312     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
313
314     This->count[OnAfterContextMenu]++;
315     return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(
319     INameSpaceTreeControlEvents* iface,
320     IShellItem *psi)
321 {
322     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
323
324     ok(psi != NULL, "NULL IShellItem\n");
325     This->count[OnBeforeStateImageChange]++;
326     return E_NOTIMPL;
327 }
328
329 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(
330     INameSpaceTreeControlEvents* iface,
331     IShellItem *psi,
332     int *piDefaultIcon,
333     int *piOpenIcon)
334 {
335     INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
336
337     ok(psi != NULL, "NULL IShellItem\n");
338     This->count[OnGetDefaultIconIndex]++;
339     return E_NOTIMPL;
340 }
341
342 static const INameSpaceTreeControlEventsVtbl vt_NSTCEvents = {
343     NSTCEvents_fnQueryInterface,
344     NSTCEvents_fnAddRef,
345     NSTCEvents_fnRelease,
346     NSTCEvents_fnOnItemClick,
347     NSTCEvents_fnOnPropertyItemCommit,
348     NSTCEvents_fnOnItemStateChanging,
349     NSTCEvents_fnOnItemStateChanged,
350     NSTCEvents_fnOnSelectionChanged,
351     NSTCEvents_fnOnKeyboardInput,
352     NSTCEvents_fnOnBeforeExpand,
353     NSTCEvents_fnOnAfterExpand,
354     NSTCEvents_fnOnBeginLabelEdit,
355     NSTCEvents_fnOnEndLabelEdit,
356     NSTCEvents_fnOnGetToolTip,
357     NSTCEvents_fnOnBeforeItemDelete,
358     NSTCEvents_fnOnItemAdded,
359     NSTCEvents_fnOnItemDeleted,
360     NSTCEvents_fnOnBeforeContextMenu,
361     NSTCEvents_fnOnAfterContextMenu,
362     NSTCEvents_fnOnBeforeStateImageChange,
363     NSTCEvents_fnOnGetDefaultIconIndex
364 };
365
366 static INameSpaceTreeControlEventsImpl *create_nstc_events(void)
367 {
368     INameSpaceTreeControlEventsImpl *This;
369     This = HeapAlloc(GetProcessHeap(), 0, sizeof(INameSpaceTreeControlEventsImpl));
370     This->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_NSTCEvents;
371     This->ref = 1;
372
373     return This;
374 }
375
376 /*********************************************************************
377  * Event count checking
378  */
379 static void ok_no_events_(INameSpaceTreeControlEventsImpl *impl,
380                           const char *file, int line)
381 {
382     UINT i;
383     for(i = 0; i < LastEvent; i++)
384     {
385         ok_(file, line)
386             (!impl->count[i], "Got event %d, count %d\n", i, impl->count[i]);
387         impl->count[i] = 0;
388     }
389 }
390 #define ok_no_events(impl)                      \
391     ok_no_events_(impl, __FILE__, __LINE__)
392
393 #define ok_event_count_broken(impl, event, c, b)                        \
394     do { ok(impl->count[event] == c || broken(impl->count[event] == b), \
395             "Got event %d, count %d\n", event, impl->count[event]);     \
396         impl->count[event] = 0;                                         \
397     } while(0)
398
399 #define ok_event_count(impl, event, c)          \
400     ok_event_count_broken(impl, event, c, -1)
401
402 #define ok_event_broken(impl, event)                                    \
403     do { ok(impl->count[event] || broken(!impl->count[event]),          \
404             "No event.\n");                                             \
405         impl->count[event] = 0;                                         \
406     } while(0)
407
408 #define ok_event(impl, event)                                           \
409     do { ok(impl->count[event], "No event %d.\n", event);               \
410         impl->count[event] = 0;                                         \
411     } while(0)
412
413 /* Process some messages */
414 static void process_msgs(void)
415 {
416     MSG msg;
417     BOOL got_msg;
418     do {
419         got_msg = FALSE;
420         Sleep(100);
421         while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
422         {
423             TranslateMessage(&msg);
424             DispatchMessage(&msg);
425             got_msg = TRUE;
426         }
427     } while(got_msg);
428
429     /* There seem to be a timer that sometimes fires after about
430        500ms, we need to wait for it. Failing to wait can result in
431        seemingly sporadic selection change events. (Timer ID is 87,
432        sending WM_TIMER manually does not seem to help us.) */
433     Sleep(500);
434
435     while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
436     {
437         TranslateMessage(&msg);
438         DispatchMessage(&msg);
439     }
440 }
441
442 /** Some functions from shell32/tests/shlfolder.c */
443 /* creates a file with the specified name for tests */
444 static void CreateTestFile(const CHAR *name)
445 {
446     HANDLE file;
447     DWORD written;
448
449     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
450     if (file != INVALID_HANDLE_VALUE)
451     {
452        WriteFile(file, name, strlen(name), &written, NULL);
453        WriteFile(file, "\n", strlen("\n"), &written, NULL);
454        CloseHandle(file);
455     }
456 }
457 /* initializes the tests */
458 static void CreateFilesFolders(void)
459 {
460     CreateDirectoryA(".\\testdir", NULL);
461     CreateTestFile  (".\\testdir\\test1.txt ");
462     CreateTestFile  (".\\testdir\\test2.txt ");
463     CreateTestFile  (".\\testdir\\test3.txt ");
464     CreateDirectoryA(".\\testdir\\testdir2 ", NULL);
465     CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL);
466 }
467
468 /* cleans after tests */
469 static void Cleanup(void)
470 {
471     DeleteFileA(".\\testdir\\test1.txt");
472     DeleteFileA(".\\testdir\\test2.txt");
473     DeleteFileA(".\\testdir\\test3.txt");
474     RemoveDirectoryA(".\\testdir\\testdir2\\subdir");
475     RemoveDirectoryA(".\\testdir\\testdir2");
476     RemoveDirectoryA(".\\testdir");
477 }
478
479 /* Based on PathAddBackslashW from dlls/shlwapi/path.c */
480 static LPWSTR myPathAddBackslashW( LPWSTR lpszPath )
481 {
482   size_t iLen;
483
484   if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH)
485     return NULL;
486
487   if (iLen)
488   {
489     lpszPath += iLen;
490     if (lpszPath[-1] != '\\')
491     {
492       *lpszPath++ = '\\';
493       *lpszPath = '\0';
494     }
495   }
496   return lpszPath;
497 }
498
499 static HWND get_treeview_hwnd(INameSpaceTreeControl *pnstc)
500 {
501     IOleWindow *pow;
502     HRESULT hr;
503     HWND treeview = NULL;
504
505     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
506     ok(hr == S_OK, "Got 0x%08x\n", hr);
507     if(SUCCEEDED(hr))
508     {
509         HWND host;
510         hr = IOleWindow_GetWindow(pow, &host);
511         ok(hr == S_OK, "Got 0x%08x\n", hr);
512         if(SUCCEEDED(hr))
513             treeview = FindWindowExW(host, NULL, WC_TREEVIEWW, NULL);
514         IOleWindow_Release(pow);
515     }
516
517     return treeview;
518 }
519
520 static LRESULT WINAPI treeview_subclass_proc(HWND hwnd_tv, UINT message, WPARAM wParam, LPARAM lParam)
521 {
522     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrW(hwnd_tv, GWLP_USERDATA);
523     static LONG defwndproc_counter = 0;
524     LRESULT ret;
525     struct message msg;
526
527     msg.message = message;
528     msg.flags = sent|wparam|lparam;
529     if (defwndproc_counter) msg.flags |= defwinproc;
530     msg.wParam = wParam;
531     msg.lParam = lParam;
532     msg.id = 0;
533     add_message(sequences, TREEVIEW_SEQ_INDEX, &msg);
534
535     if(message == TVM_SETITEMW)
536     {
537         memcpy(&last_tvi, (void*)lParam, sizeof(TVITEMEXW));
538         tvi_count++;
539     }
540
541     defwndproc_counter++;
542     ret = CallWindowProcW(oldproc, hwnd_tv, message, wParam, lParam);
543     defwndproc_counter--;
544     return ret;
545 }
546
547 static BOOL subclass_treeview(INameSpaceTreeControl *pnstc)
548 {
549     HWND hwnd_tv;
550     WNDPROC oldproc = NULL;
551
552     hwnd_tv = get_treeview_hwnd(pnstc);
553     if(hwnd_tv)
554     {
555         oldproc = (WNDPROC)SetWindowLongPtrW(hwnd_tv, GWLP_WNDPROC,
556                                              (LONG_PTR)treeview_subclass_proc);
557         SetWindowLongPtrW(hwnd_tv, GWLP_USERDATA, (LONG_PTR)oldproc);
558         ok(oldproc != NULL, "Failed to subclass.\n");
559     }
560
561     return oldproc != 0;
562 }
563
564 static UINT get_msg_count(struct msg_sequence **seq, int sequence_index, UINT message)
565 {
566     struct msg_sequence *msg_seq = seq[sequence_index];
567     UINT i, count = 0;
568
569     for(i = 0; i < msg_seq->count ; i++)
570         if(msg_seq->sequence[i].message == message)
571             count++;
572
573     return count;
574 }
575
576 /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
577 static BOOL test_initialization(void)
578 {
579     INameSpaceTreeControl *pnstc;
580     IOleWindow *pow;
581     IUnknown *punk;
582     HWND hwnd_host1;
583     LONG lres;
584     HRESULT hr;
585     RECT rc;
586
587     hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
588                           &IID_INameSpaceTreeControl, (void**)&pnstc);
589     ok(hr == S_OK || hr == REGDB_E_CLASSNOTREG, "Got 0x%08x\n", hr);
590     if(FAILED(hr))
591     {
592         return FALSE;
593     }
594
595     hr = INameSpaceTreeControl_Initialize(pnstc, NULL, NULL, 0);
596     ok(hr == HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD), "Got (0x%08x)\n", hr);
597
598     hr = INameSpaceTreeControl_Initialize(pnstc, (HWND)0xDEADBEEF, NULL, 0);
599     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE), "Got (0x%08x)\n", hr);
600
601     ZeroMemory(&rc, sizeof(RECT));
602     hr = INameSpaceTreeControl_Initialize(pnstc, NULL, &rc, 0);
603     ok(hr == HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD), "Got (0x%08x)\n", hr);
604
605     hr = INameSpaceTreeControl_Initialize(pnstc, (HWND)0xDEADBEEF, &rc, 0);
606     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE), "Got (0x%08x)\n", hr);
607
608     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
609     ok(hr == S_OK, "Got (0x%08x)\n", hr);
610     if(SUCCEEDED(hr))
611     {
612         hr = IOleWindow_GetWindow(pow, &hwnd_host1);
613         ok(hr == S_OK, "Got (0x%08x)\n", hr);
614         ok(hwnd_host1 == NULL, "hwnd is not null.\n");
615
616         hr = IOleWindow_ContextSensitiveHelp(pow, TRUE);
617         ok(hr == E_NOTIMPL, "Got (0x%08x)\n", hr);
618         hr = IOleWindow_ContextSensitiveHelp(pow, FALSE);
619         ok(hr == E_NOTIMPL, "Got (0x%08x)\n", hr);
620         IOleWindow_Release(pow);
621     }
622
623     hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, NULL, 0);
624     ok(hr == S_OK, "Got (0x%08x)\n", hr);
625     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
626     ok(hr == S_OK, "Got 0x%08x\n", hr);
627     if(SUCCEEDED(hr))
628     {
629         static const CHAR namespacetree[] = "NamespaceTreeControl";
630         char buf[1024];
631         LONG style, expected_style;
632         HWND hwnd_tv;
633         hr = IOleWindow_GetWindow(pow, &hwnd_host1);
634         ok(hr == S_OK, "Got (0x%08x)\n", hr);
635         ok(hwnd_host1 != NULL, "hwnd_host1 is null.\n");
636         buf[0] = '\0';
637         GetClassNameA(hwnd_host1, buf, 1024);
638         ok(!lstrcmpA(namespacetree, buf), "Class name was %s\n", buf);
639
640         expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
641         style = GetWindowLongPtrW(hwnd_host1, GWL_STYLE);
642         ok(style == expected_style, "Got style %08x\n", style);
643
644         expected_style = 0;
645         style = GetWindowLongPtrW(hwnd_host1, GWL_EXSTYLE);
646         ok(style == expected_style, "Got style %08x\n", style);
647
648         expected_style = 0;
649         style = SendMessageW(hwnd_host1, TVM_GETEXTENDEDSTYLE, 0, 0);
650         ok(style == expected_style, "Got 0x%08x\n", style);
651
652         hwnd_tv = FindWindowExW(hwnd_host1, NULL, WC_TREEVIEWW, NULL);
653         ok(hwnd_tv != NULL, "Failed to get treeview hwnd.\n");
654         if(hwnd_tv)
655         {
656             expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
657                 WS_CLIPCHILDREN | WS_TABSTOP | TVS_NOHSCROLL |
658                 TVS_NONEVENHEIGHT | TVS_INFOTIP | TVS_TRACKSELECT | TVS_EDITLABELS;
659             style = GetWindowLongPtrW(hwnd_tv, GWL_STYLE);
660             ok(style == expected_style, "Got style %08x\n", style);
661
662             expected_style = 0;
663             style = GetWindowLongPtrW(hwnd_tv, GWL_EXSTYLE);
664             ok(style == expected_style, "Got style %08x\n", style);
665
666             expected_style = TVS_EX_NOSINGLECOLLAPSE | TVS_EX_DOUBLEBUFFER |
667                 TVS_EX_RICHTOOLTIP | TVS_EX_DRAWIMAGEASYNC;
668             style = SendMessageW(hwnd_tv, TVM_GETEXTENDEDSTYLE, 0, 0);
669             todo_wine ok(style == expected_style, "Got 0x%08x\n", style);
670         }
671
672         IOleWindow_Release(pow);
673     }
674
675     if(0)
676     {
677         /* The control can be initialized again without crashing, but
678          * the reference counting will break. */
679         hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, &rc, 0);
680         ok(hr == S_OK, "Got (0x%08x)\n", hr);
681         hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
682         if(SUCCEEDED(hr))
683         {
684             HWND hwnd_host2;
685             hr = IOleWindow_GetWindow(pow, &hwnd_host2);
686             ok(hr == S_OK, "Got (0x%08x)\n", hr);
687             ok(hwnd_host1 != hwnd_host2, "Same hwnd.\n");
688             IOleWindow_Release(pow);
689         }
690     }
691
692     /* Some "random" interfaces */
693     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceObject, (void**)&punk);
694     ok(hr == E_NOINTERFACE || 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 || 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 || hr == S_OK /* vista, w2k8 */, "Got (0x%08x)\n", hr);
701     if(SUCCEEDED(hr)) IUnknown_Release(punk);
702
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);
713
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);
719
720     DestroyWindow(hwnd_host1);
721     lres = INameSpaceTreeControl_Release(pnstc);
722     ok(!lres, "lres was %d\n", lres);
723
724     return TRUE;
725 }
726
727 static void verify_root_order_(INameSpaceTreeControl *pnstc, IShellItem **roots,
728                                const char *file, int line)
729 {
730     HRESULT hr;
731     IShellItemArray *psia;
732
733     hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia);
734     ok_(file,line) (hr == S_OK, "GetRootItems: got (0x%08x)\n", hr);
735     if(SUCCEEDED(hr))
736     {
737         DWORD i, expected, count = -1;
738         hr = IShellItemArray_GetCount(psia, &count);
739         ok_(file,line) (hr == S_OK, "Got (0x%08x)\n", hr);
740
741         for(expected = 0; roots[expected] != NULL; expected++);
742         ok_(file,line) (count == expected, "Got %d roots, expected %d\n", count, expected);
743
744         for(i = 0; i < count && roots[i] != NULL; i++)
745         {
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))
750             {
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);
755             }
756         }
757         IShellItemArray_Release(psia);
758     }
759 }
760 #define verify_root_order(pnstc, psi_a)         \
761     verify_root_order_(pnstc, psi_a, __FILE__, __LINE__)
762
763 static void test_basics(void)
764 {
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];
784     static const WCHAR testdirW[] = {'t','e','s','t','d','i','r',0};
785     static const WCHAR testdir2W[] =
786         {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','2',0};
787     static const WCHAR test1W[] =
788         {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
789     static const WCHAR explorerW[] = {'E','x','p','l','o','r','e','r',0};
790     static const WCHAR randomW[] = {'_','_','h','e','l','l','o',0};
791
792     /* These should exist on platforms supporting the NSTC */
793     ok(pSHCreateShellItem != NULL, "No SHCreateShellItem.\n");
794     ok(pSHCreateItemFromParsingName != NULL, "No SHCreateItemFromParsingName\n");
795     ok(pSHGetIDListFromObject != NULL, "No SHCreateShellItem.\n");
796     ok(pSHCreateItemFromParsingName != NULL, "No SHCreateItemFromParsingName\n");
797
798     /* Create ShellItems for testing. */
799     SHGetDesktopFolder(&psfdesktop);
800     hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl_desktop);
801     ok(hr == S_OK, "Got 0x%08x\n", hr);
802     if(SUCCEEDED(hr))
803     {
804         hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop);
805         ok(hr == S_OK, "Got 0x%08x\n", hr);
806         if(SUCCEEDED(hr))
807         {
808             hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop2);
809             ok(hr == S_OK, "Got 0x%08x\n", hr);
810             if(FAILED(hr)) IShellItem_Release(psidesktop);
811         }
812         ILFree(pidl_desktop);
813     }
814     IShellFolder_Release(psfdesktop);
815
816     if(FAILED(hr))
817     {
818         win_skip("Test setup failed.\n");
819         return;
820     }
821
822     ok(psidesktop != psidesktop2, "psidesktop == psidesktop2\n");
823
824     CreateFilesFolders();
825     GetCurrentDirectoryW(MAX_PATH, curdirW);
826     ok(lstrlenW(curdirW), "Got 0 length string.\n");
827
828     lstrcpyW(buf, curdirW);
829     myPathAddBackslashW(buf);
830     lstrcatW(buf, testdirW);
831     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitestdir);
832     ok(hr == S_OK, "Got 0x%08x\n", hr);
833     if(FAILED(hr)) goto cleanup;
834     lstrcpyW(buf, curdirW);
835     myPathAddBackslashW(buf);
836     lstrcatW(buf, testdir2W);
837     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitestdir2);
838     ok(hr == S_OK, "Got 0x%08x\n", hr);
839     if(FAILED(hr)) goto cleanup;
840     lstrcpyW(buf, curdirW);
841     myPathAddBackslashW(buf);
842     lstrcatW(buf, test1W);
843     hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitest1);
844     ok(hr == S_OK, "Got 0x%08x\n", hr);
845     if(FAILED(hr)) goto cleanup;
846
847     hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
848                           &IID_INameSpaceTreeControl, (void**)&pnstc);
849     ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr);
850
851     /* Some tests on an uninitialized control */
852     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
853     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
854     hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop);
855     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
856     hr = INameSpaceTreeControl_RemoveRoot(pnstc, NULL);
857     ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr);
858     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_NONFOLDERS, 0, NULL);
859     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
860     process_msgs();
861
862     /* Initialize the control */
863     rc.top = rc.left = 0; rc.right = rc.bottom = 200;
864     hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, &rc, 0);
865     ok(hr == S_OK, "Got (0x%08x)\n", hr);
866
867
868     /* Set/GetControlStyle(2) */
869     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_INameSpaceTreeControl2, (void**)&pnstc2);
870     ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Got 0x%08x\n", hr);
871     if(SUCCEEDED(hr))
872     {
873         DWORD tmp;
874         NSTCSTYLE style;
875         NSTCSTYLE2 style2;
876         static const NSTCSTYLE2 styles2[] =
877             { NSTCS2_INTERRUPTNOTIFICATIONS,NSTCS2_SHOWNULLSPACEMENU,
878               NSTCS2_DISPLAYPADDING,NSTCS2_DISPLAYPINNEDONLY,
879               NTSCS2_NOSINGLETONAUTOEXPAND,NTSCS2_NEVERINSERTNONENUMERATED, 0};
880
881
882         /* We can use this to differentiate between two versions of
883          * this interface. Windows 7 returns hr == S_OK. */
884         hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0);
885         ok(hr == S_OK || broken(hr == E_FAIL), "Got 0x%08x\n", hr);
886         if(hr == S_OK)
887         {
888             static const NSTCSTYLE styles_setable[] =
889                 { NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND,
890                   NSTCS_FULLROWSELECT,NSTCS_HORIZONTALSCROLL,
891                   NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP,
892                   NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP,
893                   NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS,
894                   NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES,
895                   NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON,
896                   NSTCS_SHOWREFRESHBUTTON, 0};
897             static const NSTCSTYLE styles_nonsetable[] =
898                 { NSTCS_SPRINGEXPAND, NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL,
899                   NSTCS_FADEINOUTEXPANDOS,
900                   NSTCS_PARTIALCHECKBOXES, NSTCS_EXCLUSIONCHECKBOXES,
901                   NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS,0};
902
903             /* Set/GetControlStyle */
904             style = style2 = 0xdeadbeef;
905             hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
906             ok(hr == S_OK, "Got 0x%08x\n", hr);
907             ok(style == 0, "Got style %x\n", style);
908
909             hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0xFFFFFFF);
910             ok(hr == S_OK, "Got 0x%08x\n", hr);
911
912             hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0);
913             ok(hr == E_FAIL, "Got 0x%08x\n", hr);
914             hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF);
915             ok(hr == E_FAIL, "Got 0x%08x\n", hr);
916
917             tmp = 0;
918             for(i = 0; styles_setable[i] != 0; i++)
919             {
920                 hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], styles_setable[i]);
921                 ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]);
922                 if(SUCCEEDED(hr)) tmp |= styles_setable[i];
923             }
924             for(i = 0; styles_nonsetable[i] != 0; i++)
925             {
926                 hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], styles_nonsetable[i]);
927                 ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]);
928             }
929
930             hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
931             ok(hr == S_OK, "Got 0x%08x\n", hr);
932             ok(style == tmp, "Got style %x (expected %x)\n", style, tmp);
933             if(SUCCEEDED(hr))
934             {
935                 DWORD tmp2;
936                 for(i = 0; styles_setable[i] != 0; i++)
937                 {
938                     hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, styles_setable[i], &tmp2);
939                     ok(hr == S_OK, "Got 0x%08x\n", hr);
940                     ok(tmp2 == (style & styles_setable[i]), "Got %x\n", tmp2);
941                 }
942             }
943
944             for(i = 0; styles_setable[i] != 0; i++)
945             {
946                 hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], 0);
947                 ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]);
948             }
949             for(i = 0; styles_nonsetable[i] != 0; i++)
950             {
951                 hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], 0);
952                 ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]);
953             }
954             hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
955             ok(hr == S_OK, "Got 0x%08x\n", hr);
956             ok(style == 0, "Got style %x\n", style);
957
958             /* Set/GetControlStyle2 */
959             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
960             ok(hr == S_OK, "Got 0x%08x\n", hr);
961             ok(style2 == 0, "Got style %x\n", style2);
962
963             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0);
964             ok(hr == S_OK, "Got 0x%08x\n", hr);
965             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0xFFFFFFFF);
966             ok(hr == S_OK, "Got 0x%08x\n", hr);
967
968             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0);
969             ok(hr == S_OK, "Got 0x%08x\n", hr);
970             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF);
971             ok(hr == S_OK, "Got 0x%08x\n", hr);
972
973             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0);
974             ok(hr == S_OK, "Got 0x%08x\n", hr);
975             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
976             ok(hr == S_OK, "Got 0x%08x\n", hr);
977             ok(style2 == 0x00000000, "Got style %x\n", style2);
978
979             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
980             ok(hr == S_OK, "Got 0x%08x\n", hr);
981             ok(style2 == 0, "Got style %x\n", style2);
982
983             tmp = 0;
984             for(i = 0; styles2[i] != 0; i++)
985             {
986                 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]);
987                 ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
988                 if(SUCCEEDED(hr)) tmp |= styles2[i];
989             }
990
991             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
992             ok(hr == S_OK, "Got 0x%08x\n", hr);
993             ok(style2 == tmp, "Got style %x (expected %x)\n", style2, tmp);
994             if(SUCCEEDED(hr))
995             {
996                 DWORD tmp2;
997                 for(i = 0; styles2[i] != 0; i++)
998                 {
999                     hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, styles2[i], &tmp2);
1000                     ok(hr == S_OK, "Got 0x%08x\n", hr);
1001                     ok(tmp2 == (style2 & styles2[i]), "Got %x\n", tmp2);
1002                 }
1003             }
1004
1005             for(i = 0; styles2[i] != 0; i++)
1006             {
1007                 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], 0);
1008                 ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
1009             }
1010             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
1011             ok(hr == S_OK, "Got 0x%08x\n", hr);
1012             ok(style2 == 0, "Got style %x (expected 0)\n", style2);
1013         }
1014         else
1015         {
1016             /* 64-bit Windows Vista (others?) seems to have a somewhat
1017              * different idea of how the methods of this interface
1018              * should behave. */
1019
1020             static const NSTCSTYLE styles[] =
1021                 { NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND,
1022                   NSTCS_FULLROWSELECT,NSTCS_SPRINGEXPAND,NSTCS_HORIZONTALSCROLL,
1023                   NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL,
1024                   NSTCS_FADEINOUTEXPANDOS,
1025                   NSTCS_PARTIALCHECKBOXES,NSTCS_EXCLUSIONCHECKBOXES,
1026                   NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS,
1027                   NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP,
1028                   NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP,
1029                   NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS,
1030                   NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES,
1031                   NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON,
1032                   NSTCS_SHOWREFRESHBUTTON, 0};
1033             trace("Detected broken INameSpaceTreeControl2.\n");
1034
1035             style = 0xdeadbeef;
1036             hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
1037             ok(hr == S_OK, "Got 0x%08x\n", hr);
1038             ok(style == 0xdeadbeef, "Got style %x\n", style);
1039
1040             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
1041             ok(hr == S_OK, "Got 0x%08x\n", hr);
1042             ok(style2 == 0, "Got style %x\n", style2);
1043
1044             tmp = 0;
1045             for(i = 0; styles[i] != 0; i++)
1046             {
1047                 hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles[i], styles[i]);
1048                 ok(hr == E_FAIL || ((styles[i] & NSTCS_SPRINGEXPAND) && hr == S_OK),
1049                    "Got 0x%08x (%x)\n", hr, styles[i]);
1050                 if(SUCCEEDED(hr)) tmp |= styles[i];
1051             }
1052
1053             style = 0xdeadbeef;
1054             hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, tmp, &style);
1055             ok(hr == S_OK, "Got 0x%08x\n", hr);
1056             ok(style == 0xdeadbeef, "Got style %x\n", style);
1057
1058             tmp = 0;
1059             for(i = 0; styles2[i] != 0; i++)
1060             {
1061                 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]);
1062                 ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
1063                 if(SUCCEEDED(hr)) tmp |= styles2[i];
1064             }
1065
1066             style2 = 0xdeadbeef;
1067             hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
1068             ok(hr == S_OK, "Got 0x%08x\n", hr);
1069             ok(style2 == tmp, "Got style %x\n", style2);
1070
1071         }
1072
1073         INameSpaceTreeControl2_Release(pnstc2);
1074     }
1075     else
1076     {
1077         skip("INameSpaceTreeControl2 missing.\n");
1078     }
1079
1080     hr = INameSpaceTreeControl_RemoveRoot(pnstc, NULL);
1081     ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr);
1082
1083     /* Append / Insert root */
1084     if(0)
1085     {
1086         /* Crashes under Windows 7 */
1087         INameSpaceTreeControl_AppendRoot(pnstc, NULL, SHCONTF_FOLDERS, 0, NULL);
1088         INameSpaceTreeControl_InsertRoot(pnstc, 0, NULL, SHCONTF_FOLDERS, 0, NULL);
1089     }
1090
1091     /* Note the usage of psidesktop and psidesktop2 */
1092     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1093     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1094     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1095     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1096     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop2, SHCONTF_FOLDERS, 0, NULL);
1097     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1098     process_msgs();
1099
1100     hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop);
1101     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1102     hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop);
1103     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1104     hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop);
1105     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1106
1107     hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop);
1108     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
1109     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1110     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
1111
1112     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1113     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1114     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1115     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1116
1117     hr = INameSpaceTreeControl_InsertRoot(pnstc, 0, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1118     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1119     hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1120     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1121     hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1122     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1123     hr = INameSpaceTreeControl_InsertRoot(pnstc, 50, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1124     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1125     hr = INameSpaceTreeControl_InsertRoot(pnstc, 1, psidesktop, SHCONTF_FOLDERS, 0, NULL);
1126     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1127
1128     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1129     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1130
1131     /* GetRootItems */
1132     if(0)
1133     {
1134         /* Crashes on native. */
1135         INameSpaceTreeControl_GetRootItems(pnstc, NULL);
1136     }
1137
1138     hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia);
1139     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
1140
1141     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, 0, 0, NULL);
1142     ok(hr == S_OK, "Got 0x%08x\n", hr);
1143     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop2, 0, 0, NULL);
1144     ok(hr == S_OK, "Got 0x%08x\n", hr);
1145     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, 0, 0, NULL);
1146     ok(hr == S_OK, "Got 0x%08x\n", hr);
1147     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, 0, 0, NULL);
1148     ok(hr == S_OK, "Got 0x%08x\n", hr);
1149
1150     roots[0] = psidesktop;
1151     roots[1] = psidesktop2;
1152     roots[2] = psitestdir;
1153     roots[3] = psitestdir2;
1154     roots[4] = NULL;
1155     verify_root_order(pnstc, roots);
1156
1157     hr = INameSpaceTreeControl_InsertRoot(pnstc, 0, psitestdir2, 0, 0, NULL);
1158     ok(hr == S_OK, "Got 0x%08x\n", hr);
1159
1160     roots[0] = psitestdir2;
1161     roots[1] = psidesktop;
1162     roots[2] = psidesktop2;
1163     roots[3] = psitestdir;
1164     roots[4] = psitestdir2;
1165     roots[5] = NULL;
1166     verify_root_order(pnstc, roots);
1167
1168     hr = INameSpaceTreeControl_InsertRoot(pnstc, 5, psidesktop, 0, 0, NULL);
1169     ok(hr == S_OK, "Got 0x%08x\n", hr);
1170
1171     roots[5] = psidesktop;
1172     roots[6] = NULL;
1173     verify_root_order(pnstc, roots);
1174
1175     hr = INameSpaceTreeControl_InsertRoot(pnstc, 3, psitestdir2, 0, 0, NULL);
1176     ok(hr == S_OK, "Got 0x%08x\n", hr);
1177
1178     roots[3] = psitestdir2;
1179     roots[4] = psitestdir;
1180     roots[5] = psitestdir2;
1181     roots[6] = psidesktop;
1182     roots[7] = NULL;
1183     verify_root_order(pnstc, roots);
1184
1185     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, 0, 0, NULL);
1186     ok(hr == S_OK, "Got 0x%08x\n", hr);
1187
1188     roots[7] = psitestdir2;
1189     roots[8] = NULL;
1190     verify_root_order(pnstc, roots);
1191
1192     hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, 0, 0, NULL);
1193     ok(hr == S_OK, "Got 0x%08x\n", hr);
1194
1195     roots[0] = psidesktop;
1196     roots[1] = psitestdir2;
1197     roots[2] = psidesktop;
1198     roots[3] = psidesktop2;
1199     roots[4] = psitestdir2;
1200     roots[5] = psitestdir;
1201     roots[6] = psitestdir2;
1202     roots[7] = psidesktop;
1203     roots[8] = psitestdir2;
1204     roots[9] = NULL;
1205     verify_root_order(pnstc, roots);
1206
1207     /* CollapseAll */
1208     hr = INameSpaceTreeControl_CollapseAll(pnstc);
1209     ok(hr == S_OK, "Got 0x%08x\n", hr);
1210
1211     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1212     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1213
1214     hr = INameSpaceTreeControl_CollapseAll(pnstc);
1215     ok(hr == S_OK, "Got 0x%08x\n", hr);
1216
1217     /* SetItemState message checks */
1218     res = subclass_treeview(pnstc);
1219     ok(res, "Failed to subclass treeview.\n");
1220     if(res)
1221     {
1222         UINT isMask, isFlags;
1223
1224         hr = INameSpaceTreeControl_AppendRoot(
1225             pnstc, psidesktop, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, 0, NULL);
1226         ok(hr == S_OK, "Got (0x%08x)\n", hr);
1227         flush_sequences(sequences, NUM_MSG_SEQUENCES);
1228
1229         /* A special case -
1230          *  The first expansion results in an "unrelated" TVM_SETITEMW being sent
1231          *  (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) )
1232          */
1233         tvi_count = 0;
1234         hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop,
1235                                                 NSTCIS_EXPANDED, NSTCIS_EXPANDED);
1236         ok(hr == S_OK, "Got 0x%08x\n", hr);
1237         todo_wine
1238         {
1239             ok(tvi_count == 1, "Got %d\n", tvi_count);
1240             ok(last_tvi.mask == 0x50, "Got mask %x, expected 0x50\n", last_tvi.mask);
1241         }
1242
1243         tvi_count = 0;
1244         hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop,
1245                                                 NSTCIS_EXPANDED, NSTCIS_EXPANDED);
1246         ok(hr == S_OK, "Got 0x%08x\n", hr);
1247         ok(tvi_count == 0, "Got %d\n", tvi_count);
1248
1249         /* Test all the combinations of NSTCIS_SELECTED to NSTCIS_SELECTEDNOEXPAND */
1250         flush_sequences(sequences, NUM_MSG_SEQUENCES);
1251         for(isMask = 0; isMask <= 0x1f; isMask++)
1252         {
1253             for(isFlags = 0; isFlags <= 0x1f; isFlags++)
1254             {
1255                 UINT select_sent, select_sent_vista, ensurev_sent, expand_sent;
1256                 TVITEMEXW tviexp;
1257                 UINT msg_count;
1258
1259                 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1260                 tvi_count = 0;
1261
1262                 hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, isMask, isFlags);
1263                 ok(hr == S_OK, "(%x|%x)Got 0x%08x\n", isMask, isFlags, hr);
1264
1265                 /*****************************/
1266                 /* Calculate expected values */
1267                 /*****************************/
1268
1269                 /* Number of TVM_SELECTITEM/TVM_ENSUREVISIBLE and TVM_EXPAND sent */
1270                 select_sent = ((isMask&isFlags) & NSTCIS_SELECTED)?1:0;
1271                 select_sent_vista = ensurev_sent = select_sent;
1272
1273                 select_sent +=       ((isMask&isFlags) & NSTCIS_SELECTEDNOEXPAND)?1:0;
1274                 select_sent_vista += ((isMask&isFlags) & NSTCIS_EXPANDED)?1:0;
1275                 expand_sent =        ((isMask|isFlags) & NSTCIS_EXPANDED)?1:0;
1276
1277                 /* Possible TWM_SETITEMW message and its contents */
1278                 if(isMask & NSTCIS_DISABLED)
1279                     tviexp.mask = TVIF_STATE | TVIF_STATEEX;
1280                 else if( ((isMask^isFlags) & (NSTCIS_SELECTED|NSTCIS_EXPANDED|NSTCIS_SELECTEDNOEXPAND)) ||
1281                          ((isMask|isFlags) & NSTCIS_BOLD) || (isFlags & NSTCIS_DISABLED) )
1282                     tviexp.mask = TVIF_STATE;
1283                 else
1284                     tviexp.mask = 0;
1285
1286                 if(tviexp.mask)
1287                 {
1288                     tviexp.stateMask = tviexp.state = 0;
1289                     tviexp.stateMask |= ((isMask^isFlags)&NSTCIS_SELECTED) ? TVIS_SELECTED : 0;
1290                     tviexp.stateMask |= (isMask|isFlags)&NSTCIS_BOLD ? TVIS_BOLD:0;
1291                     tviexp.state     |= (isMask&isFlags)&NSTCIS_BOLD ? TVIS_BOLD:0;
1292
1293                     if((isMask&NSTCIS_EXPANDED)^(isFlags&NSTCIS_EXPANDED))
1294                     {
1295                         tviexp.stateMask = 0;
1296                     }
1297
1298                     tviexp.uStateEx = (isFlags&isMask)&NSTCIS_DISABLED?TVIS_EX_DISABLED:0;
1299                 }
1300                 else
1301                 {
1302                     /* Make sure that no tests accidentally succeeded
1303                      * (and avoid a gcc warning) */
1304                     tviexp.stateMask = tviexp.state = tviexp.uStateEx = -1;
1305                 }
1306
1307                 /*****************************/
1308                 /*      Check the values.    */
1309                 /*****************************/
1310
1311                 msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_SELECTITEM);
1312                 ok(msg_count == select_sent || broken(msg_count == select_sent_vista),
1313                    "(%x|%x) Got msg_count %d, expected %d (%d)\n",
1314                    isMask, isFlags, msg_count, select_sent, select_sent_vista);
1315                 msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_ENSUREVISIBLE);
1316                 ok(msg_count == ensurev_sent || broken(msg_count == 0 /* Vista */),
1317                    "(%x|%x) Got msg_count %d, expected %d\n",
1318                    isMask, isFlags, msg_count, ensurev_sent);
1319                 msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_EXPAND);
1320                 ok(msg_count == expand_sent, "(%x|%x) Got msg_count %d, expected %d\n",
1321                    isMask, isFlags, msg_count, expand_sent);
1322
1323                 msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_SETITEMW);
1324                 if(!tviexp.mask)
1325                 {
1326                     /* Four special cases for vista */
1327                     BOOL vista_check = ( (isMask == 0x10 && isFlags == 0x10) ||
1328                                          (isMask == 0x11 && isFlags == 0x11) ||
1329                                          (isMask == 0x12 && isFlags == 0x12) ||
1330                                          (isMask == 0x13 && isFlags == 0x13) );
1331
1332                     ok(msg_count == 0 || broken(msg_count == 1 && vista_check),
1333                        "(%x|%x) Got msg_count %d (tviexp.mask %x)\n",
1334                        isMask, isFlags, msg_count, tviexp.mask);
1335                 }
1336                 else
1337                 {
1338                     ok(msg_count == 1, "(%x|%x) Got msg_count %d, expected 1\n",
1339                        isMask, isFlags, msg_count);
1340                     ok(last_tvi.mask == tviexp.mask,
1341                        "(%x|%x) Got mask %x, expected %x\n",
1342                        isMask, isFlags, last_tvi.mask, tviexp.mask);
1343                     ok(last_tvi.stateMask == tviexp.stateMask,
1344                        "(%x|%x) Got stateMask %x, expected %x\n",
1345                        isMask, isFlags, last_tvi.stateMask, tviexp.stateMask);
1346                     ok(last_tvi.state == tviexp.state,
1347                        "(%x|%x) Got state %x, expected %x\n",
1348                        isMask, isFlags,     last_tvi.state, tviexp.state);
1349                     ok(last_tvi.uStateEx == tviexp.uStateEx,
1350                        "(%x|%x) Got uStateEx %x, expected %x\n",
1351                        isMask, isFlags,   last_tvi.uStateEx, tviexp.uStateEx);
1352                 }
1353             }
1354         }
1355         hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1356         ok(hr == S_OK, "Got (0x%08x)\n", hr);
1357     }
1358
1359     /* GetSelectedItems */
1360     if(0)
1361     {
1362         /* Crashes under Windows 7 */
1363         INameSpaceTreeControl_GetSelectedItems(pnstc, NULL);
1364     }
1365
1366     psia = (void*)0xdeadbeef;
1367     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1368     ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1369     ok(psia == (void*)0xdeadbeef, "Got %p\n", psia);
1370
1371     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, SHCONTF_FOLDERS, 0, NULL);
1372     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1373     process_msgs();
1374
1375     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, SHCONTF_FOLDERS, 0, NULL);
1376     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1377     process_msgs();
1378
1379     hr = INameSpaceTreeControl_SetItemState(pnstc, psitestdir,
1380                                             NSTCIS_SELECTED, NSTCIS_SELECTED);
1381     ok(hr == S_OK, "Got 0x%08x\n", hr);
1382
1383     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1384     ok(hr == S_OK, "Got 0x%08x\n", hr);
1385     if(SUCCEEDED(hr))
1386     {
1387         UINT count;
1388         hr = IShellItemArray_GetCount(psia, &count);
1389         ok(hr == S_OK, "Got 0x%08x\n", hr);
1390         ok(count == 1, "Got %d selected items.\n", count);
1391         if(count)
1392         {
1393             hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1394             ok(hr == S_OK, "Got 0x%08x\n", hr);
1395             if(SUCCEEDED(hr))
1396             {
1397                 int cmp;
1398                 hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1399                 ok(hr == S_OK, "Got 0x%08x\n", hr);
1400                 IShellItem_Release(psi);
1401             }
1402         }
1403         IShellItemArray_Release(psia);
1404     }
1405
1406     hr = INameSpaceTreeControl_SetItemState(pnstc, psitestdir2,
1407                                             NSTCIS_SELECTED, NSTCIS_SELECTED);
1408     ok(hr == S_OK, "Got 0x%08x\n", hr);
1409     process_msgs();
1410
1411     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1412     ok(hr == S_OK, "Got 0x%08x\n", hr);
1413     if(SUCCEEDED(hr))
1414     {
1415         UINT count;
1416         hr = IShellItemArray_GetCount(psia, &count);
1417         ok(hr == S_OK, "Got 0x%08x\n", hr);
1418         ok(count == 1, "Got %d selected items.\n", count);
1419         if(count)
1420         {
1421             hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1422             ok(hr == S_OK, "Got 0x%08x\n", hr);
1423             if(SUCCEEDED(hr))
1424             {
1425                 int cmp;
1426                 hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp);
1427                 ok(hr == S_OK, "Got 0x%08x\n", hr);
1428                 IShellItem_Release(psi);
1429             }
1430         }
1431         IShellItemArray_Release(psia);
1432     }
1433
1434     hr = INameSpaceTreeControl_SetItemState(pnstc, psitest1,
1435                                             NSTCIS_SELECTED, NSTCIS_SELECTED);
1436     todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
1437     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1438     ok(hr == S_OK, "Got 0x%08x\n", hr);
1439     if(SUCCEEDED(hr))
1440     {
1441         UINT count;
1442         hr = IShellItemArray_GetCount(psia, &count);
1443         ok(hr == S_OK, "Got 0x%08x\n", hr);
1444         ok(count == 1, "Got %d selected items.\n", count);
1445         if(count)
1446         {
1447             hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1448             ok(hr == S_OK, "Got 0x%08x\n", hr);
1449             if(SUCCEEDED(hr))
1450             {
1451                 int cmp;
1452                 hr = IShellItem_Compare(psi, psitest1, SICHINT_DISPLAY, &cmp);
1453                 todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
1454                 IShellItem_Release(psi);
1455             }
1456         }
1457         IShellItemArray_Release(psia);
1458     }
1459
1460     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1461     ok(hr == S_OK || broken(hr == E_FAIL), "Got 0x%08x\n", hr);
1462     if(hr == E_FAIL)
1463     {
1464         /* For some reason, Vista fails to properly remove both the
1465          * roots here on the first try. */
1466         hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1467         ok(hr == S_OK, "Got 0x%08x\n", hr);
1468     }
1469
1470     /* Adding without NSTCRS_EXPANDED does not set the selection */
1471     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir,
1472                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1473                                           0, NULL);
1474     ok(hr == S_OK, "Got 0x%08x\n", hr);
1475     process_msgs();
1476
1477     hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir, 0xFF, &istate);
1478     ok(hr == S_OK, "Got 0x%08x\n", hr);
1479     ok(!(istate & NSTCIS_SELECTED), "Got 0x%08x\n", istate);
1480     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1481     ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1482     if(SUCCEEDED(hr)) IShellItemArray_Release(psia);
1483
1484     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1485     ok(hr == S_OK, "Got 0x%08x\n", hr);
1486
1487     /* Adding with NSTCRS_EXPANDED sets the selection */
1488     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir,
1489                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1490                                           NSTCRS_EXPANDED, NULL);
1491     ok(hr == S_OK, "Got 0x%08x\n", hr);
1492     process_msgs();
1493
1494     hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir, 0xFF, &istate);
1495     ok(hr == S_OK, "Got 0x%08x\n", hr);
1496     todo_wine ok(istate & NSTCIS_SELECTED, "Got 0x%08x\n", istate);
1497     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1498     todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
1499     if(SUCCEEDED(hr))
1500     {
1501         IShellItem *psi;
1502
1503         hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1504         if(SUCCEEDED(hr))
1505         {
1506             INT cmp;
1507             hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1508             ok(hr == S_OK, "Got 0x%08x\n", hr);
1509
1510             IShellItem_Release(psi);
1511         }
1512
1513         IShellItemArray_Release(psia);
1514     }
1515
1516     /* Adding a second root with NSTCRS_EXPANDED does not change the selection */
1517     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2,
1518                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1519                                           NSTCRS_EXPANDED, NULL);
1520     ok(hr == S_OK, "Got 0x%08x\n", hr);
1521     process_msgs();
1522
1523     hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir2, 0xFF, &istate);
1524     ok(hr == S_OK, "Got 0x%08x\n", hr);
1525     ok(!(istate & NSTCIS_SELECTED), "Got 0x%08x\n", istate);
1526     hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia);
1527     todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr);
1528     if(SUCCEEDED(hr))
1529     {
1530         IShellItem *psi;
1531
1532         hr = IShellItemArray_GetItemAt(psia, 0, &psi);
1533         if(SUCCEEDED(hr))
1534         {
1535             INT cmp;
1536             hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1537             ok(hr == S_OK, "Got 0x%08x\n", hr);
1538
1539             IShellItem_Release(psi);
1540         }
1541
1542         IShellItemArray_Release(psia);
1543     }
1544
1545     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1546     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1547
1548     /* GetItemRect */
1549     rc.top = rc.left = rc.bottom = rc.right = 0;
1550     if(0)
1551     {
1552         /* Crashes under win 7 */
1553         INameSpaceTreeControl_GetItemRect(pnstc, NULL, NULL);
1554         INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, NULL);
1555         INameSpaceTreeControl_GetItemRect(pnstc, NULL, &rc);
1556     }
1557
1558     hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, &rc);
1559     ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr);
1560
1561     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir,
1562                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1563                                           NSTCRS_EXPANDED, NULL);
1564     ok(hr == S_OK, "Got 0x%08x\n", hr);
1565     process_msgs();
1566
1567     hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, &rc);
1568     ok(hr == S_OK, "Got 0x%08x\n", hr);
1569     ok(rc.top != rc.bottom, "Got 0 height.\n");
1570     ok(rc.left != rc.bottom, "Got 0 width.\n");
1571
1572     height = 0;
1573     hwnd_tv = get_treeview_hwnd(pnstc);
1574     if(hwnd_tv)
1575     {
1576         HTREEITEM hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
1577         ok(hroot != NULL, "Failed to get root.\n");
1578         if(hroot)
1579         {
1580             RECT tv_rc;
1581             BOOL bret;
1582
1583             *(HTREEITEM*)&tv_rc = hroot;
1584             bret = SendMessageW(hwnd_tv, TVM_GETITEMRECT, FALSE, (LPARAM)&tv_rc);
1585             ok(bret, "TVM_GETITEMRECT failed.\n");
1586
1587             /* The NamespaceTreeControl returns screen coordinates. */
1588             MapWindowPoints(NULL, hwnd, (POINT*)&rc, 2);
1589             ok(rc.left == tv_rc.left, "Differed, got %d and %d\n", rc.left, tv_rc.left);
1590             ok(rc.top == tv_rc.top, "Differed, got %d and %d\n", rc.top, tv_rc.top);
1591             ok(rc.right == tv_rc.right, "Differed, got %d and %d\n", rc.right, tv_rc.right);
1592             ok(rc.bottom == tv_rc.bottom, "Differed, got %d and %d\n", rc.bottom, tv_rc.bottom);
1593
1594             /* Save the height and compare to that of other items.
1595                Observed values: 18, 19, 21 */
1596             height = rc.bottom - rc.top;
1597             trace("height: %d\n", height);
1598         }
1599     }
1600     else
1601         win_skip("Skipping some GetItemRect tests.\n");
1602
1603     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1604     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1605
1606     /*  HitTest */
1607     hr = INameSpaceTreeControl_HitTest(pnstc, NULL, NULL);
1608     ok(hr == E_POINTER, "Got 0x%08x\n", hr);
1609     hr = INameSpaceTreeControl_HitTest(pnstc, &pt, NULL);
1610     ok(hr == E_POINTER, "Got 0x%08x\n", hr);
1611     hr = INameSpaceTreeControl_HitTest(pnstc, NULL, &psi);
1612     ok(hr == E_POINTER, "Got 0x%08x\n", hr);
1613
1614     psi = (void*)0xdeadbeef;
1615     pt.x = pt.y = 0;
1616     hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1617     ok(hr == S_FALSE, "Got 0x%08x\n", hr);
1618     ok(psi == NULL, "Got psi %p\n", psi);
1619
1620     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir,
1621                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1622                                           NSTCRS_EXPANDED, NULL);
1623     ok(hr == S_OK, "Got 0x%08x\n", hr);
1624     process_msgs();
1625
1626     hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1627     ok(hr == S_OK, "Got 0x%08x\n", hr);
1628     if(SUCCEEDED(hr))
1629     {
1630         int cmp;
1631         hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1632         ok(hr == S_OK, "Got 0x%08x\n", hr);
1633         ok(!cmp, "Got cmp %d\n", cmp);
1634         IShellItem_Release(psi);
1635     }
1636
1637     pt.y += height - 1;
1638     hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1639     ok(hr == S_OK, "Got 0x%08x\n", hr);
1640     if(SUCCEEDED(hr))
1641     {
1642         int cmp;
1643         hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1644         ok(hr == S_OK, "Got 0x%08x\n", hr);
1645         ok(!cmp, "Got cmp %d\n", cmp);
1646         IShellItem_Release(psi);
1647     }
1648
1649     pt.y += 1;
1650     hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1651     ok(hr == S_OK, "Got 0x%08x\n", hr);
1652     if(SUCCEEDED(hr))
1653     {
1654         int cmp;
1655         todo_wine
1656         {
1657             hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp);
1658             ok(hr == S_FALSE, "Got 0x%08x\n", hr);
1659             ok(cmp, "no cmp value.\n");
1660             hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp);
1661             ok(hr == S_OK, "Got 0x%08x\n", hr);
1662             ok(!cmp, "Got cmp %d\n", cmp);
1663         }
1664         IShellItem_Release(psi);
1665     }
1666
1667     hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir2, &rc);
1668     ok(hr == S_OK, "Got 0x%08x\n", hr);
1669     if(SUCCEEDED(hr))
1670     {
1671         MapWindowPoints(NULL, hwnd, (POINT*)&rc, 2);
1672         pt.x = rc.left; pt.y = rc.top;
1673
1674         hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi);
1675         ok(hr == S_OK, "Got 0x%08x\n", hr);
1676         if(SUCCEEDED(hr))
1677         {
1678             int cmp;
1679             hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp);
1680             ok(hr == S_OK, "Got 0x%08x\n", hr);
1681             ok(!cmp, "Got cmp %d\n", cmp);
1682             IShellItem_Release(psi);
1683         }
1684     }
1685
1686     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1687     ok(hr == S_OK, "Got 0x%08x\n", hr);
1688
1689     /* GetItemCustomState / SetItemCustomState */
1690     if(0)
1691     {
1692         /* Crashes under Windows 7 */
1693         INameSpaceTreeControl_GetItemCustomState(pnstc, NULL, NULL);
1694         INameSpaceTreeControl_GetItemCustomState(pnstc, NULL, &cbstate);
1695         INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, NULL);
1696         INameSpaceTreeControl_SetItemCustomState(pnstc, NULL, 0);
1697     }
1698
1699     hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir,
1700                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
1701                                           0, NULL);
1702     process_msgs();
1703     ok(hr == S_OK, "Got 0x%08x\n", hr);
1704
1705     todo_wine
1706     {
1707         cbstate = -1;
1708         hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate);
1709         ok(hr == S_OK, "Got 0x%08x\n", hr);
1710         ok(cbstate == BST_UNCHECKED || broken(cbstate == BST_CHECKED /* Vista x64 */),
1711            "Got %d\n", cbstate);
1712
1713         hr = INameSpaceTreeControl_SetItemCustomState(pnstc, psitestdir, BST_CHECKED);
1714         ok(hr == S_OK, "Got 0x%08x\n", hr);
1715
1716         cbstate = -1;
1717         hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate);
1718         ok(hr == S_OK, "Got 0x%08x\n", hr);
1719         ok(cbstate == BST_CHECKED, "Got %d\n", cbstate);
1720
1721         hr = INameSpaceTreeControl_SetItemCustomState(pnstc, psitestdir, 0xFFF);
1722         ok(hr == S_OK, "Got 0x%08x\n", hr);
1723
1724         cbstate = -1;
1725         hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate);
1726         ok(hr == S_OK, "Got 0x%08x\n", hr);
1727         ok(cbstate == 0xF, "Got %d\n", cbstate);
1728     }
1729
1730     /* SetTheme */
1731     todo_wine
1732     {
1733         hr = INameSpaceTreeControl_SetTheme(pnstc, NULL);
1734         ok(hr == S_OK, "Got 0x%08x\n", hr);
1735         hr = INameSpaceTreeControl_SetTheme(pnstc, explorerW);
1736         ok(hr == S_OK, "Got 0x%08x\n", hr);
1737         hr = INameSpaceTreeControl_SetTheme(pnstc, randomW);
1738         ok(hr == S_OK, "Got 0x%08x\n", hr);
1739     }
1740
1741     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1742     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1743
1744     IShellItem_Release(psidesktop);
1745     IShellItem_Release(psidesktop2);
1746     IShellItem_Release(psitestdir);
1747     IShellItem_Release(psitestdir2);
1748     IShellItem_Release(psitest1);
1749
1750     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
1751     ok(hr == S_OK, "Got 0x%08x\n", hr);
1752     if(SUCCEEDED(hr))
1753     {
1754         HWND hwnd_nstc;
1755         hr = IOleWindow_GetWindow(pow, &hwnd_nstc);
1756         ok(hr == S_OK, "Got 0x%08x\n", hr);
1757         DestroyWindow(hwnd_nstc);
1758         IOleWindow_Release(pow);
1759     }
1760
1761     res = INameSpaceTreeControl_Release(pnstc);
1762     ok(!res, "res was %d!\n", res);
1763
1764 cleanup:
1765     Cleanup();
1766 }
1767
1768 static void test_events(void)
1769 {
1770     INameSpaceTreeControl *pnstc;
1771     INameSpaceTreeControlEventsImpl *pnstceimpl, *pnstceimpl2;
1772     INameSpaceTreeControlEvents *pnstce, *pnstce2;
1773     IShellFolder *psfdesktop;
1774     IShellItem *psidesktop;
1775     IOleWindow *pow;
1776     LPITEMIDLIST pidl_desktop;
1777     LPITEMIDLIST pidl_drives;
1778     NSTCITEMSTATE itemstate;
1779     IShellItem *psi;
1780     DWORD cookie1, cookie2;
1781     HWND hwnd_tv;
1782     HRESULT hr;
1783     UINT res;
1784
1785     hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
1786                           &IID_INameSpaceTreeControl, (void**)&pnstc);
1787     ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr);
1788
1789     ok(pSHCreateShellItem != NULL, "No SHCreateShellItem.\n");
1790     ok(pSHGetIDListFromObject != NULL, "No SHCreateShellItem.\n");
1791
1792     SHGetDesktopFolder(&psfdesktop);
1793     hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl_desktop);
1794     IShellFolder_Release(psfdesktop);
1795     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1796     hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop);
1797     ok(hr == S_OK, "Got 0x%08x\n", hr);
1798     ILFree(pidl_desktop);
1799
1800     /* Create two instances of INameSpaceTreeControlEvents */
1801     pnstceimpl = create_nstc_events();
1802     pnstce = &pnstceimpl->INameSpaceTreeControlEvents_iface;
1803     ZeroMemory(&pnstceimpl->count, sizeof(UINT)*LastEvent);
1804     pnstceimpl2 = create_nstc_events();
1805     pnstce2 = &pnstceimpl2->INameSpaceTreeControlEvents_iface;
1806
1807     if(0)
1808     {
1809         /* Crashes native */
1810         INameSpaceTreeControl_TreeAdvise(pnstc, NULL, NULL);
1811         INameSpaceTreeControl_TreeAdvise(pnstc, NULL, &cookie1);
1812         INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, NULL);
1813     }
1814
1815     /* TreeAdvise in NameSpaceTreeController seems to support only one
1816      * client at the time.
1817      */
1818
1819     /* First, respond with E_NOINTERFACE to all QI's */
1820     pnstceimpl->qi_enable_events = FALSE;
1821     pnstceimpl->qi_called_count = 0;
1822     cookie1 = 0xDEADBEEF;
1823     hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1);
1824     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
1825     ok(cookie1 == 0, "cookie now (0x%08x)\n", cookie1);
1826     todo_wine
1827     {
1828         ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */,
1829            "QueryInterface called %d times.\n",
1830            pnstceimpl->qi_called_count);
1831     }
1832     ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref);
1833
1834     /* Accept query for IID_INameSpaceTreeControlEvents */
1835     pnstceimpl->qi_enable_events = TRUE;
1836     pnstceimpl->qi_called_count = 0;
1837     cookie1 = 0xDEADBEEF;
1838     hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1);
1839     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1840     ok(cookie1 == 1, "cookie now (0x%08x)\n", cookie1);
1841     todo_wine
1842     {
1843         ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */,
1844            "QueryInterface called %d times.\n",
1845            pnstceimpl->qi_called_count);
1846     }
1847     ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref);
1848
1849     /* A second time, query interface will not be called at all. */
1850     pnstceimpl->qi_enable_events = TRUE;
1851     pnstceimpl->qi_called_count = 0;
1852     cookie2 = 0xDEADBEEF;
1853     hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie2);
1854     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
1855     ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2);
1856     ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n",
1857        pnstceimpl->qi_called_count);
1858     ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref);
1859
1860     /* Using another "instance" does not help. */
1861     pnstceimpl2->qi_enable_events = TRUE;
1862     pnstceimpl2->qi_called_count = 0;
1863     cookie2 = 0xDEADBEEF;
1864     hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce2, &cookie2);
1865     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
1866     ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2);
1867     ok(!pnstceimpl2->qi_called_count, "QueryInterface called %d times.\n",
1868        pnstceimpl2->qi_called_count);
1869     ok(pnstceimpl2->ref == 1, "refcount was %d\n", pnstceimpl->ref);
1870
1871     /* Unadvise with bogus cookie (will actually unadvise properly) */
1872     pnstceimpl->qi_enable_events = TRUE;
1873     pnstceimpl->qi_called_count = 0;
1874     hr = INameSpaceTreeControl_TreeUnadvise(pnstc, 1234);
1875     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1876     ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n",
1877        pnstceimpl->qi_called_count);
1878     ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref);
1879
1880     /* Unadvise "properly" (will have no additional effect) */
1881     pnstceimpl->qi_enable_events = TRUE;
1882     pnstceimpl->qi_called_count = 0;
1883     hr = INameSpaceTreeControl_TreeUnadvise(pnstc, cookie1);
1884     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1885     ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n",
1886        pnstceimpl->qi_called_count);
1887     ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref);
1888
1889     /* Advise again.. */
1890     pnstceimpl->qi_enable_events = 1;
1891     pnstceimpl->qi_called_count = 0;
1892     hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie2);
1893     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1894     ok(cookie2 == 1, "Cookie is %d\n", cookie2);
1895     ok(cookie1 == cookie2, "Old cookie differs from old cookie.\n");
1896     todo_wine
1897     {
1898         ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */,
1899            "QueryInterface called %d times.\n",
1900            pnstceimpl->qi_called_count);
1901     }
1902     ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref);
1903
1904     /* Initialize the control */
1905     hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, NULL, 0);
1906     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1907     ok_no_events(pnstceimpl);
1908
1909     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop,
1910                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
1911     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1912     process_msgs();
1913     ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
1914     ok_event_count(pnstceimpl, OnGetDefaultIconIndex, 0);
1915     ok_no_events(pnstceimpl);
1916
1917     hwnd_tv = get_treeview_hwnd(pnstc);
1918     ok(hwnd_tv != NULL, "Failed to get hwnd_tv HWND.\n");
1919     if(hwnd_tv)
1920     {
1921         HTREEITEM hroot, hitem;
1922         UINT i;
1923         static const UINT kbd_msgs_event[] = {
1924             WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
1925             WM_SYSCHAR, 0 };
1926         static const UINT kbd_msgs_noevent[] ={
1927             WM_DEADCHAR, WM_SYSDEADCHAR, WM_UNICHAR, 0 };
1928
1929         /* Test On*Expand */
1930         hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
1931         SendMessage(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot);
1932         process_msgs();
1933         ok_event_count(pnstceimpl, OnBeforeExpand, 1);
1934         ok_event_count(pnstceimpl, OnAfterExpand, 1);
1935         ok_event_broken(pnstceimpl, OnItemAdded); /* No event on Vista */
1936         todo_wine ok_event_count(pnstceimpl, OnSelectionChanged, 1);
1937         ok_no_events(pnstceimpl);
1938         SendMessage(hwnd_tv, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hroot);
1939         process_msgs();
1940         ok_no_events(pnstceimpl);
1941         SendMessage(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot);
1942         process_msgs();
1943         ok_no_events(pnstceimpl);
1944
1945         /* Test OnSelectionChanged */
1946         hitem = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hroot);
1947         SendMessageW(hwnd_tv, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hitem);
1948         process_msgs();
1949         ok_event_count(pnstceimpl, OnSelectionChanged, 1);
1950         ok_no_events(pnstceimpl);
1951
1952         /* Test OnKeyboardInput */
1953         for(i = 0; kbd_msgs_event[i] != 0; i++)
1954         {
1955             SendMessageW(hwnd_tv, kbd_msgs_event[i], 0x1234, 0x1234);
1956             ok(pnstceimpl->count[OnKeyboardInput] == 1,
1957                "%d (%x): Got count %d\n",
1958                kbd_msgs_event[i], kbd_msgs_event[i], pnstceimpl->count[OnKeyboardInput]);
1959             pnstceimpl->count[OnKeyboardInput] = 0;
1960         }
1961
1962         for(i = 0; kbd_msgs_noevent[i] != 0; i++)
1963         {
1964             SendMessageW(hwnd_tv, kbd_msgs_noevent[i], 0x1234, 0x1234);
1965             ok(pnstceimpl->count[OnKeyboardInput] == 0,
1966                "%d (%x): Got count %d\n",
1967                kbd_msgs_noevent[i], kbd_msgs_noevent[i], pnstceimpl->count[OnKeyboardInput]);
1968             pnstceimpl->count[OnKeyboardInput] = 0;
1969         }
1970         ok_no_events(pnstceimpl);
1971     }
1972     else
1973         skip("Skipping some tests.\n");
1974
1975     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
1976     process_msgs();
1977     ok(hr == S_OK, "Got 0x%08x\n", hr);
1978     ok_event(pnstceimpl, OnItemDeleted);
1979     ok_no_events(pnstceimpl);
1980
1981     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop,
1982                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
1983     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1984     process_msgs();
1985     ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
1986     ok_no_events(pnstceimpl);
1987
1988     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
1989     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1990     ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate);
1991     process_msgs();
1992     ok_no_events(pnstceimpl);
1993
1994     /* Expand the root */
1995     itemstate |= NSTCIS_EXPANDED;
1996     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, itemstate);
1997     ok(hr == S_OK, "Got (0x%08x)\n", hr);
1998     process_msgs();
1999     ok_event_count(pnstceimpl, OnBeforeExpand, 1);
2000     ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */
2001     ok_event_count(pnstceimpl, OnAfterExpand, 1);
2002     todo_wine
2003     {
2004         ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /* Vista*/);
2005     }
2006     ok_no_events(pnstceimpl);
2007
2008     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2009     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2010     ok(itemstate & NSTCIS_EXPANDED, "Item not expanded.\n");
2011     todo_wine
2012     {
2013         ok(itemstate == (NSTCIS_SELECTED | NSTCIS_EXPANDED)||
2014            broken(itemstate == NSTCIS_EXPANDED) /* Vista */,
2015            "itemstate is 0x%08x\n", itemstate);
2016         process_msgs();
2017         ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /* Vista*/);
2018     }
2019     ok_no_events(pnstceimpl);
2020
2021     /* Deselect the root */
2022     itemstate &= ~NSTCIS_SELECTED;
2023     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, itemstate);
2024     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2025     process_msgs();
2026     ok_no_events(pnstceimpl);
2027
2028     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2029     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2030     ok(itemstate == (NSTCIS_EXPANDED), "itemstate is 0x%08x\n", itemstate);
2031     ok_no_events(pnstceimpl);
2032
2033     hr = INameSpaceTreeControl_CollapseAll(pnstc);
2034     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2035     ok_no_events(pnstceimpl);
2036
2037     /* Delete all roots */
2038     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
2039     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2040     ok_event_count(pnstceimpl, OnItemDeleted, 1);
2041     ok_no_events(pnstceimpl);
2042
2043     /* Get/SetItemState */
2044     if(0)
2045     {
2046         /* Crashes on Windows 7 */
2047         INameSpaceTreeControl_SetItemState(pnstc, NULL, 0, 0);
2048         INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, NULL);
2049         INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0, NULL);
2050         INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, &itemstate);
2051         INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0, NULL);
2052         INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, &itemstate);
2053     }
2054
2055     itemstate = 0xDEADBEEF;
2056     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2057     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
2058     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0);
2059     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
2060     ok_no_events(pnstceimpl);
2061
2062     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop,
2063                                           SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2064     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2065     process_msgs();
2066     ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
2067     ok_no_events(pnstceimpl);
2068
2069     itemstate = 0xDEADBEEF;
2070     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2071     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2072     ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate);
2073     ok_no_events(pnstceimpl);
2074
2075     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0, 0xffff);
2076     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2077     process_msgs();
2078     todo_wine
2079     {
2080         ok_event_count(pnstceimpl, OnBeforeExpand, 0);
2081         ok_event_count(pnstceimpl, OnAfterExpand, 0);
2082         ok_event_count(pnstceimpl, OnItemAdded, 0);
2083     }
2084     ok_no_events(pnstceimpl);
2085
2086     itemstate = 0xDEADBEEF;
2087     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2088     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2089     todo_wine
2090         ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate);
2091     ok_no_events(pnstceimpl);
2092
2093     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0);
2094     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2095     process_msgs();
2096     ok_no_events(pnstceimpl);
2097
2098     itemstate = 0xDEADBEEF;
2099     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2100     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2101     ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate);
2102     ok_no_events(pnstceimpl);
2103
2104     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_SELECTED);
2105     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2106     process_msgs();
2107     ok_event_count(pnstceimpl, OnSelectionChanged, 1);
2108     ok_no_events(pnstceimpl);
2109
2110     itemstate = 0xDEADBEEF;
2111     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2112     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2113     ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate);
2114     ok_no_events(pnstceimpl);
2115
2116     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_EXPANDED, NSTCIS_SELECTED);
2117     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2118     process_msgs();
2119     ok_no_events(pnstceimpl);
2120
2121     itemstate = 0xDEADBEEF;
2122     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2123     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2124     ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate);
2125     ok_no_events(pnstceimpl);
2126
2127     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0);
2128     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2129     process_msgs();
2130     ok_no_events(pnstceimpl);
2131
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_SELECTED, "itemstate is 0x%08x\n", itemstate);
2136     ok_no_events(pnstceimpl);
2137
2138     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_SELECTEDNOEXPAND);
2139     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2140     process_msgs();
2141     ok_no_events(pnstceimpl);
2142
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_SELECTED, "itemstate is 0x%08x\n", itemstate);
2147     ok_no_events(pnstceimpl);
2148
2149     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_EXPANDED);
2150     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2151     process_msgs();
2152     todo_wine
2153     {
2154         ok_event_count(pnstceimpl, OnBeforeExpand, 1);
2155         ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */
2156         ok_event_count(pnstceimpl, OnAfterExpand, 1);
2157     }
2158     ok_no_events(pnstceimpl);
2159
2160     itemstate = 0xDEADBEEF;
2161     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2162     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2163     ok(itemstate == NSTCIS_EXPANDED, "itemstate is 0x%08x\n", itemstate);
2164     ok_no_events(pnstceimpl);
2165
2166     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0);
2167     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2168     process_msgs();
2169     ok_no_events(pnstceimpl);
2170
2171     itemstate = 0xDEADBEEF;
2172     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2173     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2174     ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate);
2175     ok_no_events(pnstceimpl);
2176
2177     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0xffff);
2178     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2179     process_msgs();
2180     ok_no_events(pnstceimpl);
2181
2182     itemstate = 0xDEADBEEF;
2183     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2184     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2185     todo_wine
2186     {
2187         ok(itemstate == (NSTCIS_EXPANDED | NSTCIS_BOLD | NSTCIS_DISABLED),
2188            "itemstate is 0x%08x\n", itemstate);
2189     }
2190     ok_no_events(pnstceimpl);
2191
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);
2196
2197     itemstate = 0xDEADBEEF;
2198     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2199     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2200     todo_wine
2201     {
2202         ok(itemstate == (NSTCIS_EXPANDED | NSTCIS_BOLD | NSTCIS_DISABLED),
2203            "itemstate is 0x%08x\n", itemstate);
2204     }
2205     ok_no_events(pnstceimpl);
2206
2207     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop,
2208                                             NSTCIS_SELECTED | NSTCIS_DISABLED, NSTCIS_SELECTED);
2209     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2210     process_msgs();
2211     ok_no_events(pnstceimpl);
2212
2213     itemstate = 0xDEADBEEF;
2214     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2215     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2216     ok(itemstate == (NSTCIS_BOLD | NSTCIS_EXPANDED),
2217        "itemstate is 0x%08x\n", itemstate);
2218     ok_no_events(pnstceimpl);
2219
2220     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_SELECTED, NSTCIS_SELECTED);
2221     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2222     process_msgs();
2223     ok_no_events(pnstceimpl);
2224
2225     itemstate = 0xDEADBEEF;
2226     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2227     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2228     ok(itemstate == (NSTCIS_BOLD | NSTCIS_EXPANDED),
2229        "itemstate is 0x%08x\n", itemstate);
2230     ok_no_events(pnstceimpl);
2231
2232     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff & ~NSTCIS_DISABLED, 0);
2233     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2234     process_msgs();
2235     ok_no_events(pnstceimpl);
2236
2237     itemstate = 0xDEADBEEF;
2238     hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate);
2239     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2240     ok(itemstate == (NSTCIS_BOLD), "itemstate is 0x%08x\n", itemstate);
2241     ok_no_events(pnstceimpl);
2242
2243     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
2244     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2245     ok_event_count(pnstceimpl, OnItemDeleted, 1);
2246     ok_no_events(pnstceimpl);
2247
2248     /* GetNextItem */
2249     hr = INameSpaceTreeControl_GetNextItem(pnstc, NULL, 0, NULL);
2250     ok(hr == E_POINTER, "Got (0x%08x)\n", hr);
2251     ok_no_events(pnstceimpl);
2252
2253     hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, 0, NULL);
2254     ok(hr == E_POINTER, "Got (0x%08x)\n", hr);
2255     ok_no_events(pnstceimpl);
2256
2257     hr = INameSpaceTreeControl_GetNextItem(pnstc, NULL, 0, &psi);
2258     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
2259     ok_no_events(pnstceimpl);
2260
2261     hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, 0, &psi);
2262     ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
2263     ok_no_events(pnstceimpl);
2264
2265     hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2266     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2267     process_msgs();
2268     ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
2269     ok_no_events(pnstceimpl);
2270
2271     /* Get child from unexpanded and unfilled parent */
2272     psi = (void*)0xDEADBEEF;
2273     hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, NSTCGNI_CHILD, &psi);
2274     ok(hr == E_FAIL, "Got (0x%08x)\n", hr);
2275     ok(psi == NULL, "psi is %p\n", psi);
2276     process_msgs();
2277     ok_no_events(pnstceimpl);
2278
2279     /* Expand and try again */
2280     hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_EXPANDED, 0xffff);
2281     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2282     process_msgs();
2283     ok_event_count(pnstceimpl, OnBeforeExpand, 1);
2284     ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */
2285     ok_event_count(pnstceimpl, OnAfterExpand, 1);
2286     todo_wine ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /*Vista */);
2287     ok_no_events(pnstceimpl);
2288     psi = (void*)0xDEADBEEF;
2289     hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, NSTCGNI_CHILD, &psi);
2290     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2291     ok((psi != NULL) && (psi != (void*)0xDEADBEEF), "psi is %p\n", psi);
2292     process_msgs();
2293     ok_no_events(pnstceimpl);
2294     if(SUCCEEDED(hr)) IShellItem_Release(psi);
2295
2296     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
2297     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2298     ok_event_count(pnstceimpl, OnItemDeleted, 1);
2299     ok_no_events(pnstceimpl);
2300
2301     /* EnsureItemVisible */
2302     if(0)
2303     {
2304         /* Crashes on Windows 7 */
2305         INameSpaceTreeControl_EnsureItemVisible(pnstc, NULL);
2306     }
2307
2308     hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop);
2309     ok(hr == E_INVALIDARG || hr == E_FAIL, "Got (0x%08x)\n", hr);
2310     ok_no_events(pnstceimpl);
2311
2312     hr = pSHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl_drives);
2313     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2314     if(SUCCEEDED(hr))
2315     {
2316         hr = pSHCreateShellItem(NULL, NULL, pidl_drives, &psi);
2317         ok(hr == S_OK, "Got (0x%08x)\n", hr);
2318         if(SUCCEEDED(hr))
2319         {
2320             hr = INameSpaceTreeControl_AppendRoot(pnstc, psi, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2321             ok(hr == S_OK, "Got (0x%08x)\n", hr);
2322             process_msgs();
2323             ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
2324             ok_no_events(pnstceimpl);
2325
2326             hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop);
2327             ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr);
2328             ok_no_events(pnstceimpl);
2329
2330             hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psi);
2331             ok(hr == S_OK, "Got (0x%08x)\n", hr);
2332             ok_no_events(pnstceimpl);
2333
2334             hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL);
2335             ok(hr == S_OK, "Got (0x%08x)\n", hr);
2336             process_msgs();
2337             ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */);
2338             ok_no_events(pnstceimpl);
2339
2340             hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop);
2341             ok(hr == S_OK, "Got (0x%08x)\n", hr);
2342             ok_no_events(pnstceimpl);
2343
2344             hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psi);
2345             ok(hr == S_OK, "Got (0x%08x)\n", hr);
2346             ok_no_events(pnstceimpl);
2347
2348         }
2349         else
2350             skip("Failed to create shellitem.\n");
2351
2352         ILFree(pidl_drives);
2353     }
2354     else
2355         skip("Failed to get pidl for CSIDL_DRIVES.\n");
2356
2357     hr = INameSpaceTreeControl_RemoveAllRoots(pnstc);
2358     ok(hr == S_OK, "Got (0x%08x)\n", hr);
2359     ok_event_count(pnstceimpl, OnItemDeleted, 2);
2360     ok_no_events(pnstceimpl);
2361
2362     hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
2363     ok(hr == S_OK, "Got 0x%08x\n", hr);
2364     if(SUCCEEDED(hr))
2365     {
2366         HWND hwnd_nstc;
2367         hr = IOleWindow_GetWindow(pow, &hwnd_nstc);
2368         ok(hr == S_OK, "Got 0x%08x\n", hr);
2369         DestroyWindow(hwnd_nstc);
2370         IOleWindow_Release(pow);
2371     }
2372
2373     hr = INameSpaceTreeControl_TreeUnadvise(pnstc, cookie2);
2374     ok(hr == S_OK, "Got 0x%08x\n", hr);
2375
2376     res = INameSpaceTreeControl_Release(pnstc);
2377     ok(!res, "res was %d!\n", res);
2378
2379     if(!res)
2380     {
2381         /* Freeing these prematurely causes a crash. */
2382         HeapFree(GetProcessHeap(), 0, pnstceimpl);
2383         HeapFree(GetProcessHeap(), 0, pnstceimpl2);
2384     }
2385
2386     IShellItem_Release(psi);
2387     IShellItem_Release(psidesktop);
2388 }
2389
2390 static void setup_window(void)
2391 {
2392     WNDCLASSA wc;
2393     static const char nstctest_wnd_name[] = "nstctest_wnd";
2394
2395     ZeroMemory(&wc, sizeof(WNDCLASSA));
2396     wc.lpfnWndProc      = DefWindowProcA;
2397     wc.lpszClassName    = nstctest_wnd_name;
2398     RegisterClassA(&wc);
2399     hwnd = CreateWindowA(nstctest_wnd_name, NULL, WS_TABSTOP,
2400                          0, 0, 200, 200, NULL, 0, 0, NULL);
2401     ok(hwnd != NULL, "Failed to create window for test (lasterror: %d).\n",
2402        GetLastError());
2403 }
2404
2405 static void destroy_window(void)
2406 {
2407     DestroyWindow(hwnd);
2408 }
2409
2410 START_TEST(nstc)
2411 {
2412     OleInitialize(NULL);
2413     setup_window();
2414     init_function_pointers();
2415     init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
2416
2417     if(test_initialization())
2418     {
2419         test_basics();
2420         test_events();
2421     }
2422     else
2423     {
2424         win_skip("No NamespaceTreeControl (or instantiation failed).\n");
2425     }
2426
2427     destroy_window();
2428     OleUninitialize();
2429 }