[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