| /* | |
| * Unit tests for the NamespaceTree Control | |
| * | |
| * Copyright 2010 David Hedberg | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include <stdio.h> | |
| #define COBJMACROS | |
| #define CONST_VTABLE | |
| #include "shlobj.h" | |
| #include "wine/test.h" | |
| #include "msg.h" | |
| static HWND hwnd; | |
| static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**); | |
| static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*); | |
| static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**); | |
| static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *); | |
| #define NUM_MSG_SEQUENCES 1 | |
| #define TREEVIEW_SEQ_INDEX 0 | |
| static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; | |
| /* Keep a copy of the last structure passed by TVM_SETITEMW */ | |
| static TVITEMEXW last_tvi; | |
| static int tvi_count; | |
| static void init_function_pointers(void) | |
| { | |
| HMODULE hmod; | |
| hmod = GetModuleHandleA("shell32.dll"); | |
| pSHCreateShellItem = (void*)GetProcAddress(hmod, "SHCreateShellItem"); | |
| pSHGetIDListFromObject = (void*)GetProcAddress(hmod, "SHGetIDListFromObject"); | |
| pSHCreateItemFromParsingName = (void*)GetProcAddress(hmod, "SHCreateItemFromParsingName"); | |
| pSHGetSpecialFolderLocation = (void*)GetProcAddress(hmod, "SHGetSpecialFolderLocation"); | |
| } | |
| /******************************************************* | |
| * INameSpaceTreeControlEvents implementation. | |
| */ | |
| enum { OnItemClick = 0, OnPropertyItemCommit, OnItemStateChanging, OnItemStateChanged, | |
| OnSelectionChanged, OnKeyboardInput, OnBeforeExpand, OnAfterExpand, OnBeginLabelEdit, | |
| OnEndLabelEdit, OnGetToolTip, OnBeforeItemDelete, OnItemAdded, OnItemDeleted, | |
| OnBeforeContextMenu, OnAfterContextMenu, OnBeforeStateImageChange, OnGetDefaultIconIndex, | |
| LastEvent }; | |
| typedef struct { | |
| INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface; | |
| UINT qi_called_count; /* Keep track of calls to QueryInterface */ | |
| BOOL qi_enable_events; /* If FALSE, QueryInterface returns only E_NOINTERFACE */ | |
| UINT count[LastEvent]; /* Keep track of calls to all On* functions. */ | |
| LONG ref; | |
| } INameSpaceTreeControlEventsImpl; | |
| static inline INameSpaceTreeControlEventsImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface) | |
| { | |
| return CONTAINING_RECORD(iface, INameSpaceTreeControlEventsImpl, INameSpaceTreeControlEvents_iface); | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnQueryInterface( | |
| INameSpaceTreeControlEvents* iface, | |
| REFIID riid, | |
| void **ppvObject) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| This->qi_called_count++; | |
| if(This->qi_enable_events && IsEqualIID(riid, &IID_INameSpaceTreeControlEvents)) | |
| { | |
| INameSpaceTreeControlEvents_AddRef(iface); | |
| *ppvObject = iface; | |
| return S_OK; | |
| } | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI NSTCEvents_fnAddRef( | |
| INameSpaceTreeControlEvents* iface) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| return InterlockedIncrement(&This->ref); | |
| } | |
| static ULONG WINAPI NSTCEvents_fnRelease( | |
| INameSpaceTreeControlEvents* iface) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| return InterlockedDecrement(&This->ref); | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnItemClick( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| NSTCEHITTEST nstceHitTest, | |
| NSTCECLICKTYPE nstceClickType) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnItemClick]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnPropertyItemCommit]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| NSTCITEMSTATE nstcisMask, | |
| NSTCITEMSTATE nstcisState) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnItemStateChanging]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| NSTCITEMSTATE nstcisMask, | |
| NSTCITEMSTATE nstcisState) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnItemStateChanged]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItemArray *psiaSelection) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psiaSelection != NULL, "IShellItemArray was NULL.\n"); | |
| if(psiaSelection) | |
| { | |
| HRESULT hr; | |
| DWORD count = 0xdeadbeef; | |
| hr = IShellItemArray_GetCount(psiaSelection, &count); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(count == 1, "Got count 0x%x\n", count); | |
| } | |
| This->count[OnSelectionChanged]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput( | |
| INameSpaceTreeControlEvents* iface, | |
| UINT uMsg, | |
| WPARAM wParam, | |
| LPARAM lParam) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| This->count[OnKeyboardInput]++; | |
| ok(wParam == 0x1234, "Got unexpected wParam %lx\n", wParam); | |
| ok(lParam == 0x1234, "Got unexpected lParam %lx\n", lParam); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnBeforeExpand]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnAfterExpand( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnAfterExpand]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnBeginLabelEdit]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnEndLabelEdit]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnGetToolTip( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| LPWSTR pszTip, | |
| int cchTip) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnGetToolTip]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnBeforeItemDelete]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnItemAdded( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| BOOL fIsRoot) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnItemAdded]++; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnItemDeleted( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| BOOL fIsRoot) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnItemDeleted]++; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| REFIID riid, | |
| void **ppv) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| This->count[OnBeforeContextMenu]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| IContextMenu *pcmIn, | |
| REFIID riid, | |
| void **ppv) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| This->count[OnAfterContextMenu]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnBeforeStateImageChange]++; | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex( | |
| INameSpaceTreeControlEvents* iface, | |
| IShellItem *psi, | |
| int *piDefaultIcon, | |
| int *piOpenIcon) | |
| { | |
| INameSpaceTreeControlEventsImpl *This = impl_from_INameSpaceTreeControlEvents(iface); | |
| ok(psi != NULL, "NULL IShellItem\n"); | |
| This->count[OnGetDefaultIconIndex]++; | |
| return E_NOTIMPL; | |
| } | |
| static const INameSpaceTreeControlEventsVtbl vt_NSTCEvents = { | |
| NSTCEvents_fnQueryInterface, | |
| NSTCEvents_fnAddRef, | |
| NSTCEvents_fnRelease, | |
| NSTCEvents_fnOnItemClick, | |
| NSTCEvents_fnOnPropertyItemCommit, | |
| NSTCEvents_fnOnItemStateChanging, | |
| NSTCEvents_fnOnItemStateChanged, | |
| NSTCEvents_fnOnSelectionChanged, | |
| NSTCEvents_fnOnKeyboardInput, | |
| NSTCEvents_fnOnBeforeExpand, | |
| NSTCEvents_fnOnAfterExpand, | |
| NSTCEvents_fnOnBeginLabelEdit, | |
| NSTCEvents_fnOnEndLabelEdit, | |
| NSTCEvents_fnOnGetToolTip, | |
| NSTCEvents_fnOnBeforeItemDelete, | |
| NSTCEvents_fnOnItemAdded, | |
| NSTCEvents_fnOnItemDeleted, | |
| NSTCEvents_fnOnBeforeContextMenu, | |
| NSTCEvents_fnOnAfterContextMenu, | |
| NSTCEvents_fnOnBeforeStateImageChange, | |
| NSTCEvents_fnOnGetDefaultIconIndex | |
| }; | |
| static INameSpaceTreeControlEventsImpl *create_nstc_events(void) | |
| { | |
| INameSpaceTreeControlEventsImpl *This; | |
| This = HeapAlloc(GetProcessHeap(), 0, sizeof(INameSpaceTreeControlEventsImpl)); | |
| This->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_NSTCEvents; | |
| This->ref = 1; | |
| return This; | |
| } | |
| /********************************************************************* | |
| * Event count checking | |
| */ | |
| static void ok_no_events_(INameSpaceTreeControlEventsImpl *impl, | |
| const char *file, int line) | |
| { | |
| UINT i; | |
| for(i = 0; i < LastEvent; i++) | |
| { | |
| ok_(file, line) | |
| (!impl->count[i], "Got event %d, count %d\n", i, impl->count[i]); | |
| impl->count[i] = 0; | |
| } | |
| } | |
| #define ok_no_events(impl) \ | |
| ok_no_events_(impl, __FILE__, __LINE__) | |
| #define ok_event_count_broken(impl, event, c, b) \ | |
| do { ok(impl->count[event] == c || broken(impl->count[event] == b), \ | |
| "Got event %d, count %d\n", event, impl->count[event]); \ | |
| impl->count[event] = 0; \ | |
| } while(0) | |
| #define ok_event_count(impl, event, c) \ | |
| ok_event_count_broken(impl, event, c, -1) | |
| #define ok_event_broken(impl, event) \ | |
| do { ok(impl->count[event] || broken(!impl->count[event]), \ | |
| "No event.\n"); \ | |
| impl->count[event] = 0; \ | |
| } while(0) | |
| #define ok_event(impl, event) \ | |
| do { ok(impl->count[event], "No event %d.\n", event); \ | |
| impl->count[event] = 0; \ | |
| } while(0) | |
| /* Process some messages */ | |
| static void process_msgs(void) | |
| { | |
| MSG msg; | |
| BOOL got_msg; | |
| do { | |
| got_msg = FALSE; | |
| Sleep(100); | |
| while(PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE)) | |
| { | |
| TranslateMessage(&msg); | |
| DispatchMessageW(&msg); | |
| got_msg = TRUE; | |
| } | |
| } while(got_msg); | |
| /* There seem to be a timer that sometimes fires after about | |
| 500ms, we need to wait for it. Failing to wait can result in | |
| seemingly sporadic selection change events. (Timer ID is 87, | |
| sending WM_TIMER manually does not seem to help us.) */ | |
| Sleep(500); | |
| while(PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE)) | |
| { | |
| TranslateMessage(&msg); | |
| DispatchMessageW(&msg); | |
| } | |
| } | |
| /** Some functions from shell32/tests/shlfolder.c */ | |
| /* creates a file with the specified name for tests */ | |
| static void CreateTestFile(const CHAR *name) | |
| { | |
| HANDLE file; | |
| DWORD written; | |
| file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); | |
| if (file != INVALID_HANDLE_VALUE) | |
| { | |
| WriteFile(file, name, strlen(name), &written, NULL); | |
| WriteFile(file, "\n", strlen("\n"), &written, NULL); | |
| CloseHandle(file); | |
| } | |
| } | |
| /* initializes the tests */ | |
| static void CreateFilesFolders(void) | |
| { | |
| CreateDirectoryA(".\\testdir", NULL); | |
| CreateTestFile (".\\testdir\\test1.txt "); | |
| CreateTestFile (".\\testdir\\test2.txt "); | |
| CreateTestFile (".\\testdir\\test3.txt "); | |
| CreateDirectoryA(".\\testdir\\testdir2 ", NULL); | |
| CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL); | |
| } | |
| /* cleans after tests */ | |
| static void Cleanup(void) | |
| { | |
| DeleteFileA(".\\testdir\\test1.txt"); | |
| DeleteFileA(".\\testdir\\test2.txt"); | |
| DeleteFileA(".\\testdir\\test3.txt"); | |
| RemoveDirectoryA(".\\testdir\\testdir2\\subdir"); | |
| RemoveDirectoryA(".\\testdir\\testdir2"); | |
| RemoveDirectoryA(".\\testdir"); | |
| } | |
| /* Based on PathAddBackslashW from dlls/shlwapi/path.c */ | |
| static LPWSTR myPathAddBackslashW( LPWSTR lpszPath ) | |
| { | |
| size_t iLen; | |
| if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH) | |
| return NULL; | |
| if (iLen) | |
| { | |
| lpszPath += iLen; | |
| if (lpszPath[-1] != '\\') | |
| { | |
| *lpszPath++ = '\\'; | |
| *lpszPath = '\0'; | |
| } | |
| } | |
| return lpszPath; | |
| } | |
| static HWND get_treeview_hwnd(INameSpaceTreeControl *pnstc) | |
| { | |
| IOleWindow *pow; | |
| HRESULT hr; | |
| HWND treeview = NULL; | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| HWND host; | |
| hr = IOleWindow_GetWindow(pow, &host); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| treeview = FindWindowExW(host, NULL, WC_TREEVIEWW, NULL); | |
| IOleWindow_Release(pow); | |
| } | |
| return treeview; | |
| } | |
| static LRESULT WINAPI treeview_subclass_proc(HWND hwnd_tv, UINT message, WPARAM wParam, LPARAM lParam) | |
| { | |
| WNDPROC oldproc = (WNDPROC)GetWindowLongPtrW(hwnd_tv, GWLP_USERDATA); | |
| static LONG defwndproc_counter = 0; | |
| LRESULT ret; | |
| struct message msg; | |
| msg.message = message; | |
| msg.flags = sent|wparam|lparam; | |
| if (defwndproc_counter) msg.flags |= defwinproc; | |
| msg.wParam = wParam; | |
| msg.lParam = lParam; | |
| msg.id = 0; | |
| add_message(sequences, TREEVIEW_SEQ_INDEX, &msg); | |
| if(message == TVM_SETITEMW) | |
| { | |
| memcpy(&last_tvi, (void*)lParam, sizeof(TVITEMEXW)); | |
| tvi_count++; | |
| } | |
| defwndproc_counter++; | |
| ret = CallWindowProcW(oldproc, hwnd_tv, message, wParam, lParam); | |
| defwndproc_counter--; | |
| return ret; | |
| } | |
| static BOOL subclass_treeview(INameSpaceTreeControl *pnstc) | |
| { | |
| HWND hwnd_tv; | |
| WNDPROC oldproc = NULL; | |
| hwnd_tv = get_treeview_hwnd(pnstc); | |
| if(hwnd_tv) | |
| { | |
| oldproc = (WNDPROC)SetWindowLongPtrW(hwnd_tv, GWLP_WNDPROC, | |
| (LONG_PTR)treeview_subclass_proc); | |
| SetWindowLongPtrW(hwnd_tv, GWLP_USERDATA, (LONG_PTR)oldproc); | |
| ok(oldproc != NULL, "Failed to subclass.\n"); | |
| } | |
| return oldproc != 0; | |
| } | |
| static UINT get_msg_count(struct msg_sequence **seq, int sequence_index, UINT message) | |
| { | |
| struct msg_sequence *msg_seq = seq[sequence_index]; | |
| UINT i, count = 0; | |
| for(i = 0; i < msg_seq->count ; i++) | |
| if(msg_seq->sequence[i].message == message) | |
| count++; | |
| return count; | |
| } | |
| /* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */ | |
| static BOOL test_initialization(void) | |
| { | |
| INameSpaceTreeControl *pnstc; | |
| IOleWindow *pow; | |
| IUnknown *punk; | |
| HWND hwnd_host1; | |
| LONG lres; | |
| HRESULT hr; | |
| RECT rc; | |
| hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER, | |
| &IID_INameSpaceTreeControl, (void**)&pnstc); | |
| ok(hr == S_OK || hr == REGDB_E_CLASSNOTREG, "Got 0x%08x\n", hr); | |
| if(FAILED(hr)) | |
| { | |
| return FALSE; | |
| } | |
| hr = INameSpaceTreeControl_Initialize(pnstc, NULL, NULL, 0); | |
| ok(hr == HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD), "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_Initialize(pnstc, (HWND)0xDEADBEEF, NULL, 0); | |
| ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE), "Got (0x%08x)\n", hr); | |
| ZeroMemory(&rc, sizeof(RECT)); | |
| hr = INameSpaceTreeControl_Initialize(pnstc, NULL, &rc, 0); | |
| ok(hr == HRESULT_FROM_WIN32(ERROR_TLW_WITH_WSCHILD), "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_Initialize(pnstc, (HWND)0xDEADBEEF, &rc, 0); | |
| ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE), "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| hr = IOleWindow_GetWindow(pow, &hwnd_host1); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(hwnd_host1 == NULL, "hwnd is not null.\n"); | |
| hr = IOleWindow_ContextSensitiveHelp(pow, TRUE); | |
| ok(hr == E_NOTIMPL, "Got (0x%08x)\n", hr); | |
| hr = IOleWindow_ContextSensitiveHelp(pow, FALSE); | |
| ok(hr == E_NOTIMPL, "Got (0x%08x)\n", hr); | |
| IOleWindow_Release(pow); | |
| } | |
| hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, NULL, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| static const CHAR namespacetree[] = "NamespaceTreeControl"; | |
| char buf[1024]; | |
| LONG style, expected_style; | |
| HWND hwnd_tv; | |
| hr = IOleWindow_GetWindow(pow, &hwnd_host1); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(hwnd_host1 != NULL, "hwnd_host1 is null.\n"); | |
| buf[0] = '\0'; | |
| GetClassNameA(hwnd_host1, buf, 1024); | |
| ok(!lstrcmpA(namespacetree, buf), "Class name was %s\n", buf); | |
| expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; | |
| style = GetWindowLongPtrW(hwnd_host1, GWL_STYLE); | |
| ok(style == expected_style, "Got style %08x\n", style); | |
| expected_style = 0; | |
| style = GetWindowLongPtrW(hwnd_host1, GWL_EXSTYLE); | |
| ok(style == expected_style, "Got style %08x\n", style); | |
| expected_style = 0; | |
| style = SendMessageW(hwnd_host1, TVM_GETEXTENDEDSTYLE, 0, 0); | |
| ok(style == expected_style, "Got 0x%08x\n", style); | |
| hwnd_tv = FindWindowExW(hwnd_host1, NULL, WC_TREEVIEWW, NULL); | |
| ok(hwnd_tv != NULL, "Failed to get treeview hwnd.\n"); | |
| if(hwnd_tv) | |
| { | |
| expected_style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | | |
| WS_CLIPCHILDREN | WS_TABSTOP | TVS_NOHSCROLL | | |
| TVS_NONEVENHEIGHT | TVS_INFOTIP | TVS_TRACKSELECT | TVS_EDITLABELS; | |
| style = GetWindowLongPtrW(hwnd_tv, GWL_STYLE); | |
| ok(style == expected_style, "Got style %08x\n", style); | |
| expected_style = 0; | |
| style = GetWindowLongPtrW(hwnd_tv, GWL_EXSTYLE); | |
| ok(style == expected_style, "Got style %08x\n", style); | |
| expected_style = TVS_EX_NOSINGLECOLLAPSE | TVS_EX_DOUBLEBUFFER | | |
| TVS_EX_RICHTOOLTIP | TVS_EX_DRAWIMAGEASYNC; | |
| style = SendMessageW(hwnd_tv, TVM_GETEXTENDEDSTYLE, 0, 0); | |
| todo_wine ok(style == expected_style, "Got 0x%08x\n", style); | |
| } | |
| IOleWindow_Release(pow); | |
| } | |
| if(0) | |
| { | |
| /* The control can be initialized again without crashing, but | |
| * the reference counting will break. */ | |
| hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, &rc, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| if(SUCCEEDED(hr)) | |
| { | |
| HWND hwnd_host2; | |
| hr = IOleWindow_GetWindow(pow, &hwnd_host2); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(hwnd_host1 != hwnd_host2, "Same hwnd.\n"); | |
| IOleWindow_Release(pow); | |
| } | |
| } | |
| /* Some "random" interfaces */ | |
| /* Next three are supported on Vista/2k8, but not on newer versions */ | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceObject, (void**)&punk); | |
| ok(hr == E_NOINTERFACE || broken(hr == S_OK) /* vista, w2k8 */, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) IUnknown_Release(punk); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceActiveObject, (void**)&punk); | |
| ok(hr == E_NOINTERFACE || broken(hr == S_OK) /* vista, w2k8 */, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) IUnknown_Release(punk); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceObjectWindowless, (void**)&punk); | |
| ok(hr == E_NOINTERFACE || broken(hr == S_OK) /* vista, w2k8 */, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) IUnknown_Release(punk); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceUIWindow, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceFrame, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceSite, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceSiteEx, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceSiteWindowless, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| /* On windows, the reference count won't go to zero until the | |
| * window is destroyed. */ | |
| INameSpaceTreeControl_AddRef(pnstc); | |
| lres = INameSpaceTreeControl_Release(pnstc); | |
| ok(lres > 1, "Reference count was (%d).\n", lres); | |
| DestroyWindow(hwnd_host1); | |
| lres = INameSpaceTreeControl_Release(pnstc); | |
| ok(!lres, "lres was %d\n", lres); | |
| return TRUE; | |
| } | |
| static void verify_root_order_(INameSpaceTreeControl *pnstc, IShellItem **roots, | |
| const char *file, int line) | |
| { | |
| HRESULT hr; | |
| IShellItemArray *psia; | |
| hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia); | |
| ok_(file,line) (hr == S_OK, "GetRootItems: got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| DWORD i, expected, count = -1; | |
| hr = IShellItemArray_GetCount(psia, &count); | |
| ok_(file,line) (hr == S_OK, "Got (0x%08x)\n", hr); | |
| for(expected = 0; roots[expected] != NULL; expected++); | |
| ok_(file,line) (count == expected, "Got %d roots, expected %d\n", count, expected); | |
| for(i = 0; i < count && roots[i] != NULL; i++) | |
| { | |
| IShellItem *psi; | |
| hr = IShellItemArray_GetItemAt(psia, i, &psi); | |
| ok_(file,line) (hr == S_OK, "GetItemAt %i: got 0x%08x\n", i, hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, roots[i], SICHINT_DISPLAY, &cmp); | |
| ok_(file,line) (hr == S_OK, "Compare %i: got 0x%08x\n", i, hr); | |
| IShellItem_Release(psi); | |
| } | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| } | |
| #define verify_root_order(pnstc, psi_a) \ | |
| verify_root_order_(pnstc, psi_a, __FILE__, __LINE__) | |
| static void test_basics(void) | |
| { | |
| INameSpaceTreeControl *pnstc; | |
| INameSpaceTreeControl2 *pnstc2; | |
| IShellItemArray *psia; | |
| IShellFolder *psfdesktop; | |
| IShellItem *psi; | |
| IShellItem *psidesktop, *psidesktop2; | |
| IShellItem *psitestdir, *psitestdir2, *psitest1; | |
| IOleWindow *pow; | |
| LPITEMIDLIST pidl_desktop; | |
| NSTCITEMSTATE istate; | |
| HRESULT hr; | |
| UINT i, res, height; | |
| HWND hwnd_tv; | |
| RECT rc; | |
| IShellItem *roots[10]; | |
| POINT pt; | |
| int cbstate; | |
| WCHAR curdirW[MAX_PATH]; | |
| WCHAR buf[MAX_PATH]; | |
| static const WCHAR testdirW[] = {'t','e','s','t','d','i','r',0}; | |
| static const WCHAR testdir2W[] = | |
| {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','2',0}; | |
| static const WCHAR test1W[] = | |
| {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0}; | |
| static const WCHAR explorerW[] = {'E','x','p','l','o','r','e','r',0}; | |
| static const WCHAR randomW[] = {'_','_','h','e','l','l','o',0}; | |
| /* These should exist on platforms supporting the NSTC */ | |
| ok(pSHCreateShellItem != NULL, "No SHCreateShellItem.\n"); | |
| ok(pSHCreateItemFromParsingName != NULL, "No SHCreateItemFromParsingName\n"); | |
| ok(pSHGetIDListFromObject != NULL, "No SHCreateShellItem.\n"); | |
| ok(pSHCreateItemFromParsingName != NULL, "No SHCreateItemFromParsingName\n"); | |
| /* Create ShellItems for testing. */ | |
| SHGetDesktopFolder(&psfdesktop); | |
| hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl_desktop); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(FAILED(hr)) IShellItem_Release(psidesktop); | |
| } | |
| ILFree(pidl_desktop); | |
| } | |
| IShellFolder_Release(psfdesktop); | |
| if(FAILED(hr)) | |
| { | |
| win_skip("Test setup failed.\n"); | |
| return; | |
| } | |
| ok(psidesktop != psidesktop2, "psidesktop == psidesktop2\n"); | |
| CreateFilesFolders(); | |
| GetCurrentDirectoryW(MAX_PATH, curdirW); | |
| ok(lstrlenW(curdirW), "Got 0 length string.\n"); | |
| lstrcpyW(buf, curdirW); | |
| myPathAddBackslashW(buf); | |
| lstrcatW(buf, testdirW); | |
| hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitestdir); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(FAILED(hr)) goto cleanup; | |
| lstrcpyW(buf, curdirW); | |
| myPathAddBackslashW(buf); | |
| lstrcatW(buf, testdir2W); | |
| hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitestdir2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(FAILED(hr)) goto cleanup; | |
| lstrcpyW(buf, curdirW); | |
| myPathAddBackslashW(buf); | |
| lstrcatW(buf, test1W); | |
| hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psitest1); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(FAILED(hr)) goto cleanup; | |
| hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER, | |
| &IID_INameSpaceTreeControl, (void**)&pnstc); | |
| ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr); | |
| /* Some tests on an uninitialized control */ | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, NULL); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| /* Initialize the control */ | |
| SetRect(&rc, 0, 0, 200, 200); | |
| hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, &rc, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| /* Set/GetControlStyle(2) */ | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_INameSpaceTreeControl2, (void**)&pnstc2); | |
| ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| DWORD tmp; | |
| NSTCSTYLE style; | |
| NSTCSTYLE2 style2; | |
| static const NSTCSTYLE2 styles2[] = | |
| { NSTCS2_INTERRUPTNOTIFICATIONS,NSTCS2_SHOWNULLSPACEMENU, | |
| NSTCS2_DISPLAYPADDING,NSTCS2_DISPLAYPINNEDONLY, | |
| NTSCS2_NOSINGLETONAUTOEXPAND,NTSCS2_NEVERINSERTNONENUMERATED, 0}; | |
| /* We can use this to differentiate between two versions of | |
| * this interface. Windows 7 returns hr == S_OK. */ | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0); | |
| ok(hr == S_OK || broken(hr == E_FAIL), "Got 0x%08x\n", hr); | |
| if(hr == S_OK) | |
| { | |
| static const NSTCSTYLE styles_setable[] = | |
| { NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND, | |
| NSTCS_FULLROWSELECT,NSTCS_HORIZONTALSCROLL, | |
| NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP, | |
| NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP, | |
| NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS, | |
| NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES, | |
| NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON, | |
| NSTCS_SHOWREFRESHBUTTON, 0}; | |
| static const NSTCSTYLE styles_nonsetable[] = | |
| { NSTCS_SPRINGEXPAND, NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL, | |
| NSTCS_FADEINOUTEXPANDOS, | |
| NSTCS_PARTIALCHECKBOXES, NSTCS_EXCLUSIONCHECKBOXES, | |
| NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS,0}; | |
| /* Set/GetControlStyle */ | |
| style = style2 = 0xdeadbeef; | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style == 0, "Got style %x\n", style); | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0xFFFFFFF); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| tmp = 0; | |
| for(i = 0; styles_setable[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], styles_setable[i]); | |
| ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]); | |
| if(SUCCEEDED(hr)) tmp |= styles_setable[i]; | |
| } | |
| for(i = 0; styles_nonsetable[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], styles_nonsetable[i]); | |
| ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]); | |
| } | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style == tmp, "Got style %x (expected %x)\n", style, tmp); | |
| if(SUCCEEDED(hr)) | |
| { | |
| DWORD tmp2; | |
| for(i = 0; styles_setable[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, styles_setable[i], &tmp2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(tmp2 == (style & styles_setable[i]), "Got %x\n", tmp2); | |
| } | |
| } | |
| for(i = 0; styles_setable[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], 0); | |
| ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]); | |
| } | |
| for(i = 0; styles_nonsetable[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], 0); | |
| ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]); | |
| } | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style == 0, "Got style %x\n", style); | |
| /* Set/GetControlStyle2 */ | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == 0, "Got style %x\n", style2); | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0xFFFFFFFF); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == 0x00000000, "Got style %x\n", style2); | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == 0, "Got style %x\n", style2); | |
| tmp = 0; | |
| for(i = 0; styles2[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]); | |
| ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]); | |
| if(SUCCEEDED(hr)) tmp |= styles2[i]; | |
| } | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == tmp, "Got style %x (expected %x)\n", style2, tmp); | |
| if(SUCCEEDED(hr)) | |
| { | |
| DWORD tmp2; | |
| for(i = 0; styles2[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, styles2[i], &tmp2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(tmp2 == (style2 & styles2[i]), "Got %x\n", tmp2); | |
| } | |
| } | |
| for(i = 0; styles2[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], 0); | |
| ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]); | |
| } | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == 0, "Got style %x (expected 0)\n", style2); | |
| } | |
| else | |
| { | |
| /* 64-bit Windows Vista (others?) seems to have a somewhat | |
| * different idea of how the methods of this interface | |
| * should behave. */ | |
| static const NSTCSTYLE styles[] = | |
| { NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND, | |
| NSTCS_FULLROWSELECT,NSTCS_SPRINGEXPAND,NSTCS_HORIZONTALSCROLL, | |
| NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL, | |
| NSTCS_FADEINOUTEXPANDOS, | |
| NSTCS_PARTIALCHECKBOXES,NSTCS_EXCLUSIONCHECKBOXES, | |
| NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS, | |
| NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP, | |
| NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP, | |
| NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS, | |
| NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES, | |
| NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON, | |
| NSTCS_SHOWREFRESHBUTTON, 0}; | |
| trace("Detected broken INameSpaceTreeControl2.\n"); | |
| style = 0xdeadbeef; | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style == 0xdeadbeef, "Got style %x\n", style); | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == 0, "Got style %x\n", style2); | |
| tmp = 0; | |
| for(i = 0; styles[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles[i], styles[i]); | |
| ok(hr == E_FAIL || ((styles[i] & NSTCS_SPRINGEXPAND) && hr == S_OK), | |
| "Got 0x%08x (%x)\n", hr, styles[i]); | |
| if(SUCCEEDED(hr)) tmp |= styles[i]; | |
| } | |
| style = 0xdeadbeef; | |
| hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, tmp, &style); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style == 0xdeadbeef, "Got style %x\n", style); | |
| tmp = 0; | |
| for(i = 0; styles2[i] != 0; i++) | |
| { | |
| hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]); | |
| ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]); | |
| if(SUCCEEDED(hr)) tmp |= styles2[i]; | |
| } | |
| style2 = 0xdeadbeef; | |
| hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(style2 == tmp, "Got style %x\n", style2); | |
| } | |
| INameSpaceTreeControl2_Release(pnstc2); | |
| } | |
| else | |
| { | |
| skip("INameSpaceTreeControl2 missing.\n"); | |
| } | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, NULL); | |
| ok(hr == E_NOINTERFACE, "Got (0x%08x)\n", hr); | |
| /* Append / Insert root */ | |
| if(0) | |
| { | |
| /* Crashes under Windows 7 */ | |
| INameSpaceTreeControl_AppendRoot(pnstc, NULL, SHCONTF_FOLDERS, 0, NULL); | |
| INameSpaceTreeControl_InsertRoot(pnstc, 0, NULL, SHCONTF_FOLDERS, 0, NULL); | |
| } | |
| /* Note the usage of psidesktop and psidesktop2 */ | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop2, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveRoot(pnstc, psidesktop); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 0, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 50, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 1, psidesktop, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| /* GetRootItems */ | |
| if(0) | |
| { | |
| /* Crashes on native. */ | |
| INameSpaceTreeControl_GetRootItems(pnstc, NULL); | |
| } | |
| hr = INameSpaceTreeControl_GetRootItems(pnstc, &psia); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop2, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psidesktop; | |
| roots[1] = psidesktop2; | |
| roots[2] = psitestdir; | |
| roots[3] = psitestdir2; | |
| roots[4] = NULL; | |
| verify_root_order(pnstc, roots); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 0, psitestdir2, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psitestdir2; | |
| roots[1] = psidesktop; | |
| roots[2] = psidesktop2; | |
| roots[3] = psitestdir; | |
| roots[4] = psitestdir2; | |
| roots[5] = NULL; | |
| verify_root_order(pnstc, roots); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 5, psidesktop, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psitestdir2; | |
| roots[1] = psidesktop; | |
| roots[2] = psidesktop2; | |
| roots[3] = psitestdir; | |
| roots[4] = psitestdir2; | |
| roots[5] = psidesktop; | |
| roots[6] = NULL; | |
| verify_root_order(pnstc, roots); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, 3, psitestdir2, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psitestdir2; | |
| roots[1] = psidesktop; | |
| roots[2] = psidesktop2; | |
| roots[3] = psitestdir2; | |
| roots[4] = psitestdir; | |
| roots[5] = psitestdir2; | |
| roots[6] = psidesktop; | |
| roots[7] = NULL; | |
| verify_root_order(pnstc, roots); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psitestdir2; | |
| roots[1] = psidesktop; | |
| roots[2] = psidesktop2; | |
| roots[3] = psitestdir2; | |
| roots[4] = psitestdir; | |
| roots[5] = psitestdir2; | |
| roots[6] = psidesktop; | |
| roots[7] = psitestdir2; | |
| roots[8] = NULL; | |
| verify_root_order(pnstc, roots); | |
| hr = INameSpaceTreeControl_InsertRoot(pnstc, -1, psidesktop, 0, 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| roots[0] = psidesktop; | |
| roots[1] = psitestdir2; | |
| roots[2] = psidesktop; | |
| roots[3] = psidesktop2; | |
| roots[4] = psitestdir2; | |
| roots[5] = psitestdir; | |
| roots[6] = psitestdir2; | |
| roots[7] = psidesktop; | |
| roots[8] = psitestdir2; | |
| roots[9] = NULL; | |
| verify_root_order(pnstc, roots); | |
| /* CollapseAll */ | |
| hr = INameSpaceTreeControl_CollapseAll(pnstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_CollapseAll(pnstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| /* SetItemState message checks */ | |
| res = subclass_treeview(pnstc); | |
| ok(res, "Failed to subclass treeview.\n"); | |
| if(res) | |
| { | |
| UINT isMask, isFlags; | |
| hr = INameSpaceTreeControl_AppendRoot( | |
| pnstc, psidesktop, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| flush_sequences(sequences, NUM_MSG_SEQUENCES); | |
| /* A special case - | |
| * The first expansion results in an "unrelated" TVM_SETITEMW being sent | |
| * (mask == 0x50 (TVIF_CHILDREN|TVIF_HANDLE) ) | |
| */ | |
| tvi_count = 0; | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, | |
| NSTCIS_EXPANDED, NSTCIS_EXPANDED); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| todo_wine | |
| { | |
| ok(tvi_count == 1, "Got %d\n", tvi_count); | |
| ok(last_tvi.mask == 0x50, "Got mask %x, expected 0x50\n", last_tvi.mask); | |
| } | |
| tvi_count = 0; | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, | |
| NSTCIS_EXPANDED, NSTCIS_EXPANDED); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(tvi_count == 0, "Got %d\n", tvi_count); | |
| /* Test all the combinations of NSTCIS_SELECTED to NSTCIS_SELECTEDNOEXPAND */ | |
| flush_sequences(sequences, NUM_MSG_SEQUENCES); | |
| for(isMask = 0; isMask <= 0x1f; isMask++) | |
| { | |
| for(isFlags = 0; isFlags <= 0x1f; isFlags++) | |
| { | |
| UINT select_sent, select_sent_vista, ensurev_sent, expand_sent; | |
| TVITEMEXW tviexp; | |
| UINT msg_count; | |
| flush_sequences(sequences, NUM_MSG_SEQUENCES); | |
| tvi_count = 0; | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, isMask, isFlags); | |
| ok(hr == S_OK, "(%x|%x)Got 0x%08x\n", isMask, isFlags, hr); | |
| /*****************************/ | |
| /* Calculate expected values */ | |
| /*****************************/ | |
| /* Number of TVM_SELECTITEM/TVM_ENSUREVISIBLE and TVM_EXPAND sent */ | |
| select_sent = ((isMask&isFlags) & NSTCIS_SELECTED)?1:0; | |
| select_sent_vista = ensurev_sent = select_sent; | |
| select_sent += ((isMask&isFlags) & NSTCIS_SELECTEDNOEXPAND)?1:0; | |
| select_sent_vista += ((isMask&isFlags) & NSTCIS_EXPANDED)?1:0; | |
| expand_sent = ((isMask|isFlags) & NSTCIS_EXPANDED)?1:0; | |
| /* Possible TWM_SETITEMW message and its contents */ | |
| if(isMask & NSTCIS_DISABLED) | |
| tviexp.mask = TVIF_STATE | TVIF_STATEEX; | |
| else if( ((isMask^isFlags) & (NSTCIS_SELECTED|NSTCIS_EXPANDED|NSTCIS_SELECTEDNOEXPAND)) || | |
| ((isMask|isFlags) & NSTCIS_BOLD) || (isFlags & NSTCIS_DISABLED) ) | |
| tviexp.mask = TVIF_STATE; | |
| else | |
| tviexp.mask = 0; | |
| if(tviexp.mask) | |
| { | |
| tviexp.stateMask = tviexp.state = 0; | |
| tviexp.stateMask |= ((isMask^isFlags)&NSTCIS_SELECTED) ? TVIS_SELECTED : 0; | |
| tviexp.stateMask |= (isMask|isFlags)&NSTCIS_BOLD ? TVIS_BOLD:0; | |
| tviexp.state |= (isMask&isFlags)&NSTCIS_BOLD ? TVIS_BOLD:0; | |
| if((isMask&NSTCIS_EXPANDED)^(isFlags&NSTCIS_EXPANDED)) | |
| { | |
| tviexp.stateMask = 0; | |
| } | |
| tviexp.uStateEx = (isFlags&isMask)&NSTCIS_DISABLED?TVIS_EX_DISABLED:0; | |
| } | |
| else | |
| { | |
| /* Make sure that no tests accidentally succeeded | |
| * (and avoid a gcc warning) */ | |
| tviexp.stateMask = tviexp.state = tviexp.uStateEx = -1; | |
| } | |
| /*****************************/ | |
| /* Check the values. */ | |
| /*****************************/ | |
| msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_SELECTITEM); | |
| ok(msg_count == select_sent || broken(msg_count == select_sent_vista), | |
| "(%x|%x) Got msg_count %d, expected %d (%d)\n", | |
| isMask, isFlags, msg_count, select_sent, select_sent_vista); | |
| msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_ENSUREVISIBLE); | |
| ok(msg_count == ensurev_sent || broken(msg_count == 0 /* Vista */), | |
| "(%x|%x) Got msg_count %d, expected %d\n", | |
| isMask, isFlags, msg_count, ensurev_sent); | |
| msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_EXPAND); | |
| ok(msg_count == expand_sent, "(%x|%x) Got msg_count %d, expected %d\n", | |
| isMask, isFlags, msg_count, expand_sent); | |
| msg_count = get_msg_count(sequences, TREEVIEW_SEQ_INDEX, TVM_SETITEMW); | |
| if(!tviexp.mask) | |
| { | |
| /* Four special cases for vista */ | |
| BOOL vista_check = ( (isMask == 0x10 && isFlags == 0x10) || | |
| (isMask == 0x11 && isFlags == 0x11) || | |
| (isMask == 0x12 && isFlags == 0x12) || | |
| (isMask == 0x13 && isFlags == 0x13) ); | |
| ok(msg_count == 0 || broken(msg_count == 1 && vista_check), | |
| "(%x|%x) Got msg_count %d (tviexp.mask %x)\n", | |
| isMask, isFlags, msg_count, tviexp.mask); | |
| } | |
| else | |
| { | |
| ok(msg_count == 1, "(%x|%x) Got msg_count %d, expected 1\n", | |
| isMask, isFlags, msg_count); | |
| ok(last_tvi.mask == tviexp.mask, | |
| "(%x|%x) Got mask %x, expected %x\n", | |
| isMask, isFlags, last_tvi.mask, tviexp.mask); | |
| ok(last_tvi.stateMask == tviexp.stateMask, | |
| "(%x|%x) Got stateMask %x, expected %x\n", | |
| isMask, isFlags, last_tvi.stateMask, tviexp.stateMask); | |
| ok(last_tvi.state == tviexp.state, | |
| "(%x|%x) Got state %x, expected %x\n", | |
| isMask, isFlags, last_tvi.state, tviexp.state); | |
| ok(last_tvi.uStateEx == tviexp.uStateEx, | |
| "(%x|%x) Got uStateEx %x, expected %x\n", | |
| isMask, isFlags, last_tvi.uStateEx, tviexp.uStateEx); | |
| } | |
| } | |
| } | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| } | |
| /* GetSelectedItems */ | |
| if(0) | |
| { | |
| /* Crashes under Windows 7 */ | |
| INameSpaceTreeControl_GetSelectedItems(pnstc, NULL); | |
| } | |
| psia = (void*)0xdeadbeef; | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| ok(!psia || broken(psia == (void*)0xdeadbeef /* before Win8 */), "Got %p\n", psia); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, SHCONTF_FOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psitestdir, | |
| NSTCIS_SELECTED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| UINT count; | |
| hr = IShellItemArray_GetCount(psia, &count); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(count == 1, "Got %d selected items.\n", count); | |
| if(count) | |
| { | |
| hr = IShellItemArray_GetItemAt(psia, 0, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| IShellItem_Release(psi); | |
| } | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psitestdir2, | |
| NSTCIS_SELECTED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| UINT count; | |
| hr = IShellItemArray_GetCount(psia, &count); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(count == 1, "Got %d selected items.\n", count); | |
| if(count) | |
| { | |
| hr = IShellItemArray_GetItemAt(psia, 0, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| IShellItem_Release(psi); | |
| } | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psitest1, | |
| NSTCIS_SELECTED, NSTCIS_SELECTED); | |
| todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| UINT count; | |
| hr = IShellItemArray_GetCount(psia, &count); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(count == 1, "Got %d selected items.\n", count); | |
| if(count) | |
| { | |
| hr = IShellItemArray_GetItemAt(psia, 0, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitest1, SICHINT_DISPLAY, &cmp); | |
| todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| IShellItem_Release(psi); | |
| } | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK || broken(hr == E_FAIL), "Got 0x%08x\n", hr); | |
| if(hr == E_FAIL) | |
| { | |
| /* For some reason, Vista fails to properly remove both the | |
| * roots here on the first try. */ | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| } | |
| /* Adding without NSTCRS_EXPANDED does not set the selection */ | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| 0, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir, 0xFF, &istate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!(istate & NSTCIS_SELECTED), "Got 0x%08x\n", istate); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) IShellItemArray_Release(psia); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| /* Adding with NSTCRS_EXPANDED sets the selection */ | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| NSTCRS_EXPANDED, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir, 0xFF, &istate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| todo_wine ok(istate & NSTCIS_SELECTED, "Got 0x%08x\n", istate); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| IShellItem *psi; | |
| hr = IShellItemArray_GetItemAt(psia, 0, &psi); | |
| if(SUCCEEDED(hr)) | |
| { | |
| INT cmp; | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| IShellItem_Release(psi); | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| /* Adding a second root with NSTCRS_EXPANDED does not change the selection */ | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir2, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| NSTCRS_EXPANDED, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psitestdir2, 0xFF, &istate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!(istate & NSTCIS_SELECTED), "Got 0x%08x\n", istate); | |
| hr = INameSpaceTreeControl_GetSelectedItems(pnstc, &psia); | |
| todo_wine ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| IShellItem *psi; | |
| hr = IShellItemArray_GetItemAt(psia, 0, &psi); | |
| if(SUCCEEDED(hr)) | |
| { | |
| INT cmp; | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| IShellItem_Release(psi); | |
| } | |
| IShellItemArray_Release(psia); | |
| } | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| /* GetItemRect */ | |
| SetRectEmpty(&rc); | |
| if(0) | |
| { | |
| /* Crashes under win 7 */ | |
| INameSpaceTreeControl_GetItemRect(pnstc, NULL, NULL); | |
| INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, NULL); | |
| INameSpaceTreeControl_GetItemRect(pnstc, NULL, &rc); | |
| } | |
| hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, &rc); | |
| ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| NSTCRS_EXPANDED, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir, &rc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(rc.top != rc.bottom, "Got 0 height.\n"); | |
| ok(rc.left != rc.right, "Got 0 width.\n"); | |
| height = 0; | |
| hwnd_tv = get_treeview_hwnd(pnstc); | |
| if(hwnd_tv) | |
| { | |
| HTREEITEM hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0); | |
| ok(hroot != NULL, "Failed to get root.\n"); | |
| if(hroot) | |
| { | |
| RECT tv_rc; | |
| BOOL bret; | |
| *(HTREEITEM*)&tv_rc = hroot; | |
| bret = SendMessageW(hwnd_tv, TVM_GETITEMRECT, FALSE, (LPARAM)&tv_rc); | |
| ok(bret, "TVM_GETITEMRECT failed.\n"); | |
| /* The NamespaceTreeControl returns screen coordinates. */ | |
| MapWindowPoints(NULL, hwnd, (POINT*)&rc, 2); | |
| ok(EqualRect(&rc, &tv_rc), "Differed, got %s and %s\n", wine_dbgstr_rect(&rc), | |
| wine_dbgstr_rect(&tv_rc)); | |
| /* Save the height and compare to that of other items. | |
| Observed values: 18, 19, 21 */ | |
| height = rc.bottom - rc.top; | |
| trace("height: %d\n", height); | |
| } | |
| } | |
| else | |
| win_skip("Skipping some GetItemRect tests.\n"); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| /* HitTest */ | |
| hr = INameSpaceTreeControl_HitTest(pnstc, NULL, NULL); | |
| ok(hr == E_POINTER, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, NULL); | |
| ok(hr == E_POINTER, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_HitTest(pnstc, NULL, &psi); | |
| ok(hr == E_POINTER, "Got 0x%08x\n", hr); | |
| psi = (void*)0xdeadbeef; | |
| pt.x = pt.y = 0; | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi); | |
| ok(hr == S_FALSE, "Got 0x%08x\n", hr); | |
| ok(psi == NULL, "Got psi %p\n", psi); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| NSTCRS_EXPANDED, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| process_msgs(); | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!cmp, "Got cmp %d\n", cmp); | |
| IShellItem_Release(psi); | |
| } | |
| pt.y += height - 1; | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!cmp, "Got cmp %d\n", cmp); | |
| IShellItem_Release(psi); | |
| } | |
| pt.y += 1; | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| todo_wine | |
| { | |
| hr = IShellItem_Compare(psi, psitestdir, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_FALSE, "Got 0x%08x\n", hr); | |
| ok(cmp, "no cmp value.\n"); | |
| hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!cmp, "Got cmp %d\n", cmp); | |
| } | |
| IShellItem_Release(psi); | |
| } | |
| hr = INameSpaceTreeControl_GetItemRect(pnstc, psitestdir2, &rc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| MapWindowPoints(NULL, hwnd, (POINT*)&rc, 2); | |
| pt.x = rc.left; pt.y = rc.top; | |
| hr = INameSpaceTreeControl_HitTest(pnstc, &pt, &psi); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| int cmp; | |
| hr = IShellItem_Compare(psi, psitestdir2, SICHINT_DISPLAY, &cmp); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(!cmp, "Got cmp %d\n", cmp); | |
| IShellItem_Release(psi); | |
| } | |
| } | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| /* GetItemCustomState / SetItemCustomState */ | |
| if(0) | |
| { | |
| /* Crashes under Windows 7 */ | |
| INameSpaceTreeControl_GetItemCustomState(pnstc, NULL, NULL); | |
| INameSpaceTreeControl_GetItemCustomState(pnstc, NULL, &cbstate); | |
| INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, NULL); | |
| INameSpaceTreeControl_SetItemCustomState(pnstc, NULL, 0); | |
| } | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psitestdir, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, | |
| 0, NULL); | |
| process_msgs(); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| todo_wine | |
| { | |
| cbstate = -1; | |
| hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(cbstate == BST_UNCHECKED || broken(cbstate == BST_CHECKED /* Vista x64 */), | |
| "Got %d\n", cbstate); | |
| hr = INameSpaceTreeControl_SetItemCustomState(pnstc, psitestdir, BST_CHECKED); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| cbstate = -1; | |
| hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(cbstate == BST_CHECKED, "Got %d\n", cbstate); | |
| hr = INameSpaceTreeControl_SetItemCustomState(pnstc, psitestdir, 0xFFF); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| cbstate = -1; | |
| hr = INameSpaceTreeControl_GetItemCustomState(pnstc, psitestdir, &cbstate); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(cbstate == 0xF, "Got %d\n", cbstate); | |
| } | |
| /* SetTheme */ | |
| todo_wine | |
| { | |
| hr = INameSpaceTreeControl_SetTheme(pnstc, NULL); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_SetTheme(pnstc, explorerW); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| hr = INameSpaceTreeControl_SetTheme(pnstc, randomW); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| } | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| IShellItem_Release(psidesktop); | |
| IShellItem_Release(psidesktop2); | |
| IShellItem_Release(psitestdir); | |
| IShellItem_Release(psitestdir2); | |
| IShellItem_Release(psitest1); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| HWND hwnd_nstc; | |
| hr = IOleWindow_GetWindow(pow, &hwnd_nstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| DestroyWindow(hwnd_nstc); | |
| IOleWindow_Release(pow); | |
| } | |
| res = INameSpaceTreeControl_Release(pnstc); | |
| ok(!res, "res was %d!\n", res); | |
| cleanup: | |
| Cleanup(); | |
| } | |
| static void test_events(void) | |
| { | |
| INameSpaceTreeControl *pnstc; | |
| INameSpaceTreeControlEventsImpl *pnstceimpl, *pnstceimpl2; | |
| INameSpaceTreeControlEvents *pnstce, *pnstce2; | |
| IShellFolder *psfdesktop; | |
| IShellItem *psidesktop; | |
| IOleWindow *pow; | |
| LPITEMIDLIST pidl_desktop; | |
| LPITEMIDLIST pidl_drives; | |
| NSTCITEMSTATE itemstate; | |
| IShellItem *psi; | |
| DWORD cookie1, cookie2; | |
| HWND hwnd_tv; | |
| HRESULT hr; | |
| UINT res; | |
| hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER, | |
| &IID_INameSpaceTreeControl, (void**)&pnstc); | |
| ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr); | |
| ok(pSHCreateShellItem != NULL, "No SHCreateShellItem.\n"); | |
| ok(pSHGetIDListFromObject != NULL, "No SHCreateShellItem.\n"); | |
| SHGetDesktopFolder(&psfdesktop); | |
| hr = pSHGetIDListFromObject((IUnknown*)psfdesktop, &pidl_desktop); | |
| IShellFolder_Release(psfdesktop); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psidesktop); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ILFree(pidl_desktop); | |
| /* Create two instances of INameSpaceTreeControlEvents */ | |
| pnstceimpl = create_nstc_events(); | |
| pnstce = &pnstceimpl->INameSpaceTreeControlEvents_iface; | |
| ZeroMemory(&pnstceimpl->count, sizeof(UINT)*LastEvent); | |
| pnstceimpl2 = create_nstc_events(); | |
| pnstce2 = &pnstceimpl2->INameSpaceTreeControlEvents_iface; | |
| if(0) | |
| { | |
| /* Crashes native */ | |
| INameSpaceTreeControl_TreeAdvise(pnstc, NULL, NULL); | |
| INameSpaceTreeControl_TreeAdvise(pnstc, NULL, &cookie1); | |
| INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, NULL); | |
| } | |
| /* TreeAdvise in NameSpaceTreeController seems to support only one | |
| * client at the time. | |
| */ | |
| /* First, respond with E_NOINTERFACE to all QI's */ | |
| pnstceimpl->qi_enable_events = FALSE; | |
| pnstceimpl->qi_called_count = 0; | |
| cookie1 = 1; | |
| hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok(cookie1 == 0, "cookie now (0x%08x)\n", cookie1); | |
| ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref); | |
| /* Accept query for IID_INameSpaceTreeControlEvents */ | |
| pnstceimpl->qi_enable_events = TRUE; | |
| pnstceimpl->qi_called_count = 0; | |
| cookie1 = 0; | |
| hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(cookie1 == 1, "cookie now (0x%08x)\n", cookie1); | |
| ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref); | |
| /* A second time, query interface will not be called at all. */ | |
| pnstceimpl->qi_enable_events = TRUE; | |
| pnstceimpl->qi_called_count = 0; | |
| cookie2 = 1; | |
| hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie2); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2); | |
| ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n", | |
| pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref); | |
| /* Using another "instance" does not help. */ | |
| pnstceimpl2->qi_enable_events = TRUE; | |
| pnstceimpl2->qi_called_count = 0; | |
| cookie2 = 1; | |
| hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce2, &cookie2); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2); | |
| ok(!pnstceimpl2->qi_called_count, "QueryInterface called %d times.\n", | |
| pnstceimpl2->qi_called_count); | |
| ok(pnstceimpl2->ref == 1, "refcount was %d\n", pnstceimpl->ref); | |
| /* Unadvise with bogus cookie (will actually unadvise properly) */ | |
| pnstceimpl->qi_enable_events = TRUE; | |
| pnstceimpl->qi_called_count = 0; | |
| hr = INameSpaceTreeControl_TreeUnadvise(pnstc, 1234); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n", | |
| pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref); | |
| /* Unadvise "properly" (will have no additional effect) */ | |
| pnstceimpl->qi_enable_events = TRUE; | |
| pnstceimpl->qi_called_count = 0; | |
| hr = INameSpaceTreeControl_TreeUnadvise(pnstc, cookie1); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(!pnstceimpl->qi_called_count, "QueryInterface called %d times.\n", | |
| pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref); | |
| /* Advise again.. */ | |
| pnstceimpl->qi_enable_events = 1; | |
| pnstceimpl->qi_called_count = 0; | |
| hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie2); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(cookie2 == 1, "Cookie is %d\n", cookie2); | |
| ok(cookie1 == cookie2, "Old cookie differs from old cookie.\n"); | |
| /* several kinds of callbacks are queried for */ | |
| ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); | |
| ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref); | |
| /* Initialize the control */ | |
| hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, NULL, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_event_count(pnstceimpl, OnGetDefaultIconIndex, 0); | |
| ok_no_events(pnstceimpl); | |
| hwnd_tv = get_treeview_hwnd(pnstc); | |
| ok(hwnd_tv != NULL, "Failed to get hwnd_tv HWND.\n"); | |
| if(hwnd_tv) | |
| { | |
| HTREEITEM hroot, hitem; | |
| UINT i; | |
| static const UINT kbd_msgs_event[] = { | |
| WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_SYSKEYDOWN, WM_SYSKEYUP, | |
| WM_SYSCHAR, 0 }; | |
| static const UINT kbd_msgs_noevent[] ={ | |
| WM_DEADCHAR, WM_SYSDEADCHAR, WM_UNICHAR, 0 }; | |
| /* Test On*Expand */ | |
| hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0); | |
| SendMessageW(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot); | |
| process_msgs(); | |
| ok_event_count(pnstceimpl, OnBeforeExpand, 1); | |
| ok_event_count(pnstceimpl, OnAfterExpand, 1); | |
| ok_event_broken(pnstceimpl, OnItemAdded); /* No event on Vista */ | |
| todo_wine ok_event_count(pnstceimpl, OnSelectionChanged, 1); | |
| ok_no_events(pnstceimpl); | |
| SendMessageW(hwnd_tv, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hroot); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| SendMessageW(hwnd_tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)hroot); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| /* Test OnSelectionChanged */ | |
| hitem = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hroot); | |
| SendMessageW(hwnd_tv, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hitem); | |
| process_msgs(); | |
| ok_event_count(pnstceimpl, OnSelectionChanged, 1); | |
| ok_no_events(pnstceimpl); | |
| /* Test OnKeyboardInput */ | |
| for(i = 0; kbd_msgs_event[i] != 0; i++) | |
| { | |
| SendMessageW(hwnd_tv, kbd_msgs_event[i], 0x1234, 0x1234); | |
| ok(pnstceimpl->count[OnKeyboardInput] == 1, | |
| "%d (%x): Got count %d\n", | |
| kbd_msgs_event[i], kbd_msgs_event[i], pnstceimpl->count[OnKeyboardInput]); | |
| pnstceimpl->count[OnKeyboardInput] = 0; | |
| } | |
| for(i = 0; kbd_msgs_noevent[i] != 0; i++) | |
| { | |
| SendMessageW(hwnd_tv, kbd_msgs_noevent[i], 0x1234, 0x1234); | |
| ok(pnstceimpl->count[OnKeyboardInput] == 0, | |
| "%d (%x): Got count %d\n", | |
| kbd_msgs_noevent[i], kbd_msgs_noevent[i], pnstceimpl->count[OnKeyboardInput]); | |
| pnstceimpl->count[OnKeyboardInput] = 0; | |
| } | |
| ok_no_events(pnstceimpl); | |
| } | |
| else | |
| skip("Skipping some tests.\n"); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| process_msgs(); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok_event(pnstceimpl, OnItemDeleted); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| /* Expand the root */ | |
| itemstate |= NSTCIS_EXPANDED; | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count(pnstceimpl, OnBeforeExpand, 1); | |
| ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */ | |
| ok_event_count(pnstceimpl, OnAfterExpand, 1); | |
| todo_wine | |
| { | |
| ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /* Vista*/); | |
| } | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate & NSTCIS_EXPANDED, "Item not expanded.\n"); | |
| todo_wine | |
| { | |
| ok(itemstate == (NSTCIS_SELECTED | NSTCIS_EXPANDED)|| | |
| broken(itemstate == NSTCIS_EXPANDED) /* Vista */, | |
| "itemstate is 0x%08x\n", itemstate); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /* Vista*/); | |
| } | |
| ok_no_events(pnstceimpl); | |
| /* Deselect the root */ | |
| itemstate &= ~NSTCIS_SELECTED; | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == (NSTCIS_EXPANDED), "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_CollapseAll(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| /* Delete all roots */ | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_event_count(pnstceimpl, OnItemDeleted, 1); | |
| ok_no_events(pnstceimpl); | |
| /* Get/SetItemState */ | |
| if(0) | |
| { | |
| /* Crashes on Windows 7 */ | |
| INameSpaceTreeControl_SetItemState(pnstc, NULL, 0, 0); | |
| INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, NULL); | |
| INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0, NULL); | |
| INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, &itemstate); | |
| INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0, NULL); | |
| INameSpaceTreeControl_GetItemState(pnstc, NULL, 0, &itemstate); | |
| } | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, | |
| SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0, 0xffff); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| todo_wine | |
| { | |
| ok_event_count(pnstceimpl, OnBeforeExpand, 0); | |
| ok_event_count(pnstceimpl, OnAfterExpand, 0); | |
| ok_event_count(pnstceimpl, OnItemAdded, 0); | |
| } | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| todo_wine | |
| ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count(pnstceimpl, OnSelectionChanged, 1); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_EXPANDED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_SELECTEDNOEXPAND); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_SELECTED, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, NSTCIS_EXPANDED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| todo_wine | |
| { | |
| ok_event_count(pnstceimpl, OnBeforeExpand, 1); | |
| ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */ | |
| ok_event_count(pnstceimpl, OnAfterExpand, 1); | |
| } | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_EXPANDED, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_NONE, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff, 0xffff); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| todo_wine | |
| { | |
| ok(itemstate == (NSTCIS_EXPANDED | NSTCIS_BOLD | NSTCIS_DISABLED), | |
| "itemstate is 0x%08x\n", itemstate); | |
| } | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_SELECTED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| todo_wine | |
| { | |
| ok(itemstate == (NSTCIS_EXPANDED | NSTCIS_BOLD | NSTCIS_DISABLED), | |
| "itemstate is 0x%08x\n", itemstate); | |
| } | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, | |
| NSTCIS_SELECTED | NSTCIS_DISABLED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == (NSTCIS_BOLD | NSTCIS_EXPANDED), | |
| "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_SELECTED, NSTCIS_SELECTED); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == (NSTCIS_BOLD | NSTCIS_EXPANDED), | |
| "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, 0xffff & ~NSTCIS_DISABLED, 0); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| itemstate = 0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetItemState(pnstc, psidesktop, 0xffff, &itemstate); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok(itemstate == NSTCIS_BOLD, "itemstate is 0x%08x\n", itemstate); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_event_count(pnstceimpl, OnItemDeleted, 1); | |
| ok_no_events(pnstceimpl); | |
| /* GetNextItem */ | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, NULL, 0, NULL); | |
| ok(hr == E_POINTER, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, 0, NULL); | |
| ok(hr == E_POINTER, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, NULL, 0, &psi); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, 0, &psi); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_no_events(pnstceimpl); | |
| /* Get child from unexpanded and unfilled parent */ | |
| psi = (void*)0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, NSTCGNI_CHILD, &psi); | |
| ok(hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok(psi == NULL, "psi is %p\n", psi); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| /* Expand and try again */ | |
| hr = INameSpaceTreeControl_SetItemState(pnstc, psidesktop, NSTCIS_EXPANDED, 0xffff); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count(pnstceimpl, OnBeforeExpand, 1); | |
| ok_event_broken(pnstceimpl, OnItemAdded); /* Does not fire on Vista */ | |
| ok_event_count(pnstceimpl, OnAfterExpand, 1); | |
| todo_wine ok_event_count_broken(pnstceimpl, OnSelectionChanged, 1, 0 /*Vista */); | |
| ok_no_events(pnstceimpl); | |
| psi = (void*)0xDEADBEEF; | |
| hr = INameSpaceTreeControl_GetNextItem(pnstc, psidesktop, NSTCGNI_CHILD, &psi); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok((psi != NULL) && (psi != (void*)0xDEADBEEF), "psi is %p\n", psi); | |
| process_msgs(); | |
| ok_no_events(pnstceimpl); | |
| if(SUCCEEDED(hr)) IShellItem_Release(psi); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_event_count(pnstceimpl, OnItemDeleted, 1); | |
| ok_no_events(pnstceimpl); | |
| /* EnsureItemVisible */ | |
| if(0) | |
| { | |
| /* Crashes on Windows 7 */ | |
| INameSpaceTreeControl_EnsureItemVisible(pnstc, NULL); | |
| } | |
| hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop); | |
| ok(hr == E_INVALIDARG || hr == E_FAIL, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = pSHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl_drives); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| hr = pSHCreateShellItem(NULL, NULL, pidl_drives, &psi); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psi, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop); | |
| ok(hr == E_INVALIDARG, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psi); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_AppendRoot(pnstc, psidesktop, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 0, NULL); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| process_msgs(); | |
| ok_event_count_broken(pnstceimpl, OnItemAdded, 1, 0 /* Vista */); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psidesktop); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_EnsureItemVisible(pnstc, psi); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_no_events(pnstceimpl); | |
| } | |
| else | |
| skip("Failed to create shellitem.\n"); | |
| ILFree(pidl_drives); | |
| } | |
| else | |
| skip("Failed to get pidl for CSIDL_DRIVES.\n"); | |
| hr = INameSpaceTreeControl_RemoveAllRoots(pnstc); | |
| ok(hr == S_OK, "Got (0x%08x)\n", hr); | |
| ok_event_count(pnstceimpl, OnItemDeleted, 2); | |
| ok_no_events(pnstceimpl); | |
| hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| if(SUCCEEDED(hr)) | |
| { | |
| HWND hwnd_nstc; | |
| hr = IOleWindow_GetWindow(pow, &hwnd_nstc); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| DestroyWindow(hwnd_nstc); | |
| IOleWindow_Release(pow); | |
| } | |
| hr = INameSpaceTreeControl_TreeUnadvise(pnstc, cookie2); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| res = INameSpaceTreeControl_Release(pnstc); | |
| ok(!res, "res was %d!\n", res); | |
| if(!res) | |
| { | |
| /* Freeing these prematurely causes a crash. */ | |
| HeapFree(GetProcessHeap(), 0, pnstceimpl); | |
| HeapFree(GetProcessHeap(), 0, pnstceimpl2); | |
| } | |
| IShellItem_Release(psi); | |
| IShellItem_Release(psidesktop); | |
| } | |
| static void setup_window(void) | |
| { | |
| WNDCLASSA wc; | |
| static const char nstctest_wnd_name[] = "nstctest_wnd"; | |
| ZeroMemory(&wc, sizeof(WNDCLASSA)); | |
| wc.lpfnWndProc = DefWindowProcA; | |
| wc.lpszClassName = nstctest_wnd_name; | |
| RegisterClassA(&wc); | |
| hwnd = CreateWindowA(nstctest_wnd_name, NULL, WS_TABSTOP, | |
| 0, 0, 200, 200, NULL, 0, 0, NULL); | |
| ok(hwnd != NULL, "Failed to create window for test (lasterror: %d).\n", | |
| GetLastError()); | |
| } | |
| static void destroy_window(void) | |
| { | |
| DestroyWindow(hwnd); | |
| } | |
| START_TEST(nstc) | |
| { | |
| OleInitialize(NULL); | |
| setup_window(); | |
| init_function_pointers(); | |
| init_msg_sequences(sequences, NUM_MSG_SEQUENCES); | |
| if(test_initialization()) | |
| { | |
| test_basics(); | |
| test_events(); | |
| } | |
| else | |
| win_skip("No NamespaceTreeControl (or instantiation failed).\n"); | |
| destroy_window(); | |
| OleUninitialize(); | |
| } |