https://git.reactos.org/?p=reactos.git;a=commitdiff;h=96c0f7d341f9d0ba0ab54…
commit 96c0f7d341f9d0ba0ab543e0772ba1d6c303a8c0
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Wed Dec 20 22:32:06 2017 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Fri Mar 30 19:46:24 2018 +0200
Add initial test for IShellFolderViewCB
---
modules/rostests/apitests/shell32/CMakeLists.txt | 1 +
.../apitests/shell32/IShellFolderViewCB.cpp | 622 +++++++++++++++++++++
modules/rostests/apitests/shell32/testlist.c | 2 +
3 files changed, 625 insertions(+)
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt
b/modules/rostests/apitests/shell32/CMakeLists.txt
index e2c5e0c663..7526df1bad 100644
--- a/modules/rostests/apitests/shell32/CMakeLists.txt
+++ b/modules/rostests/apitests/shell32/CMakeLists.txt
@@ -13,6 +13,7 @@ list(APPEND SOURCE
CShellDesktop.cpp
CShellLink.cpp
CUserNotification.cpp
+ IShellFolderViewCB.cpp
menu.cpp
PathResolve.cpp
SHCreateFileExtractIconW.cpp
diff --git a/modules/rostests/apitests/shell32/IShellFolderViewCB.cpp
b/modules/rostests/apitests/shell32/IShellFolderViewCB.cpp
new file mode 100644
index 0000000000..a1fd664fe6
--- /dev/null
+++ b/modules/rostests/apitests/shell32/IShellFolderViewCB.cpp
@@ -0,0 +1,622 @@
+/*
+ * PROJECT: ReactOS API tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Test for IShellFolderViewCB
+ * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen(a)reactos.org)
+ */
+
+#include "shelltest.h"
+#include <atlsimpcoll.h>
+#include <stdio.h>
+
+#if 1
+#define DbgPrint(...) trace(__VA_ARGS__)
+#else
+EXTERN_C
+void DbgPrint(PCSTR, ...);
+#endif
+#include <shellutils.h>
+//#include <msgtrace.h>
+
+static DWORD g_WinVersion;
+#define WINVER_VISTA 0x0600
+
+#ifndef SFVM_SELECTIONCHANGED
+#define SFVM_SELECTIONCHANGED 8 /* undocumented */
+#define SFVM_DRAWMENUITEM 9 /* undocumented */
+#define SFVM_MEASUREMENUITEM 10 /* undocumented */
+#define SFVM_EXITMENULOOP 11 /* undocumented */
+#define SFVM_VIEWRELEASE 12 /* undocumented */
+#define SFVM_GETNAMELENGTH 13 /* undocumented */
+#define SFVM_WINDOWCLOSING 16 /* undocumented */
+#define SFVM_LISTREFRESHED 17 /* undocumented */
+#define SFVM_WINDOWFOCUSED 18 /* undocumented */
+#define SFVM_REGISTERCOPYHOOK 20 /* undocumented */
+#define SFVM_COPYHOOKCALLBACK 21 /* undocumented */
+#define SFVM_UNMERGEFROMMENU 28 /* undocumented */
+#define SFVM_ADDINGOBJECT 29 /* undocumented */
+#define SFVM_REMOVINGOBJECT 30 /* undocumented */
+#define SFVM_GETCOMMANDDIR 33 /* undocumented */
+#define SFVM_GETCOLUMNSTREAM 34 /* undocumented */
+#define SFVM_CANSELECTALL 35 /* undocumented */
+#define SFVM_ISSTRICTREFRESH 37 /* undocumented */
+#define SFVM_ISCHILDOBJECT 38 /* undocumented */
+#define SFVM_GETEXTVIEWS 40 /* undocumented */
+#define SFVM_GET_CUSTOMVIEWINFO 77 /* undocumented */
+#define SFVM_ENUMERATEDITEMS 79 /* undocumented */
+#define SFVM_GET_VIEW_DATA 80 /* undocumented */
+#define SFVM_GET_WEBVIEW_LAYOUT 82 /* undocumented */
+#define SFVM_GET_WEBVIEW_CONTENT 83 /* undocumented */
+#define SFVM_GET_WEBVIEW_TASKS 84 /* undocumented */
+#define SFVM_GET_WEBVIEW_THEME 86 /* undocumented */
+#define SFVM_GETDEFERREDVIEWSETTINGS 92 /* undocumented */
+#endif
+
+#define DUM_MSG_GetWindow 400
+#define DUM_MSG_ContextSensitiveHelp 401
+#define DUM_MSG_InsertMenusSB 402
+#define DUM_MSG_SetMenuSB 403
+#define DUM_MSG_RemoveMenusSB 404
+#define DUM_MSG_SetStatusTextSB 405
+#define DUM_MSG_EnableModelessSB 406
+#define DUM_MSG_TranslateAcceleratorSB 407
+#define DUM_MSG_BrowseObject 408
+#define DUM_MSG_GetViewStateStream 409
+#define DUM_MSG_GetControlWindow 410
+#define DUM_MSG_SendControlMsg 411
+#define DUM_MSG_QueryActiveShellView 412
+#define DUM_MSG_OnViewWindowActive 413
+#define DUM_MSG_SetToolbarItems 414
+
+
+const char* msg2str(UINT uMsg)
+{
+ static char buf[2][50];
+ static int index = 0;
+ index ^= 1;
+
+ switch (uMsg)
+ {
+ case SFVM_MERGEMENU: return "SFVM_MERGEMENU";
+ case SFVM_INVOKECOMMAND: return "SFVM_INVOKECOMMAND";
+ case SFVM_GETHELPTEXT: return "SFVM_GETHELPTEXT";
+ case SFVM_GETTOOLTIPTEXT: return "SFVM_GETTOOLTIPTEXT";
+ case SFVM_GETBUTTONINFO: return "SFVM_GETBUTTONINFO";
+ case SFVM_GETBUTTONS: return "SFVM_GETBUTTONS";
+ case SFVM_INITMENUPOPUP: return "SFVM_INITMENUPOPUP";
+ case SFVM_SELECTIONCHANGED: return "SFVM_SELECTIONCHANGED";
+ case SFVM_DRAWMENUITEM: return "SFVM_DRAWMENUITEM";
+ case SFVM_MEASUREMENUITEM: return "SFVM_MEASUREMENUITEM";
+ case SFVM_EXITMENULOOP: return "SFVM_EXITMENULOOP";
+ case SFVM_VIEWRELEASE: return "SFVM_VIEWRELEASE";
+ case SFVM_GETNAMELENGTH: return "SFVM_GETNAMELENGTH";
+ case SFVM_FSNOTIFY: return "SFVM_FSNOTIFY";
+ case SFVM_WINDOWCREATED: return "SFVM_WINDOWCREATED";
+ case SFVM_WINDOWCLOSING: return "SFVM_WINDOWCLOSING";
+ case SFVM_LISTREFRESHED: return "SFVM_LISTREFRESHED";
+ case SFVM_WINDOWFOCUSED: return "SFVM_WINDOWFOCUSED";
+ case SFVM_REGISTERCOPYHOOK: return "SFVM_REGISTERCOPYHOOK";
+ case SFVM_COPYHOOKCALLBACK: return "SFVM_COPYHOOKCALLBACK";
+ case SFVM_GETDETAILSOF: return "SFVM_GETDETAILSOF";
+ case SFVM_COLUMNCLICK: return "SFVM_COLUMNCLICK";
+ case SFVM_QUERYFSNOTIFY: return "SFVM_QUERYFSNOTIFY";
+ case SFVM_DEFITEMCOUNT: return "SFVM_DEFITEMCOUNT";
+ case SFVM_DEFVIEWMODE: return "SFVM_DEFVIEWMODE";
+ case SFVM_UNMERGEFROMMENU: return "SFVM_UNMERGEFROMMENU";
+ case SFVM_ADDINGOBJECT: return "SFVM_ADDINGOBJECT";
+ case SFVM_REMOVINGOBJECT: return "SFVM_REMOVINGOBJECT";
+ case SFVM_UPDATESTATUSBAR: return "SFVM_UPDATESTATUSBAR";
+ case SFVM_BACKGROUNDENUM: return "SFVM_BACKGROUNDENUM";
+ case SFVM_GETCOMMANDDIR: return "SFVM_GETCOMMANDDIR";
+ case SFVM_GETCOLUMNSTREAM: return "SFVM_GETCOLUMNSTREAM";
+ case SFVM_CANSELECTALL: return "SFVM_CANSELECTALL";
+ case SFVM_DIDDRAGDROP: return "SFVM_DIDDRAGDROP";
+ case SFVM_ISSTRICTREFRESH: return "SFVM_ISSTRICTREFRESH";
+ case SFVM_ISCHILDOBJECT: return "SFVM_ISCHILDOBJECT";
+ case SFVM_SETISFV: return "SFVM_SETISFV";
+ case SFVM_GETEXTVIEWS: return "SFVM_GETEXTVIEWS";
+ case SFVM_THISIDLIST: return "SFVM_THISIDLIST";
+ case SFVM_ADDPROPERTYPAGES: return "SFVM_ADDPROPERTYPAGES";
+ case SFVM_BACKGROUNDENUMDONE: return "SFVM_BACKGROUNDENUMDONE";
+ case SFVM_GETNOTIFY: return "SFVM_GETNOTIFY";
+ case SFVM_GETSORTDEFAULTS: return "SFVM_GETSORTDEFAULTS";
+ case SFVM_SIZE: return "SFVM_SIZE";
+ case SFVM_GETZONE: return "SFVM_GETZONE";
+ case SFVM_GETPANE: return "SFVM_GETPANE";
+ case SFVM_GETHELPTOPIC: return "SFVM_GETHELPTOPIC";
+ case SFVM_GETANIMATION: return "SFVM_GETANIMATION";
+ case SFVM_GET_CUSTOMVIEWINFO: return "SFVM_GET_CUSTOMVIEWINFO";
+ case SFVM_ENUMERATEDITEMS: return "SFVM_ENUMERATEDITEMS";
+ case SFVM_GET_VIEW_DATA: return "SFVM_GET_VIEW_DATA";
+ case SFVM_GET_WEBVIEW_LAYOUT: return "SFVM_GET_WEBVIEW_LAYOUT";
+ case SFVM_GET_WEBVIEW_CONTENT: return "SFVM_GET_WEBVIEW_CONTENT";
+ case SFVM_GET_WEBVIEW_TASKS: return "SFVM_GET_WEBVIEW_TASKS";
+ case SFVM_GET_WEBVIEW_THEME: return "SFVM_GET_WEBVIEW_THEME";
+ case SFVM_GETDEFERREDVIEWSETTINGS: return "SFVM_GET_WEBVIEW_THEME";
+
+ case DUM_MSG_GetWindow: return "|GetWindow|";
+ case DUM_MSG_ContextSensitiveHelp: return "|ContextSensitiveHelp|";
+ case DUM_MSG_InsertMenusSB: return "|InsertMenusSB|";
+ case DUM_MSG_SetMenuSB: return "|SetMenuSB|";
+ case DUM_MSG_RemoveMenusSB: return "|RemoveMenusSB|";
+ case DUM_MSG_SetStatusTextSB: return "|SetStatusTextSB|";
+ case DUM_MSG_EnableModelessSB: return "|EnableModelessSB|";
+ case DUM_MSG_TranslateAcceleratorSB: return "|TranslateAcceleratorSB|";
+ case DUM_MSG_BrowseObject: return "|BrowseObject|";
+ case DUM_MSG_GetViewStateStream: return "|GetViewStateStream|";
+ case DUM_MSG_GetControlWindow: return "|GetControlWindow|";
+ case DUM_MSG_SendControlMsg: return "|SendControlMsg|";
+ case DUM_MSG_QueryActiveShellView: return "|QueryActiveShellView|";
+ case DUM_MSG_OnViewWindowActive: return "|OnViewWindowActive|";
+ case DUM_MSG_SetToolbarItems: return "|SetToolbarItems|";
+ default:
+ sprintf(buf[index], "[%u]", uMsg);
+ return buf[index];
+ }
+}
+
+
+#define PTR_VALUE 0xf7f7f7f7
+
+struct message
+{
+ message(UINT msg, WPARAM wp, LPARAM lp) : uMsg(msg), wParam(wp), lParam(lp) { ; }
+
+ UINT uMsg;
+ WPARAM wParam;
+ LPARAM lParam;
+};
+
+CSimpleArray<message> g_Received;
+
+void clear_list()
+{
+ g_Received.RemoveAll();
+}
+
+void add_msg(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ g_Received.Add(message(uMsg, wParam, lParam));
+}
+
+void print_list_(const CSimpleArray<message>& input, const char* file, int
line)
+{
+ trace_(file, line)("Got list:\n");
+ for (int n = 0; n < input.GetSize(); ++n)
+ {
+ const message& msg = input[n];
+ trace_(file, line)("msg: %d(%s), wParam:0x%x, lParam:0x%lx\n",
msg.uMsg, msg2str(msg.uMsg), msg.wParam, msg.lParam);
+ }
+ trace_(file, line)("End of list.\n");
+}
+
+void compare_list_(const CSimpleArray<message>& input, const message* compare,
const char* file, int line)
+{
+ int input_item = 0;
+ int compare_item = 0;
+ LONG old_failures = winetest_get_failures();
+ while (compare[compare_item].uMsg && input_item < input.GetSize())
+ {
+ const message& inp = input[input_item];
+ const message& cmp = compare[compare_item];
+ if (cmp.uMsg == inp.uMsg)
+ {
+ if (cmp.lParam != (LPARAM)PTR_VALUE)
+ {
+ ok_(file, line)(cmp.lParam == inp.lParam, "Expected lParam to be
0x%lx, was 0x%lx for %i(%s)\n",
+ cmp.lParam, inp.lParam, compare_item,
msg2str(cmp.uMsg));
+ }
+ else
+ {
+ ok_(file, line)(inp.lParam != 0, "Expected lParam to be a pointer,
was 0 for %i(%s)\n",
+ compare_item, msg2str(cmp.uMsg));
+ }
+ if (cmp.wParam != PTR_VALUE)
+ {
+ ok_(file, line)(cmp.wParam == inp.wParam, "Expected wParam to be
0x%x, was 0x%x for %i(%s)\n",
+ cmp.wParam, inp.wParam, compare_item,
msg2str(cmp.uMsg));
+ }
+ else
+ {
+ ok_(file, line)(inp.wParam != 0, "Expected wParam to be a pointer,
was 0 for %i(%s)\n",
+ compare_item, msg2str(cmp.uMsg));
+ }
+ compare_item++;
+ }
+ else
+ {
+ /* We skip unknown items for now */
+ }
+
+ input_item++;
+ }
+
+ while (compare[compare_item].uMsg)
+ {
+ ok_(file, line)(0, "Message %i(%s) not found\n", compare_item,
msg2str(compare[compare_item].uMsg));
+ compare_item++;
+ }
+ if (old_failures != winetest_get_failures())
+ {
+ print_list_(input, file, line);
+ }
+}
+
+#define compare_list(cmp) compare_list_(g_Received, cmp, __FILE__, __LINE__)
+#define print_list() print_list_(g_Received, __FILE__, __LINE__)
+
+
+LONG g_AddRef = 0;
+LONG g_Release = 0;
+
+class CFolderViewCB :
+ public IShellFolderViewCB
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
+ {
+ if (riid == IID_IShellFolderViewCB || riid == IID_IUnknown)
+ {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ {
+ InterlockedIncrement(&g_AddRef);
+ return 2;
+ }
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ InterlockedIncrement(&g_Release);
+ return 1;
+ }
+ virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM
lParam)
+ {
+ //DbgPrint("MessageSFVCB(uMsg:%s, wParam:%u, lParam:%u\n",
msg2str(uMsg), wParam, lParam);
+ add_msg(uMsg, wParam, lParam);
+ return E_NOTIMPL;
+ }
+};
+
+
+static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_DESTROY)
+ {
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+
+class CDummyShellBrowser : public IShellBrowser
+{
+public:
+ HWND m_hwnd;
+ CDummyShellBrowser()
+ {
+ static const TCHAR* class_name = TEXT("DUMMY_TEST_CLASS");
+ WNDCLASSEX wx = {};
+ wx.cbSize = sizeof(WNDCLASSEX);
+ wx.lpfnWndProc = WndProc;
+ wx.hInstance = GetModuleHandle(NULL);
+ wx.lpszClassName = class_name;
+ wx.style = CS_DBLCLKS;
+ RegisterClassEx(&wx);
+ m_hwnd = CreateWindowEx(0, class_name, TEXT("dummy_name"),
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
+ ShowWindow(m_hwnd, SW_SHOW);
+ }
+
+ // *** IUnknown methods ***
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
+ {
+ if (riid == IID_IShellBrowser || riid == IID_IUnknown)
+ {
+ *ppvObject = this;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ {
+ return 2;
+ }
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ return 1;
+ }
+
+ // *** IOleWindow methods ***
+ virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ *phwnd = m_hwnd;
+ add_msg(DUM_MSG_GetWindow, NULL, NULL);
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_ContextSensitiveHelp, NULL, NULL);
+ return E_NOTIMPL;
+ }
+
+ // *** IShellBrowser methods ***
+ virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared,
LPOLEMENUGROUPWIDTHS lpMenuWidths)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_InsertMenusSB, NULL, NULL);
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes,
HWND hwndActiveObject)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_SetMenuSB, NULL, NULL);
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_RemoveMenusSB, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCWSTR pszStatusText)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_SetStatusTextSB, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_EnableModelessSB, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_TranslateAcceleratorSB, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE BrowseObject(PCUIDLIST_RELATIVE pidl,UINT wFlags)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_BrowseObject, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode,IStream **ppStrm)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_GetViewStateStream, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id,HWND *phwnd)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_GetControlWindow, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id,UINT uMsg,WPARAM
wParam,LPARAM lParam,LRESULT *pret)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_SendControlMsg, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView **ppshv)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_QueryActiveShellView, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(IShellView *pshv)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_OnViewWindowActive, NULL, NULL);
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTONSB lpButtons,UINT
nButtons,UINT uFlags)
+ {
+ //DbgPrint("%s()\n", __FUNCTION__);
+ add_msg(DUM_MSG_SetToolbarItems, NULL, NULL);
+ return E_NOTIMPL;
+ }
+};
+
+
+START_TEST(IShellFolderViewCB)
+{
+ RTL_OSVERSIONINFOEXW rtlinfo = { sizeof(rtlinfo) };
+ void (__stdcall* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
+ pRtlGetVersion = (void
(__stdcall*)(RTL_OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleA("ntdll"),
"RtlGetVersion");
+ pRtlGetVersion(&rtlinfo);
+ g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
+
+ CoInitialize(NULL);
+ CFolderViewCB cb;
+
+ CComPtr<IShellFolder> desktop;
+
+ HRESULT hr = SHGetDesktopFolder(&desktop);
+ ok_hex(hr, S_OK);
+ if (!desktop)
+ return;
+
+ SFV_CREATE sfvc = { sizeof(sfvc), desktop };
+ sfvc.psfvcb = &cb;
+ IShellView* psv = NULL;
+
+ g_AddRef = 0;
+ g_Release = 0;
+
+ hr = SHCreateShellFolderView(&sfvc, &psv);
+ ok_hex(hr, S_OK);
+ if (!SUCCEEDED(hr))
+ return;
+
+ ok_int(g_AddRef, 2);
+ ok_int(g_Release, 0);
+
+ clear_list();
+
+ HWND wnd;
+ RECT rc = { 0 };
+ FOLDERSETTINGS fs = { FVM_DETAILS, 0 };
+ CDummyShellBrowser dum;
+ hr = psv->CreateViewWindow(NULL, &fs, &dum, &rc, &wnd);
+
+
+ static message init_list[] =
+ {
+ /* ... */
+ message(DUM_MSG_GetWindow, 0, 0),
+ /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME +
SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */
+ message(SFVM_SIZE, 0, 0),
+ /* ... */
+ message(DUM_MSG_InsertMenusSB, 0, 0),
+ message(SFVM_MERGEMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ /* ... */
+ message(SFVM_WINDOWCREATED, PTR_VALUE, 0),
+ /* ... */
+
+ message(SFVM_GETBUTTONINFO, 0, PTR_VALUE),
+ message(SFVM_GETBUTTONS, PTR_VALUE, PTR_VALUE),
+ message(DUM_MSG_SetToolbarItems, 0, 0),
+
+ message(0, 0, 0)
+ };
+
+
+ static message init_list_vista[] =
+ {
+ /* Some unknown messages here */
+ message(DUM_MSG_GetWindow, 0, 0),
+ /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME +
SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */
+ message(SFVM_SIZE, 0, 0),
+ message(SFVM_WINDOWCREATED, PTR_VALUE, 0),
+ /* Some unknown messages here */
+ message(DUM_MSG_InsertMenusSB, 0, 0),
+ message(SFVM_MERGEMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+
+ message(0, 0, 0)
+ };
+
+ if (g_WinVersion < WINVER_VISTA)
+ {
+ compare_list(init_list);
+ }
+ else
+ {
+ compare_list(init_list_vista);
+ }
+ clear_list();
+
+ hr = psv->Refresh();
+ //ok_hex(hr, S_FALSE);
+
+ static message refresh_list[] =
+ {
+ message(SFVM_LISTREFRESHED, 1, 0),
+
+ message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ message(DUM_MSG_RemoveMenusSB, 0, 0),
+ message(DUM_MSG_InsertMenusSB, 0, 0),
+ message(SFVM_MERGEMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+
+ message(0, 0, 0)
+ };
+
+ static message refresh_list_vista[] =
+ {
+ message(SFVM_LISTREFRESHED, 1, 0),
+
+ message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ message(DUM_MSG_RemoveMenusSB, 0, 0),
+ message(DUM_MSG_InsertMenusSB, 0, 0),
+ message(SFVM_MERGEMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ /* Some messages here, like SFVM_GET_WEBVIEW_THEME, SFVM_GETSORTDEFAULTS,
SFVM_GETCOLUMNSTREAM */
+ message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ message(DUM_MSG_RemoveMenusSB, 0, 0),
+ message(DUM_MSG_InsertMenusSB, 0, 0),
+ message(SFVM_MERGEMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+
+ message(0, 0, 0)
+ };
+
+ if (g_WinVersion < WINVER_VISTA)
+ {
+ compare_list(refresh_list);
+ }
+ else
+ {
+ compare_list(refresh_list_vista);
+ }
+ clear_list();
+
+ hr = psv->DestroyViewWindow();
+
+ static message destroy_list[] =
+ {
+ message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
+ message(DUM_MSG_SetMenuSB, 0, 0),
+ message(DUM_MSG_RemoveMenusSB, 0, 0),
+ message(SFVM_WINDOWCLOSING, PTR_VALUE, 0),
+
+ message(0, 0, 0)
+ };
+
+ compare_list(destroy_list);
+ clear_list();
+
+ CComPtr<IShellFolderView> folderView;
+ hr = psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &folderView));
+ ok_hex(hr, S_OK);
+ if (SUCCEEDED(hr))
+ {
+ IShellFolderViewCB* oldPtr;
+
+ g_AddRef = 0;
+ g_Release = 0;
+
+ hr = folderView->SetCallback(NULL, &oldPtr);
+ ok_int(g_AddRef, 0);
+ ok_int(g_Release, 0);
+
+ g_AddRef = 0;
+ g_Release = 0;
+
+ /* Last pointer is not optional! */
+ IShellFolderViewCB* oldPtr2;
+ hr = folderView->SetCallback(oldPtr, &oldPtr2);
+ ok_int(g_AddRef, 1);
+ ok_int(g_Release, 0);
+ }
+
+
+ ULONG refCount = psv->Release();
+ ok(refCount == 0, "refCount = %lu\n", refCount);
+
+ static message release_list[] =
+ {
+ message(SFVM_VIEWRELEASE, 0, 0),
+
+ message(0, 0, 0)
+ };
+
+ /* Investigate why this fails */
+ if (refCount == 0)
+ {
+ compare_list(release_list);
+ }
+}
diff --git a/modules/rostests/apitests/shell32/testlist.c
b/modules/rostests/apitests/shell32/testlist.c
index 792bf49503..7db323ad99 100644
--- a/modules/rostests/apitests/shell32/testlist.c
+++ b/modules/rostests/apitests/shell32/testlist.c
@@ -10,6 +10,7 @@ extern void func_CMyComputer(void);
extern void func_CShellDesktop(void);
extern void func_CShellLink(void);
extern void func_CUserNotification(void);
+extern void func_IShellFolderViewCB(void);
extern void func_menu(void);
extern void func_PathResolve(void);
extern void func_SHCreateFileExtractIconW(void);
@@ -25,6 +26,7 @@ const struct test winetest_testlist[] =
{ "CShellDesktop", func_CShellDesktop },
{ "CShellLink", func_CShellLink },
{ "CUserNotification", func_CUserNotification },
+ { "IShellFolderViewCB", func_IShellFolderViewCB },
{ "menu", func_menu },
{ "PathResolve", func_PathResolve },
{ "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW },