Piotr Caban : shell32: Implement "make new folder" functionality in SHBrowseForFolder.

Alexandre Julliard julliard at winehq.org
Mon Jul 4 13:46:05 CDT 2011


Module: wine
Branch: master
Commit: 74c47d0a6709386ea8d28566c5d91fae4d4373e8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=74c47d0a6709386ea8d28566c5d91fae4d4373e8

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Sun Jul  3 13:55:39 2011 +0200

shell32: Implement "make new folder" functionality in SHBrowseForFolder.

---

 dlls/shell32/brsfolder.c       |  120 ++++++++++++++++++++++++++++++++++++---
 dlls/shell32/tests/brsfolder.c |    2 +-
 2 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/dlls/shell32/brsfolder.c b/dlls/shell32/brsfolder.c
index 3a7a736..48e19cd 100644
--- a/dlls/shell32/brsfolder.c
+++ b/dlls/shell32/brsfolder.c
@@ -18,7 +18,6 @@
  * FIXME:
  *  - many memory leaks
  *  - many flags unimplemented
- *    - implement new dialog style "make new folder" button
  *    - implement editbox
  */
 
@@ -35,6 +34,7 @@
 #include "shell32_main.h"
 #include "shellapi.h"
 #include "shresdef.h"
+#include "shellfolder.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -489,17 +489,20 @@ static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptv
         if (FAILED(r) || !(dwAttributes & (SFGAO_FILESYSANCESTOR|SFGAO_FILESYSTEM)))
             bEnabled = FALSE;
     }
-    if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
-    {
-        dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
-        r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
-                                (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
-        if (FAILED(r) || 
+
+    dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
+    r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
+            (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
+    if (FAILED(r) ||
             ((dwAttributes & (SFGAO_FOLDER|SFGAO_FILESYSTEM)) != (SFGAO_FOLDER|SFGAO_FILESYSTEM)))
-        {
+    {
+        if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
             bEnabled = FALSE;
-        }
+        EnableWindow(GetDlgItem(info->hWnd, IDD_MAKENEWFOLDER), FALSE);
     }
+    else
+        EnableWindow(GetDlgItem(info->hWnd, IDD_MAKENEWFOLDER), TRUE);
+
     SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, bEnabled);
 }
 
@@ -675,6 +678,103 @@ static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
     return TRUE;
 }
 
+static HRESULT BrsFolder_Rename(browse_info *info, HTREEITEM rename)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT BrsFolder_NewFolder(browse_info *info)
+{
+    DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
+    IShellFolder *desktop, *cur;
+    ISFHelper *sfhelper;
+    WCHAR name[MAX_PATH];
+    HTREEITEM parent, added;
+    LPTV_ITEMDATA item_data;
+    LPITEMIDLIST new_item;
+    TVITEMW item;
+    HRESULT hr;
+    int len;
+
+    if(!info->pidlRet) {
+        ERR("Make new folder button should be disabled\n");
+        return E_FAIL;
+    }
+
+    /* Create new directory */
+    hr = SHGetDesktopFolder(&desktop);
+    if(FAILED(hr))
+        return hr;
+    hr = IShellFolder_BindToObject(desktop, info->pidlRet, 0, &IID_IShellFolder, (void**)&cur);
+    IShellFolder_Release(desktop);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IShellFolder_QueryInterface(cur, &IID_ISFHelper, (void**)&sfhelper);
+    if(FAILED(hr))
+        return hr;
+
+    hr = SHGetPathFromIDListW(info->pidlRet, name);
+    if(FAILED(hr))
+        goto cleanup;
+
+    len = strlenW(name);
+    if(len<MAX_PATH)
+        name[len++] = '\\';
+    hr = ISFHelper_GetUniqueName(sfhelper, &name[len], MAX_PATH-len);
+    ISFHelper_Release(sfhelper);
+    if(FAILED(hr))
+        goto cleanup;
+
+    hr = E_FAIL;
+    if(!CreateDirectoryW(name, NULL))
+        goto cleanup;
+
+    /* Update parent of newly created directory */
+    parent = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0);
+    if(!parent)
+        goto cleanup;
+
+    SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)parent);
+
+    memset(&item, 0, sizeof(TVITEMW));
+    item.mask = TVIF_PARAM|TVIF_STATE;
+    item.hItem = parent;
+    SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
+    item_data = (LPTV_ITEMDATA)item.lParam;
+    if(!item_data)
+        goto cleanup;
+
+    if(item_data->pEnumIL)
+        IEnumIDList_Release(item_data->pEnumIL);
+    hr = IShellFolder_EnumObjects(cur, info->hwndTreeView, flags, &item_data->pEnumIL);
+    if(FAILED(hr))
+        goto cleanup;
+
+    /* Update treeview */
+    if(!(item.state&TVIS_EXPANDEDONCE)) {
+        item.mask = TVIF_STATE;
+        item.state = TVIS_EXPANDEDONCE;
+        item.stateMask = TVIS_EXPANDEDONCE;
+        SendMessageW(info->hwndTreeView, TVM_SETITEMW, 0, (LPARAM)&item);
+    }
+
+    hr = IShellFolder_ParseDisplayName(cur, NULL, NULL, name+len, NULL, &new_item, NULL);
+    if(FAILED(hr))
+        goto cleanup;
+
+    added = InsertTreeViewItem(info, cur, new_item, item_data->lpifq, NULL, parent);
+    IShellFolder_Release(cur);
+    SHFree(new_item);
+
+    SendMessageW(info->hwndTreeView, TVM_SORTCHILDREN, FALSE, (LPARAM)parent);
+    return BrsFolder_Rename(info, added);
+
+cleanup:
+    return hr;
+}
+
 static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
 {
     LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
@@ -695,7 +795,7 @@ static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
         return TRUE;
 
     case IDD_MAKENEWFOLDER:
-        FIXME("make new folder not implemented\n");
+        BrsFolder_NewFolder(info);
         return TRUE;
     }
     return FALSE;
diff --git a/dlls/shell32/tests/brsfolder.c b/dlls/shell32/tests/brsfolder.c
index c3e9d3c..03dff74 100644
--- a/dlls/shell32/tests/brsfolder.c
+++ b/dlls/shell32/tests/brsfolder.c
@@ -216,7 +216,7 @@ static void test_click_make_new_folder_button(void)
     pidl = SHBrowseForFolder(&bi);
 
     number_of_folders = get_number_of_folders(test_folder_path);
-    todo_wine ok(number_of_folders == 1 || broken(number_of_folders == 0) /* W95, W98 */,
+    ok(number_of_folders == 1 || broken(number_of_folders == 0) /* W95, W98 */,
         "Clicking \"Make New Folder\" button did not result in a new folder.\n");
 
     /* There should be a new folder foo inside the test folder */




More information about the wine-cvs mailing list