shell32: Implement Set/GetCurrentViewMode in the default shellview.

David Hedberg david.hedberg at gmail.com
Sat Jul 17 10:08:19 CDT 2010


---
 dlls/shell32/shlview.c       |   61 +++++++++++++++++++++++++-------
 dlls/shell32/tests/shlview.c |   81 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+), 13 deletions(-)

diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index 01fee47..082255f 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -683,9 +683,9 @@ static HRESULT ShellView_FillList(IShellViewImpl *This)
 }
 
 /**********************************************************
-*  ShellView_OnCreate()
+*  ShellView_CreateView()
 */
-static LRESULT ShellView_OnCreate(IShellViewImpl *This)
+static LRESULT ShellView_CreateView(IShellViewImpl *This)
 {
     IShellView2 *iface = (IShellView2*)This;
     static const WCHAR accel_nameW[] = {'s','h','v','_','a','c','c','e','l',0};
@@ -731,6 +731,19 @@ static LRESULT ShellView_OnCreate(IShellViewImpl *This)
 }
 
 /**********************************************************
+*  ShellView_DestroyView()
+*/
+static void ShellView_DestroyView(IShellViewImpl *This)
+{
+    RevokeDragDrop(This->hWnd);
+    SHChangeNotifyDeregister(This->hNotify);
+
+    /* Since we might be called by SetCurrentView, we need to
+     * explicitly destroy the current ListView. */
+    DestroyWindow(This->hWndList);
+}
+
+/**********************************************************
  *	#### Handling of the menus ####
  */
 
@@ -1668,7 +1681,7 @@ static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wPara
 	  case WM_SIZE:		return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
 	  case WM_SETFOCUS:	return ShellView_OnSetFocus(pThis);
 	  case WM_KILLFOCUS:	return ShellView_OnKillFocus(pThis);
-	  case WM_CREATE:	return ShellView_OnCreate(pThis);
+	  case WM_CREATE:	return ShellView_CreateView(pThis);
 	  case WM_ACTIVATE:	return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
 	  case WM_NOTIFY:	return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
 	  case WM_COMMAND:      return ShellView_OnCommand(pThis,
@@ -1685,10 +1698,8 @@ static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wPara
 
 	  case WM_GETDLGCODE:   return SendMessageW(pThis->hWndList, uMessage, 0, 0);
 
-	  case WM_DESTROY:	
-	  			RevokeDragDrop(pThis->hWnd);
-				SHChangeNotifyDeregister(pThis->hNotify);
-	                        break;
+	  case WM_DESTROY:	ShellView_DestroyView(pThis);
+				break;
 
 	  case WM_ERASEBKGND:
 	    if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
@@ -2732,16 +2743,40 @@ static ULONG WINAPI IFView_Release( IFolderView *iface)
 
 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
 {
-	IShellViewImpl *This = impl_from_IFolderView(iface);
-	FIXME("(%p)->(%p), stub\n", This, mode);
-	return E_NOTIMPL;
+        IShellViewImpl *This = impl_from_IFolderView(iface);
+        TRACE("(%p)->(%p), stub\n", This, mode);
+
+        if(!mode)
+            return E_INVALIDARG;
+
+        *mode = This->FolderSettings.ViewMode;
+        return S_OK;
 }
 
 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
 {
-	IShellViewImpl *This = impl_from_IFolderView(iface);
-	FIXME("(%p)->(%u), stub\n", This, mode);
-	return E_NOTIMPL;
+        IShellViewImpl *This = impl_from_IFolderView(iface);
+        RECT rc;
+        TRACE("(%p)->(%u), stub\n", This, mode);
+
+        if((mode < FVM_FIRST || mode > FVM_LAST) &&
+           (mode != FVM_AUTO))
+            return E_INVALIDARG;
+
+        /* Destroy the previous listview */
+        ShellView_DestroyView(This);
+
+        /* Change the viewmode */
+        This->FolderSettings.ViewMode = mode;
+
+        /* Create a new listview */
+        ShellView_CreateView(This);
+
+        /* Size the new listview properly. */
+        GetClientRect(This->hWnd, &rc);
+        MoveWindow(This->hWndList, 0, 0, rc.right, rc.bottom, TRUE);
+
+        return S_OK;
 }
 
 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
diff --git a/dlls/shell32/tests/shlview.c b/dlls/shell32/tests/shlview.c
index e3e0ef2..d4c2c34 100644
--- a/dlls/shell32/tests/shlview.c
+++ b/dlls/shell32/tests/shlview.c
@@ -743,6 +743,86 @@ static void test_IOleWindow(void)
     IShellFolder_Release(desktop);
 }
 
