[PATCH] comdlg32: Implement Places toolbar for file dialogs
Nikolay Sivov
nsivov at codeweavers.com
Fri Mar 16 07:55:43 CDT 2018
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/comdlg32/comdlg32.rc | 26 ++++++++
dlls/comdlg32/filedlg.c | 141 ++++++++++++++++++++++++++++++++---------
dlls/comdlg32/filedlgbrowser.h | 1 +
include/commdlg.h | 2 +
4 files changed, 140 insertions(+), 30 deletions(-)
diff --git a/dlls/comdlg32/comdlg32.rc b/dlls/comdlg32/comdlg32.rc
index 44e3d58cfd..0dc2b48bde 100644
--- a/dlls/comdlg32/comdlg32.rc
+++ b/dlls/comdlg32/comdlg32.rc
@@ -478,6 +478,32 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "&Help", pshHelp,222,145,54,14
}
+NEWFILEOPENV2ORD DIALOG 0, 0, 370, 237
+STYLE DS_MODALFRAME | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN
+CAPTION "Open"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Look &in:", IDC_LOOKINSTATIC, 28, 6, 43, 8, SS_NOTIFY
+ COMBOBOX IDC_LOOKIN, 64, 3, 150, 100, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "" , IDC_TOOLBARSTATIC, 209, 2, 102, 17, NOT WS_GROUP | NOT WS_VISIBLE
+ CONTROL "", IDC_TOOLBARPLACES, "ToolbarWindow32", 0x800 | CCS_NORESIZE | CCS_TOP | CCS_NOPARENTALIGN | CCS_NODIVIDER, 4, 20, 55, 208
+ LISTBOX IDC_SHELLSTATIC, 64, 20, 300, 155, LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | NOT WS_VISIBLE
+
+ LTEXT "File &name:", IDC_FILENAMESTATIC, 65, 182, 56, 16, SS_NOTIFY
+ EDITTEXT IDC_FILENAME, 123, 180, 180, 12, ES_AUTOHSCROLL
+ CONTROL "", cmb13, "ComboBoxEx32", CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP, 123, 180, 180, 150
+
+ LTEXT "Files of &type:", IDC_FILETYPESTATIC, 65, 200, 56, 16, SS_NOTIFY
+ COMBOBOX IDC_FILETYPE, 123, 198, 180, 53, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ CONTROL "Open as &read-only", IDC_OPENREADONLY, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 123, 218, 150, 10
+
+ DEFPUSHBUTTON "&Open", IDOK, 310, 180, 54, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 310, 198, 54, 14
+ PUSHBUTTON "&Help", pshHelp, 310, 215, 54, 14
+}
+
NEWFILEOPENV3ORD DIALOG 0, 0, 440, 300
STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN |
WS_THICKFRAME
diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c
index 2ad7efa80e..8d989bc6f6 100644
--- a/dlls/comdlg32/filedlg.c
+++ b/dlls/comdlg32/filedlg.c
@@ -122,6 +122,10 @@ 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
+
/* NOTE
* Those macros exist in windowsx.h. However, you can't really use them since
* they rely on the UNICODE defines and can't be used inside Wine itself.
@@ -197,7 +201,6 @@ static LRESULT FILEDLG95_SHELL_Init(HWND hwnd);
static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd);
static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb);
static void FILEDLG95_SHELL_Clean(HWND hwnd);
-static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd);
/* Functions used by the EDIT box */
static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed);
@@ -242,6 +245,13 @@ 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 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));
+}
+
/***********************************************************************
* GetFileName95
*
@@ -258,6 +268,7 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
void *template;
HRSRC hRes;
HANDLE hDlgTmpl = 0;
+ WORD templateid;
/* test for missing functionality */
if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
@@ -268,7 +279,12 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
/* Create the dialog from a template */
- if(!(hRes = FindResourceW(COMDLG32_hInstance,MAKEINTRESOURCEW(NEWFILEOPENORD),(LPCWSTR)RT_DIALOG)))
+ if (is_places_bar_enabled(fodInfos))
+ templateid = NEWFILEOPENV2ORD;
+ else
+ templateid = NEWFILEOPENORD;
+
+ if (!(hRes = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(templateid), (LPCWSTR)RT_DIALOG)))
{
COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
return FALSE;
@@ -1306,8 +1322,18 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
case WM_DESTROY:
{
FileOpenDlgInfos * fodInfos = get_filedlg_infoptr(hwnd);
+ HWND places_bar = GetDlgItem(hwnd, IDC_TOOLBARPLACES);
+ HIMAGELIST himl;
+
if (fodInfos && fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
MemDialogSize = fodInfos->sizedlg;
+
+ if (places_bar)
+ {
+ himl = (HIMAGELIST)SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_GETIMAGELIST, 0, 0);
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0);
+ ImageList_Destroy(himl);
+ }
RemovePropW(hwnd, filedlg_info_propnameW);
return FALSE;
}
@@ -1395,8 +1421,8 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
RECT rectlook;
HIMAGELIST toolbarImageList;
- SHFILEINFOA shFileInfo;
ITEMIDLIST *desktopPidl;
+ SHFILEINFOW fileinfo;
FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
@@ -1465,17 +1491,66 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
/* Retrieve and add desktop icon to the toolbar */
toolbarImageList = (HIMAGELIST)SendMessageW(fodInfos->DlgInfos.hwndTB, TB_GETIMAGELIST, 0, 0L);
SHGetSpecialFolderLocation(hwnd, CSIDL_DESKTOP, &desktopPidl);
- SHGetFileInfoA((LPCSTR)desktopPidl, 0, &shFileInfo, sizeof(shFileInfo),
+ SHGetFileInfoW((const WCHAR *)desktopPidl, 0, &fileinfo, sizeof(fileinfo),
SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
- ImageList_AddIcon(toolbarImageList, shFileInfo.hIcon);
+ ImageList_AddIcon(toolbarImageList, fileinfo.hIcon);
- DestroyIcon(shFileInfo.hIcon);
+ DestroyIcon(fileinfo.hIcon);
CoTaskMemFree(desktopPidl);
/* Finish Toolbar Construction */
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb);
SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
+ 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;
+ int i, cx;
+
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_BUTTONSTRUCTSIZE, 0, 0);
+ GetClientRect(GetDlgItem(hwnd, IDC_TOOLBARPLACES), &rect);
+ 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++)
+ {
+ ITEMIDLIST *pidl;
+
+ SHGetSpecialFolderLocation(NULL, default_places[i].csidl, &pidl);
+ memset(&fileinfo, 0, sizeof(fileinfo));
+ SHGetFileInfoW((const WCHAR *)pidl, 0, &fileinfo, sizeof(fileinfo),
+ SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON);
+ ImageList_AddIcon(himl, fileinfo.hIcon);
+
+ tb.iBitmap = i;
+ tb.iString = (INT_PTR)fileinfo.szDisplayName;
+ tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
+ tb.idCommand = default_places[i].cmdid;
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_ADDBUTTONSW, 1, (LPARAM)&tb);
+
+ DestroyIcon(fileinfo.hIcon);
+ CoTaskMemFree(pidl);
+ }
+
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, (LPARAM)himl);
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cx * 3 / 4));
+ }
+
/* Set the window text with the text specified in the OPENFILENAME structure */
if(fodInfos->title)
{
@@ -1818,6 +1893,25 @@ void FILEDLG95_Clean(HWND hwnd)
FILEDLG95_LOOKIN_Clean(hwnd);
FILEDLG95_SHELL_Clean(hwnd);
}
+
+
+/***********************************************************************
+ * Browse to special folder
+ */
+static void filedlg_browse_to_specialfolder(const FileOpenDlgInfos *info, int csidl)
+{
+ LPITEMIDLIST pidl;
+
+ TRACE("%p, %d\n", info->ShellInfos.hwndOwner, csidl);
+
+ 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);
+}
+
/***********************************************************************
* FILEDLG95_OnWMCommand
*
@@ -1866,9 +1960,18 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
case FCIDM_TB_REPORTVIEW:
FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
break;
- /* Details option button */
+
case FCIDM_TB_DESKTOP:
- FILEDLG95_SHELL_BrowseToDesktop(hwnd);
+ case TBPLACES_CMDID_DESKTOP:
+ filedlg_browse_to_specialfolder(fodInfos, CSIDL_DESKTOP);
+ break;
+
+ case TBPLACES_CMDID_MYDOCS:
+ filedlg_browse_to_specialfolder(fodInfos, CSIDL_MYDOCUMENTS);
+ break;
+
+ case TBPLACES_CMDID_MYCOMPUTER:
+ filedlg_browse_to_specialfolder(fodInfos, CSIDL_DRIVES);
break;
case edt1:
@@ -2841,28 +2944,6 @@ static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
}
return FALSE;
}
-
-/***********************************************************************
- * FILEDLG95_SHELL_BrowseToDesktop
- *
- * Browse to the Desktop
- * If the function succeeds, the return value is nonzero.
- */
-static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
-{
- FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
- LPITEMIDLIST pidl;
- HRESULT hres;
-
- TRACE("\n");
-
- SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidl);
- hres = IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
- if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
- SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE);
- COMDLG32_SHFree(pidl);
- return SUCCEEDED(hres);
-}
/***********************************************************************
* FILEDLG95_SHELL_Clean
*
diff --git a/dlls/comdlg32/filedlgbrowser.h b/dlls/comdlg32/filedlgbrowser.h
index 5cb5435b89..69790e9a75 100644
--- a/dlls/comdlg32/filedlgbrowser.h
+++ b/dlls/comdlg32/filedlgbrowser.h
@@ -131,6 +131,7 @@ typedef struct
#define IDC_FILENAME edt1
#define IDC_TOOLBAR 1
+#define IDC_TOOLBARPLACES ctl1
/***********************************************************************
* Prototypes for the methods of the IShellBrowserImpl class
diff --git a/include/commdlg.h b/include/commdlg.h
index c059b19ec8..214badd085 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -65,6 +65,8 @@ extern "C" {
#define OFN_DONTADDTORECENT 0x02000000
#define OFN_FORCESHOWHIDDEN 0x10000000
+#define OFN_EX_NOPLACESBAR 0x00000001
+
#define OFN_SHAREFALLTHROUGH 2
#define OFN_SHARENOWARN 1
#define OFN_SHAREWARN 0
--
2.16.2
More information about the wine-devel
mailing list