[PATCH] Initial test file for IShellView/IFolderView, implemented IFolderView::GetSpacing

Nikolay Sivov nsivov at codeweavers.com
Sat Mar 6 14:53:00 CST 2010


---
 dlls/shell32/shlview.c         |   27 ++-
 dlls/shell32/tests/Makefile.in |    1 +
 dlls/shell32/tests/msg.h       |  294 +++++++++++++++++++++++++++
 dlls/shell32/tests/shlview.c   |  433 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 749 insertions(+), 6 deletions(-)
 create mode 100644 dlls/shell32/tests/msg.h
 create mode 100644 dlls/shell32/tests/shlview.c

diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index b9a250d..2b1ac1f 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -2023,6 +2023,7 @@ static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2C
 {
     IShellViewImpl *This = (IShellViewImpl *)iface;
     WNDCLASSW wc;
+    HRESULT hr;
     HWND wnd;
 
     TRACE("(%p)->(view_params %p)\n", iface, view_params);
@@ -2039,6 +2040,8 @@ static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2C
             view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
             view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
 
+    if (!view_params->psbOwner) return E_UNEXPECTED;
+
     /* Set up the member variables */
     This->pShellBrowser = view_params->psbOwner;
     This->FolderSettings = *view_params->pfs;
@@ -2069,10 +2072,9 @@ static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2C
 
     /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
     This->pCommDlgBrowser = NULL;
-    if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
-    {
+    hr = IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser);
+    if (hr == S_OK)
         TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
-    }
 
     /* If our window class has not been registered, then do so */
     if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
@@ -2755,9 +2757,22 @@ static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD
 
 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
 {
-	IShellViewImpl *This = impl_from_IFolderView(iface);
-	FIXME("(%p)->(%p), stub\n", This, pt);
-	return E_NOTIMPL;
+    IShellViewImpl *This = impl_from_IFolderView(iface);
+
+    TRACE("(%p)->(%p)\n", This, pt);
+
+    if (!This->hWndList) return S_FALSE;
+
+    if (pt)
+    {
+        DWORD ret;
+        ret = SendMessageW(This->hWndList, LVM_GETITEMSPACING, 0, 0);
+
+        pt->x = LOWORD(ret);
+        pt->y = HIWORD(ret);
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
diff --git a/dlls/shell32/tests/Makefile.in b/dlls/shell32/tests/Makefile.in
index b53507d..c6087c2 100644
--- a/dlls/shell32/tests/Makefile.in
+++ b/dlls/shell32/tests/Makefile.in
@@ -16,6 +16,7 @@ C_SRCS = \
 	shlexec.c \
 	shlfileop.c \
 	shlfolder.c \
+	shlview.c \
 	string.c \
 	systray.c
 
diff --git a/dlls/shell32/tests/msg.h b/dlls/shell32/tests/msg.h
new file mode 100644
index 0000000..361ccdb
--- /dev/null
+++ b/dlls/shell32/tests/msg.h
@@ -0,0 +1,294 @@
+/* Message Sequence Testing Code
+ *
+ * Copyright (C) 2007 James Hawkins
+ * Copyright (C) 2007 Lei Zhang
+ *
+ * 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 <assert.h>
+#include <windows.h>
+#include "wine/test.h"
+
+/* undocumented SWP flags - from SDK 3.1 */
+#define SWP_NOCLIENTSIZE	0x0800
+#define SWP_NOCLIENTMOVE	0x1000
+
+typedef enum
+{
+    sent = 0x1,
+    posted = 0x2,
+    parent = 0x4,
+    wparam = 0x8,
+    lparam = 0x10,
+    defwinproc = 0x20,
+    beginpaint = 0x40,
+    optional = 0x80,
+    hook = 0x100,
+    winevent_hook =0x200,
+    id = 0x400
+} msg_flags_t;
+
+struct message
+{
+    UINT message;       /* the WM_* code */
+    msg_flags_t flags;  /* message props */
+    WPARAM wParam;      /* expected value of wParam */
+    LPARAM lParam;      /* expected value of lParam */
+    UINT id;            /* extra message data: id of the window,
+                           notify code etc. */
+};
+
+struct msg_sequence
+{
+    int count;
+    int size;
+    struct message *sequence;
+};
+
+static void add_message(struct msg_sequence **seq, int sequence_index,
+    const struct message *msg)
+{
+    struct msg_sequence *msg_seq = seq[sequence_index];
+
+    if (!msg_seq->sequence)
+    {
+        msg_seq->size = 10;
+        msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0,
+                                      msg_seq->size * sizeof (struct message));
+    }
+
+    if (msg_seq->count == msg_seq->size)
+    {
+        msg_seq->size *= 2;
+        msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0,
+                                        msg_seq->sequence,
+                                        msg_seq->size * sizeof (struct message));
+    }
+
+    assert(msg_seq->sequence);
+
+    msg_seq->sequence[msg_seq->count].message = msg->message;
+    msg_seq->sequence[msg_seq->count].flags = msg->flags;
+    msg_seq->sequence[msg_seq->count].wParam = msg->wParam;
+    msg_seq->sequence[msg_seq->count].lParam = msg->lParam;
+    msg_seq->sequence[msg_seq->count].id = msg->id;
+
+    msg_seq->count++;
+}
+
+static void flush_sequence(struct msg_sequence **seg, int sequence_index)
+{
+    struct msg_sequence *msg_seq = seg[sequence_index];
+    HeapFree(GetProcessHeap(), 0, msg_seq->sequence);
+    msg_seq->sequence = NULL;
+    msg_seq->count = msg_seq->size = 0;
+}
+
+static void flush_sequences(struct msg_sequence **seq, int n)
+{
+    int i;
+
+    for (i = 0; i < n; i++)
+        flush_sequence(seq, i);
+}
+
+static void ok_sequence_(struct msg_sequence **seq, int sequence_index,
+    const struct message *expected, const char *context, int todo,
+    const char *file, int line)
+{
+    struct msg_sequence *msg_seq = seq[sequence_index];
+    static const struct message end_of_sequence = {0, 0, 0, 0};
+    const struct message *actual, *sequence;
+    int failcount = 0;
+
+    add_message(seq, sequence_index, &end_of_sequence);
+
+    sequence = msg_seq->sequence;
+    actual = sequence;
+
+    while (expected->message && actual->message)
+    {
+        trace_( file, line)("expected %04x - actual %04x\n", expected->message, actual->message);
+
+        if (expected->message == actual->message)
+        {
+            if (expected->flags & wparam)
+            {
+                if (expected->wParam != actual->wParam && todo)
+                {
+                    todo_wine
+                    {
+                        failcount++;
+                        ok_(file, line) (FALSE,
+                            "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
+                            context, expected->message, expected->wParam, actual->wParam);
+                    }
+                }
+                else
+                {
+                    ok_(file, line) (expected->wParam == actual->wParam,
+                        "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
+                        context, expected->message, expected->wParam, actual->wParam);
+                }
+            }
+
+            if (expected->flags & lparam)
+            {
+                if (expected->lParam != actual->lParam && todo)
+                {
+                    todo_wine
+                    {
+                        failcount++;
+                        ok_(file, line) (FALSE,
+                            "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
+                            context, expected->message, expected->lParam, actual->lParam);
+                    }
+                }
+                else
+                {
+                    ok_(file, line) (expected->lParam == actual->lParam,
+                        "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
+                        context, expected->message, expected->lParam, actual->lParam);
+                }
+            }
+
+            if (expected->flags & id)
+            {
+                if (expected->id != actual->id && expected->flags & optional)
+                {
+                    expected++;
+                    continue;
+                }
+                if (expected->id != actual->id && todo)
+                {
+                    todo_wine
+                    {
+                        failcount++;
+                        ok_(file, line) (FALSE,
+                            "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
+                            context, expected->message, expected->id, actual->id);
+                    }
+                }
+                else
+                {
+                    ok_(file, line) (expected->id == actual->id,
+                        "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
+                        context, expected->message, expected->id, actual->id);
+                }
+            }
+
+            if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo)
+            {
+                todo_wine
+                {
+                    failcount++;
+                    ok_(file, line) (FALSE,
+                        "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
+                        context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
+                }
+            }
+            else
+            {
+                ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc),
+                    "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
+                    context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
+            }
+
+            ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint),
+                "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
+                context, expected->message, (expected->flags & beginpaint) ? "" : "NOT ");
+            ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
+                "%s: the msg 0x%04x should have been %s\n",
+                context, expected->message, (expected->flags & posted) ? "posted" : "sent");
+            ok_(file, line) ((expected->flags & parent) == (actual->flags & parent),
+                "%s: the msg 0x%04x was expected in %s\n",
+                context, expected->message, (expected->flags & parent) ? "parent" : "child");
+            ok_(file, line) ((expected->flags & hook) == (actual->flags & hook),
+                "%s: the msg 0x%04x should have been sent by a hook\n",
+                context, expected->message);
+            ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook),
+                "%s: the msg 0x%04x should have been sent by a winevent hook\n",
+                context, expected->message);
+            expected++;
+            actual++;
+        }
+        else if (expected->flags & optional)
+            expected++;
+        else if (todo)
+        {
+            failcount++;
+            todo_wine
+            {
+                ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
+                    context, expected->message, actual->message);
+            }
+
+            flush_sequence(seq, sequence_index);
+            return;
+        }
+        else
+        {
+            ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
+                context, expected->message, actual->message);
+            expected++;
+            actual++;
+        }
+    }
+
+    /* skip all optional trailing messages */
+    while (expected->message && ((expected->flags & optional)))
+        expected++;
+
+    if (todo)
+    {
+        todo_wine
+        {
+            if (expected->message || actual->message)
+            {
+                failcount++;
+                ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
+                    context, expected->message, actual->message);
+            }
+        }
+    }
+    else if (expected->message || actual->message)
+    {
+        ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
+            context, expected->message, actual->message);
+    }
+
+    if(todo && !failcount) /* succeeded yet marked todo */
+    {
+        todo_wine
+        {
+            ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
+        }
+    }
+
+    flush_sequence(seq, sequence_index);
+}
+
+#define ok_sequence(seq, index, exp, contx, todo) \
+        ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
+
+
+static void init_msg_sequences(struct msg_sequence **seq, int n)
+{
+    int i;
+
+    for (i = 0; i < n; i++)
+        seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence));
+}
diff --git a/dlls/shell32/tests/shlview.c b/dlls/shell32/tests/shlview.c
new file mode 100644
index 0000000..a14c691
--- /dev/null
+++ b/dlls/shell32/tests/shlview.c
@@ -0,0 +1,433 @@
+/*
+ * Unit test of the IShellView
+ *
+ * Copyright 2010 Nikolay Sivov for CodeWeavers
+ *
+ * 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 <stdarg.h>
+#include <stdio.h>
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include "windef.h"
+#include "winbase.h"
+#include "wtypes.h"
+#include "shellapi.h"
+
+#include "shlguid.h"
+#include "shlobj.h"
+#include "shobjidl.h"
+#include "shlwapi.h"
+#include "ocidl.h"
+#include "oleauto.h"
+
+#include "wine/test.h"
+
+#include "msg.h"
+
+#define LISTVIEW_SEQ_INDEX  0
+#define NUM_MSG_SEQUENCES   1
+
+static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
+
+static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
+    static LONG defwndproc_counter = 0;
+    LRESULT ret;
+    struct message msg;
+
+    trace("listview: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
+
+    msg.message = message;
+    msg.flags = sent|wparam|lparam;
+    if (defwndproc_counter) msg.flags |= defwinproc;
+    msg.wParam = wParam;
+    msg.lParam = lParam;
+    add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
+
+    defwndproc_counter++;
+    ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
+    defwndproc_counter--;
+    return ret;
+}
+
+static HWND subclass_listview(HWND hwnd)
+{
+    WNDPROC oldproc;
+    HWND listview;
+
+    /* listview is a first child */
+    listview = FindWindowExA(hwnd, NULL, WC_LISTVIEWA, NULL);
+
+    oldproc = (WNDPROC)SetWindowLongPtrA(listview, GWLP_WNDPROC,
+                                        (LONG_PTR)listview_subclass_proc);
+    SetWindowLongPtrA(listview, GWLP_USERDATA, (LONG_PTR)oldproc);
+
+    return listview;
+}
+
+typedef struct {
+
+    const IShellBrowserVtbl *lpVtbl;
+    LONG ref;
+} IShellBrowserImpl;
+
+/* dummy IShellBrowser implementation */
+static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
+
+IShellBrowser* IShellBrowserImpl_Construct(void)
+{
+    IShellBrowserImpl *browser;
+
+    browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
+    browser->lpVtbl = &IShellBrowserImpl_Vtbl;
+    browser->ref = 1;
+
+    return (IShellBrowser*)browser;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
+                                            REFIID riid,
+                                            LPVOID *ppvObj)
+{
+    IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
+
+    *ppvObj = NULL;
+
+    if(IsEqualIID(riid, &IID_IUnknown))
+    {
+        *ppvObj = This;
+    }
+    else if(IsEqualIID(riid, &IID_IOleWindow))
+    {
+        *ppvObj = This;
+    }
+    else if(IsEqualIID(riid, &IID_IShellBrowser))
+    {
+        *ppvObj = This;
+    }
+
+    if(*ppvObj)
+    {
+        IUnknown_AddRef( (IShellBrowser*) *ppvObj);
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
+{
+    IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
+{
+    IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    if (!ref)
+    {
+        HeapFree(GetProcessHeap(), 0, This);
+        return 0;
+    }
+    return ref;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser *iface,
+                                           HWND *phwnd)
+{
+    if (phwnd) *phwnd = GetDesktopWindow();
+    return S_OK;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser *iface,
+                                                      BOOL fEnterMode)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
+                                              LPCITEMIDLIST pidl,
+                                              UINT wFlags)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
+                                              BOOL fEnable)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
+                                              UINT id,
+                                              HWND *lphwnd)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
+                                                DWORD mode,
+                                                LPSTREAM *pStrm)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
+                                           HMENU hmenuShared,
+                                           LPOLEMENUGROUPWIDTHS lpMenuWidths)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
+                                                IShellView *ppshv)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
+                                                  IShellView **ppshv)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
+                                           HMENU hmenuShared)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
+                                            UINT id,
+                                            UINT uMsg,
+                                            WPARAM wParam,
+                                            LPARAM lParam,
+                                            LRESULT *pret)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
+                                       HMENU hmenuShared,
+                                       HOLEMENU holemenuReserved,
+                                       HWND hwndActiveObject)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
+                                             LPCOLESTR lpszStatusText)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
+                                             LPTBBUTTON lpButtons,
+                                             UINT nButtons,
+                                             UINT uFlags)
+
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
+                                                    LPMSG lpmsg,
+                                                    WORD wID)
+
+{
+    return E_NOTIMPL;
+}
+
+static const IShellBrowserVtbl IShellBrowserImpl_Vtbl =
+{
+    IShellBrowserImpl_QueryInterface,
+    IShellBrowserImpl_AddRef,
+    IShellBrowserImpl_Release,
+    IShellBrowserImpl_GetWindow,
+    IShellBrowserImpl_ContextSensitiveHelp,
+    IShellBrowserImpl_InsertMenusSB,
+    IShellBrowserImpl_SetMenuSB,
+    IShellBrowserImpl_RemoveMenusSB,
+    IShellBrowserImpl_SetStatusTextSB,
+    IShellBrowserImpl_EnableModelessSB,
+    IShellBrowserImpl_TranslateAcceleratorSB,
+    IShellBrowserImpl_BrowseObject,
+    IShellBrowserImpl_GetViewStateStream,
+    IShellBrowserImpl_GetControlWindow,
+    IShellBrowserImpl_SendControlMsg,
+    IShellBrowserImpl_QueryActiveShellView,
+    IShellBrowserImpl_OnViewWindowActive,
+    IShellBrowserImpl_SetToolbarItems
+};
+
+static const struct message empty_seq[] = {
+    { 0 }
+};
+
+static const struct message folderview_getspacing_seq[] = {
+    { LVM_GETITEMSPACING, wparam|sent, FALSE },
+    { 0 }
+};
+
+static void test_IShellView_CreateViewWindow(void)
+{
+    IShellFolder *desktop;
+    FOLDERSETTINGS settings;
+    IShellView *view;
+    HWND hwnd_view;
+    HRESULT hr;
+    RECT r = {0};
+
+    hr = SHGetDesktopFolder(&desktop);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+if (0)
+{
+    /* crashes on native */
+    hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
+}
+
+    settings.ViewMode = FVM_ICON;
+    settings.fFlags = 0;
+    hwnd_view = (HWND)0xdeadbeef;
+    hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, &hwnd_view);
+    ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
+    ok(hwnd_view == 0, "got %p\n", hwnd_view);
+
+    hwnd_view = (HWND)0xdeadbeef;
+    hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, &r, &hwnd_view);
+    ok(hr == E_UNEXPECTED, "got (0x%08x)\n", hr);
+    ok(hwnd_view == 0, "got %p\n", hwnd_view);
+
+    IShellView_Release(view);
+    IShellFolder_Release(desktop);
+}
+
+static void test_IFolderView(void)
+{
+    IShellFolder *desktop;
+    FOLDERSETTINGS settings;
+    IShellView *view;
+    IShellBrowser *browser;
+    IFolderView *fv;
+    HWND hwnd_view, hwnd_list;
+    HRESULT hr;
+    DWORD ret;
+    POINT pt;
+    RECT r;
+
+    hr = SHGetDesktopFolder(&desktop);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    hr = IShellView_QueryInterface(view, &IID_IFolderView, (void**)&fv);
+    if (hr != S_OK)
+    {
+        win_skip("IFolderView not supported by desktop folder\n");
+        IShellView_Release(view);
+        IShellFolder_Release(desktop);
+        return;
+    }
+
+    /* call methods before window creation */
+    hr = IFolderView_GetSpacing(fv, NULL);
+    ok(hr == S_FALSE || broken(hr == S_OK) /* win7 */, "got (0x%08x)\n", hr);
+
+if (0)
+{
+    /* crashes on Vista and Win2k8 - List not created yet case */
+    hr = IFolderView_GetSpacing(fv, &pt);
+}
+
+    browser = IShellBrowserImpl_Construct();
+
+    settings.ViewMode = FVM_ICON;
+    settings.fFlags = 0;
+    hwnd_view = (HWND)0xdeadbeef;
+    r.left = r.top = 0;
+    r.right = r.bottom = 100;
+    hr = IShellView_CreateViewWindow(view, NULL, &settings, browser, &r, &hwnd_view);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+    ok(IsWindow(hwnd_view), "got %p\n", hwnd_view);
+
+    hwnd_list = subclass_listview(hwnd_view);
+    if (!hwnd_list)
+    {
+        win_skip("Failed to subclass ListView control\n");
+        IShellBrowser_Release(browser);
+        IFolderView_Release(fv);
+        IShellView_Release(view);
+        IShellFolder_Release(desktop);
+        return;
+    }
+
+    /* IFolderView::GetSpacing */
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+    hr = IFolderView_GetSpacing(fv, NULL);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+    ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq, "IFolderView::GetSpacing, empty", FALSE);
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+    hr = IFolderView_GetSpacing(fv, &pt);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+    /* fails with empty sequence on win7 for unknown reason */
+    if (sequences[LISTVIEW_SEQ_INDEX]->count)
+    {
+        ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getspacing_seq, "IFolderView::GetSpacing", FALSE);
+        ok(pt.x > 0, "got %d\n", pt.x);
+        ok(pt.y > 0, "got %d\n", pt.y);
+        ret = SendMessageA(hwnd_list, LVM_GETITEMSPACING, 0, 0);
+        ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret));
+    }
+
+    IShellBrowser_Release(browser);
+    IFolderView_Release(fv);
+    IShellView_Release(view);
+    IShellFolder_Release(desktop);
+}
+
+START_TEST(shlview)
+{
+    OleInitialize(NULL);
+
+    init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
+
+    test_IShellView_CreateViewWindow();
+    test_IFolderView();
+
+    OleUninitialize();
+}
-- 
1.5.6.5


--=-ywLAHTFGLWBh4grrucWb--




More information about the wine-patches mailing list