+static void test_GetSetCurrentViewMode(void)
+{
+    IShellFolder *desktop;
+    IShellView *sview;
+    IFolderView *fview;
+    IShellBrowser *browser;
+    FOLDERSETTINGS fs;
+    UINT viewmode;
+    HWND hwnd;
+    RECT rc = {0, 0, 10, 10};
+    HRESULT hr;
+    UINT i;
+    static const int winxp_res[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    static const int win2k3_res[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0};
+    static const int vista_res[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0};
+    static const int win7_res[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8};
+
+    hr = SHGetDesktopFolder(&desktop);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&sview);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    fs.ViewMode = 1;
+    fs.fFlags = 0;
+    browser = IShellBrowserImpl_Construct();
+    hr = IShellView_CreateViewWindow(sview, NULL, &fs, browser, &rc, &hwnd);
+    ok(hr == S_OK || broken(hr == S_FALSE /*Win2k*/ ), "got (0x%08x)\n", hr);
+
+    hr = IShellView_QueryInterface(sview, &IID_IFolderView, (void**)&fview);
+    ok(hr == S_OK || broken(hr == E_NOINTERFACE), "got (0x%08x)\n", hr);
+    if(SUCCEEDED(hr))
+    {
+        if(0)
+        {
+            /* Crashes under Win7/WinXP */
+            hr = IFolderView_GetCurrentViewMode(fview, NULL);
+        }
+
+        hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
+        ok(hr == S_OK, "got (0x%08x)\n", hr);
+        ok(viewmode == 1, "ViewMode was %d\n", viewmode);
+
+        hr = IFolderView_SetCurrentViewMode(fview, FVM_AUTO);
+        ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+        hr = IFolderView_SetCurrentViewMode(fview, 0);
+        ok(hr == E_INVALIDARG || broken(hr == S_OK),
+           "got (0x%08x)\n", hr);
+
+        hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
+        ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+        for(i = 1; i < 9; i++)
+        {
+            hr = IFolderView_SetCurrentViewMode(fview, i);
+            ok(hr == S_OK || (i == 8 && hr == E_INVALIDARG /*Vista*/),
+               "(%d) got (0x%08x)\n", i, hr);
+
+            hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
+            ok(hr == S_OK, "(%d) got (0x%08x)\n", i, hr);
+
+            /* Wine currently behaves like winxp here. */
+            ok((viewmode == win7_res[i]) || (viewmode == vista_res[i]) ||
+               (viewmode == win2k3_res[i]) || (viewmode == winxp_res[i]),
+               "(%d) got %d\n",i , viewmode);
+        }
+
+        hr = IFolderView_SetCurrentViewMode(fview, 9);
+        ok(hr == E_INVALIDARG || broken(hr == S_OK),
+           "got (0x%08x)\n", hr);
+
+        IFolderView_Release(fview);
+    }
+
+    IShellView_DestroyViewWindow(sview);
+    IShellView_Release(sview);
+    IShellFolder_Release(desktop);
+}
+
 START_TEST(shlview)
 {
     OleInitialize(NULL);
@@ -754,6 +834,7 @@ START_TEST(shlview)
     test_GetItemObject();
     test_IShellFolderView();
     test_IOleWindow();
+    test_GetSetCurrentViewMode();
 
     OleUninitialize();
 }
-- 
1.7.1.1




More information about the wine-patches mailing list