Nikolay Sivov : comdlg32: Add support for Places bar customization.
Alexandre Julliard
julliard at winehq.org
Wed Mar 21 17:05:17 CDT 2018
Module: wine
Branch: master
Commit: 8bbb32c99d2aea66183321b601335c748c4bfdcb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=8bbb32c99d2aea66183321b601335c748c4bfdcb
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Mar 21 08:59:41 2018 +0300
comdlg32: Add support for Places bar customization.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/comdlg32/filedlg.c | 191 +++++++++++++++++++++++++++++++----------
dlls/comdlg32/filedlgbrowser.h | 1 +
2 files changed, 149 insertions(+), 43 deletions(-)
diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c
index 81f7449..13226e0 100644
--- a/dlls/comdlg32/filedlg.c
+++ b/dlls/comdlg32/filedlg.c
@@ -121,9 +121,11 @@ typedef struct tagLookInInfo
/* Undefined windows message sent by CreateViewObject*/
#define WM_GETISHELLBROWSER WM_USER+7
-#define TBPLACES_CMDID_DESKTOP 0xa065
-#define TBPLACES_CMDID_MYDOCS 0xa066
-#define TBPLACES_CMDID_MYCOMPUTER 0xa067
+#define TBPLACES_CMDID_PLACE0 0xa064
+#define TBPLACES_CMDID_PLACE1 0xa065
+#define TBPLACES_CMDID_PLACE2 0xa066
+#define TBPLACES_CMDID_PLACE3 0xa067
+#define TBPLACES_CMDID_PLACE4 0xa068
/* NOTE
* Those macros exist in windowsx.h. However, you can't really use them since
@@ -214,11 +216,117 @@ static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM
static BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed);
static BOOL BrowseSelectedFolder(HWND hwnd);
+static BOOL get_config_key_as_dword(HKEY hkey, const WCHAR *name, DWORD *value)
+{
+ DWORD type, data, size;
+
+ size = sizeof(data);
+ if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size))
+ {
+ *value = data;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL get_config_key_dword(HKEY hkey, const WCHAR *name, DWORD *value)
+{
+ DWORD type, data, size;
+
+ size = sizeof(data);
+ if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD)
+ {
+ *value = data;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL get_config_key_string(HKEY hkey, const WCHAR *name, WCHAR **value)
+{
+ DWORD type, size;
+ WCHAR *str;
+
+ if (hkey && !RegQueryValueExW(hkey, name, 0, &type, NULL, &size))
+ {
+ if (type != REG_SZ && type != REG_EXPAND_SZ)
+ return FALSE;
+ }
+
+ str = heap_alloc(size);
+ if (RegQueryValueExW(hkey, name, 0, &type, (BYTE *)str, &size))
+ {
+ heap_free(str);
+ return FALSE;
+ }
+
+ *value = str;
+ return TRUE;
+}
+
static BOOL is_places_bar_enabled(const FileOpenDlgInfos *fodInfos)
{
- return (fodInfos->ofnInfos->lStructSize == sizeof(*fodInfos->ofnInfos) &&
- !(fodInfos->ofnInfos->FlagsEx & OFN_EX_NOPLACESBAR) &&
- (fodInfos->ofnInfos->Flags & OFN_EXPLORER));
+ static const WCHAR noplacesbarW[] = {'N','o','P','l','a','c','e','s','B','a','r',0};
+ DWORD value;
+ HKEY hkey;
+
+ if (fodInfos->ofnInfos->lStructSize != sizeof(*fodInfos->ofnInfos) ||
+ (fodInfos->ofnInfos->FlagsEx & OFN_EX_NOPLACESBAR) ||
+ !(fodInfos->ofnInfos->Flags & OFN_EXPLORER))
+ {
+ return FALSE;
+ }
+
+ if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32", &hkey))
+ return TRUE;
+
+ value = 0;
+ get_config_key_as_dword(hkey, noplacesbarW, &value);
+ RegCloseKey(hkey);
+ return value == 0;
+}
+
+static void filedlg_collect_places_pidls(FileOpenDlgInfos *fodInfos)
+{
+ static const int default_places[] =
+ {
+ CSIDL_DESKTOP,
+ CSIDL_MYDOCUMENTS,
+ CSIDL_DRIVES,
+ };
+ unsigned int i;
+ HKEY hkey;
+
+ if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32\\Placesbar",
+ &hkey))
+ {
+ for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
+ {
+ static const WCHAR placeW[] = {'P','l','a','c','e','%','d',0};
+ WCHAR nameW[8];
+ DWORD value;
+ WCHAR *str;
+
+ sprintfW(nameW, placeW, i);
+ if (get_config_key_dword(hkey, nameW, &value))
+ SHGetSpecialFolderLocation(NULL, value, &fodInfos->places[i]);
+ else if (get_config_key_string(hkey, nameW, &str))
+ {
+ SHParseDisplayName(str, NULL, &fodInfos->places[i], 0, NULL);
+ heap_free(str);
+ }
+ }
+
+ /* FIXME: eliminate duplicates. */
+
+ RegCloseKey(hkey);
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(default_places); i++)
+ SHGetSpecialFolderLocation(NULL, default_places[i], &fodInfos->places[i]);
}
/***********************************************************************
@@ -434,6 +542,7 @@ static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
{
WCHAR *current_dir = NULL;
+ unsigned int i;
BOOL ret;
/* save current directory */
@@ -472,6 +581,10 @@ static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
heap_free(info->filename);
heap_free(info->initdir);
+
+ for (i = 0; i < ARRAY_SIZE(info->places); i++)
+ ILFree(info->places[i]);
+
return ret;
}
@@ -1477,17 +1590,6 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
if (is_places_bar_enabled(fodInfos))
{
- static const struct bar_place_descr
- {
- int csidl;
- int cmdid;
- }
- default_places[] =
- {
- { CSIDL_DESKTOP, TBPLACES_CMDID_DESKTOP },
- { CSIDL_MYDOCUMENTS, TBPLACES_CMDID_MYDOCS },
- { CSIDL_DRIVES, TBPLACES_CMDID_MYCOMPUTER },
- };
TBBUTTON tb = { 0 };
HIMAGELIST himl;
RECT rect;
@@ -1498,26 +1600,28 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
cx = rect.right - rect.left;
SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cx, cx));
-
himl = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32, 4, 1);
- for (i = 0; i < sizeof(default_places)/sizeof(default_places[0]); i++)
+
+ filedlg_collect_places_pidls(fodInfos);
+ for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
{
- ITEMIDLIST *pidl;
+ int index;
+
+ if (!fodInfos->places[i])
+ continue;
- SHGetSpecialFolderLocation(NULL, default_places[i].csidl, &pidl);
memset(&fileinfo, 0, sizeof(fileinfo));
- SHGetFileInfoW((const WCHAR *)pidl, 0, &fileinfo, sizeof(fileinfo),
+ SHGetFileInfoW((const WCHAR *)fodInfos->places[i], 0, &fileinfo, sizeof(fileinfo),
SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON);
- ImageList_AddIcon(himl, fileinfo.hIcon);
+ index = ImageList_AddIcon(himl, fileinfo.hIcon);
- tb.iBitmap = i;
+ tb.iBitmap = index;
tb.iString = (INT_PTR)fileinfo.szDisplayName;
tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
- tb.idCommand = default_places[i].cmdid;
+ tb.idCommand = TBPLACES_CMDID_PLACE0 + i;
SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_ADDBUTTONSW, 1, (LPARAM)&tb);
DestroyIcon(fileinfo.hIcon);
- CoTaskMemFree(pidl);
}
SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, (LPARAM)himl);
@@ -1869,20 +1973,15 @@ void FILEDLG95_Clean(HWND hwnd)
/***********************************************************************
- * Browse to special folder
+ * Browse to arbitrary pidl
*/
-static void filedlg_browse_to_specialfolder(const FileOpenDlgInfos *info, int csidl)
+static void filedlg_browse_to_pidl(const FileOpenDlgInfos *info, LPITEMIDLIST pidl)
{
- LPITEMIDLIST pidl;
-
- TRACE("%p, %d\n", info->ShellInfos.hwndOwner, csidl);
+ TRACE("%p, %p\n", info->ShellInfos.hwndOwner, pidl);
- SHGetSpecialFolderLocation(0, csidl, &pidl);
IShellBrowser_BrowseObject(info->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
if (info->ofnInfos->Flags & OFN_EXPLORER)
SendCustomDlgNotificationMessage(info->ShellInfos.hwndOwner, CDN_FOLDERCHANGE);
-
- COMDLG32_SHFree(pidl);
}
/***********************************************************************
@@ -1894,9 +1993,9 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
{
FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
WORD wNotifyCode = HIWORD(wParam); /* notification code */
- WORD wID = LOWORD(wParam); /* item, control, or accelerator identifier */
+ WORD id = LOWORD(wParam); /* item, control, or accelerator identifier */
- switch(wID)
+ switch (id)
{
/* OK button */
case IDOK:
@@ -1935,16 +2034,22 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
break;
case FCIDM_TB_DESKTOP:
- case TBPLACES_CMDID_DESKTOP:
- filedlg_browse_to_specialfolder(fodInfos, CSIDL_DESKTOP);
- break;
+ {
+ LPITEMIDLIST pidl;
- case TBPLACES_CMDID_MYDOCS:
- filedlg_browse_to_specialfolder(fodInfos, CSIDL_MYDOCUMENTS);
+ SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidl);
+ filedlg_browse_to_pidl(fodInfos, pidl);
+ COMDLG32_SHFree(pidl);
break;
+ }
- case TBPLACES_CMDID_MYCOMPUTER:
- filedlg_browse_to_specialfolder(fodInfos, CSIDL_DRIVES);
+ /* Places bar */
+ case TBPLACES_CMDID_PLACE0:
+ case TBPLACES_CMDID_PLACE1:
+ case TBPLACES_CMDID_PLACE2:
+ case TBPLACES_CMDID_PLACE3:
+ case TBPLACES_CMDID_PLACE4:
+ filedlg_browse_to_pidl(fodInfos, fodInfos->places[id - TBPLACES_CMDID_PLACE0]);
break;
case edt1:
diff --git a/dlls/comdlg32/filedlgbrowser.h b/dlls/comdlg32/filedlgbrowser.h
index 69790e9..21eb3d5 100644
--- a/dlls/comdlg32/filedlgbrowser.h
+++ b/dlls/comdlg32/filedlgbrowser.h
@@ -93,6 +93,7 @@ typedef struct
} HookMsg;
BOOL ole_initialized;
+ LPITEMIDLIST places[5];
} FileOpenDlgInfos;
/***********************************************************************
More information about the wine-cvs
mailing list