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