Module: wine Branch: master Commit: 8bbb32c99d2aea66183321b601335c748c4bfdcb URL: https://source.winehq.org/git/wine.git/?a=commit;h=8bbb32c99d2aea66183321b60...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Mar 21 08:59:41 2018 +0300
comdlg32: Add support for Places bar customization.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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;
/***********************************************************************