[PATCH 4/8] explorerframe/nstc: Add IOleWindow implementation.

David Hedberg david.hedberg at gmail.com
Thu Jul 29 14:10:18 CDT 2010


---
 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 8c3b403..9e69c01 100644
--- a/dlls/explorerframe/nstc.c
+++ b/dlls/explorerframe/nstc.c
@@ -34,6 +34,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)
     {
@@ -536,6 +541,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;
@@ -553,6 +614,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 0ecec68..f7f6e5e 100644
--- a/dlls/explorerframe/tests/nstc.c
+++ b/dlls/explorerframe/tests/nstc.c
@@ -33,7 +33,9 @@ static HWND hwnd;
 static void test_initialization(void)
 {
     INameSpaceTreeControl2 *pnstc;
+    IOleWindow *pow;
     IUnknown *punk;
+    HWND hwnd_host1;
     LONG lres;
     HRESULT hr;
     RECT rc;
@@ -58,8 +60,89 @@ static void test_initialization(void)
     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);
@@ -85,8 +168,13 @@ static void 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);
 }
 
 static BOOL have_INameSpaceTreeControl(void)
-- 
1.7.2




More information about the wine-patches mailing list