Module: wine Branch: master Commit: c32fa3485bb1c38fbd23fd39feea9f3d98aaef80 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c32fa3485bb1c38fbd23fd39fe...
Author: David Hedberg david.hedberg@gmail.com Date: Tue Aug 3 03:43:08 2010 +0200
explorerframe: Add IOleWindow implementation.
---
dlls/explorerframe/nstc.c | 62 +++++++++++++++++++++++++++ dlls/explorerframe/tests/nstc.c | 90 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 1 deletions(-)
diff --git a/dlls/explorerframe/nstc.c b/dlls/explorerframe/nstc.c index 2f2c3dc..e9c8346 100644 --- a/dlls/explorerframe/nstc.c +++ b/dlls/explorerframe/nstc.c @@ -36,6 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(nstc);
typedef struct { const INameSpaceTreeControl2Vtbl *lpVtbl; + const IOleWindowVtbl *lpowVtbl; LONG ref;
HWND hwnd_main; @@ -207,6 +208,10 @@ static HRESULT WINAPI NSTC2_fnQueryInterface(INameSpaceTreeControl2* iface, { *ppvObject = This; } + else if(IsEqualIID(riid, &IID_IOleWindow)) + { + *ppvObject = &This->lpowVtbl; + }
if(*ppvObject) { @@ -531,6 +536,62 @@ static const INameSpaceTreeControl2Vtbl vt_INameSpaceTreeControl2 = { NSTC2_fnGetControlStyle2 };
+/************************************************************************** + * IOleWindow Implementation + */ + +static inline NSTC2Impl *impl_from_IOleWindow(IOleWindow *iface) +{ + return (NSTC2Impl *)((char*)iface - FIELD_OFFSET(NSTC2Impl, lpowVtbl)); +} + +static HRESULT WINAPI IOW_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObject) +{ + NSTC2Impl *This = impl_from_IOleWindow(iface); + TRACE("%p\n", This); + return NSTC2_fnQueryInterface((INameSpaceTreeControl2*)This, riid, ppvObject); +} + +static ULONG WINAPI IOW_fnAddRef(IOleWindow *iface) +{ + NSTC2Impl *This = impl_from_IOleWindow(iface); + TRACE("%p\n", This); + return NSTC2_fnAddRef((INameSpaceTreeControl2*)This); +} + +static ULONG WINAPI IOW_fnRelease(IOleWindow *iface) +{ + NSTC2Impl *This = impl_from_IOleWindow(iface); + TRACE("%p\n", This); + return NSTC2_fnRelease((INameSpaceTreeControl2*)This); +} + +static HRESULT WINAPI IOW_fnGetWindow(IOleWindow *iface, HWND *phwnd) +{ + NSTC2Impl *This = impl_from_IOleWindow(iface); + TRACE("%p (%p)\n", This, phwnd); + + *phwnd = This->hwnd_main; + return S_OK; +} + +static HRESULT WINAPI IOW_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode) +{ + NSTC2Impl *This = impl_from_IOleWindow(iface); + TRACE("%p (%d)\n", This, fEnterMode); + + /* Not implemented */ + return E_NOTIMPL; +} + +static const IOleWindowVtbl vt_IOleWindow = { + IOW_fnQueryInterface, + IOW_fnAddRef, + IOW_fnRelease, + IOW_fnGetWindow, + IOW_fnContextSensitiveHelp +}; + HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) { NSTC2Impl *nstc; @@ -548,6 +609,7 @@ HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, void nstc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NSTC2Impl)); nstc->ref = 1; nstc->lpVtbl = &vt_INameSpaceTreeControl2; + nstc->lpowVtbl = &vt_IOleWindow;
ret = INameSpaceTreeControl_QueryInterface((INameSpaceTreeControl*)nstc, riid, ppv); INameSpaceTreeControl_Release((INameSpaceTreeControl*)nstc); diff --git a/dlls/explorerframe/tests/nstc.c b/dlls/explorerframe/tests/nstc.c index 122cb8d..6a72eb3 100644 --- a/dlls/explorerframe/tests/nstc.c +++ b/dlls/explorerframe/tests/nstc.c @@ -34,7 +34,9 @@ static HWND hwnd; static BOOL test_initialization(void) { INameSpaceTreeControl *pnstc; + IOleWindow *pow; IUnknown *punk; + HWND hwnd_host1; LONG lres; HRESULT hr; RECT rc; @@ -60,8 +62,89 @@ static BOOL test_initialization(void) 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 */ hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleInPlaceObject, (void**)&punk); @@ -87,8 +170,13 @@ static BOOL test_initialization(void)
/* 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); + ok(!lres, "lres was %d\n", lres);
return TRUE; }