*
*/
-// RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
+#include "config.h"
+#include "wine/port.h"
-#include <config.h>
-//#include "wine/port.h"
-
-//#include <ctype.h>
-//#include <stdlib.h>
+#include <ctype.h>
+#include <stdlib.h>
#include <stdarg.h>
-//#include <stdio.h>
-//#include <string.h>
+#include <stdio.h>
+#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include <windef.h>
-//#include "winbase.h"
-#include <winternl.h>
-//#include "winnls.h"
-#include <wingdi.h>
-#include <winreg.h>
-#include <winuser.h>
-#include <commdlg.h>
-//#include "dlgs.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "winnls.h"
+#include "wingdi.h"
+#ifdef __REACTOS__
+/* RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista */
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+#include "winreg.h"
+#include "winuser.h"
+#include "commdlg.h"
+#include "dlgs.h"
#include "cdlg.h"
-#include "filedlg31.h"
-#include <cderr.h>
-//#include "shellapi.h"
-//#include "shlobj.h"
+#include "cderr.h"
+#include "shellapi.h"
+#include "shlobj.h"
#include "filedlgbrowser.h"
-#include <shlwapi.h>
+#include "shlwapi.h"
-#include <wine/unicode.h>
-#include <wine/debug.h>
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\
OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/)
-#define IsHooked(fodInfos) \
- ((fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK) && fodInfos->ofnInfos->lpfnHook)
/***********************************************************************
* Data structure and global variables
*/
*/
/* Draw item constant */
-#define ICONWIDTH 18
#define XTEXTOFFSET 3
/* AddItem flags*/
/* Undefined windows message sent by CreateViewObject*/
#define WM_GETISHELLBROWSER WM_USER+7
+#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
* they rely on the UNICODE defines and can't be used inside Wine itself.
*/
/* Combo box macros */
-#define CBAddString(hwnd,str) \
- SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)(str));
-
-#define CBInsertString(hwnd,str,pos) \
- SendMessageW(hwnd, CB_INSERTSTRING, (WPARAM)(pos), (LPARAM)(str));
-
-#define CBDeleteString(hwnd,pos) \
- SendMessageW(hwnd, CB_DELETESTRING, (WPARAM)(pos), 0);
-
-#define CBSetItemDataPtr(hwnd,iItemId,dataPtr) \
- SendMessageW(hwnd, CB_SETITEMDATA, (WPARAM)(iItemId), (LPARAM)(dataPtr));
-
#define CBGetItemDataPtr(hwnd,iItemId) \
SendMessageW(hwnd, CB_GETITEMDATA, (WPARAM)(iItemId), 0)
-#define CBGetLBText(hwnd,iItemId,str) \
- SendMessageW(hwnd, CB_GETLBTEXT, (WPARAM)(iItemId), (LPARAM)(str));
-
-#define CBGetCurSel(hwnd) \
- SendMessageW(hwnd, CB_GETCURSEL, 0, 0);
-
-#define CBSetCurSel(hwnd,pos) \
- SendMessageW(hwnd, CB_SETCURSEL, (WPARAM)(pos), 0);
-
-#define CBGetCount(hwnd) \
- SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
-#define CBShowDropDown(hwnd,show) \
- SendMessageW(hwnd, CB_SHOWDROPDOWN, (WPARAM)(show), 0);
-#define CBSetItemHeight(hwnd,index,height) \
- SendMessageW(hwnd, CB_SETITEMHEIGHT, (WPARAM)(index), (LPARAM)(height));
-
-#define CBSetExtendedUI(hwnd,flag) \
- SendMessageW(hwnd, CB_SETEXTENDEDUI, (WPARAM)(flag), 0)
-
-const char FileOpenDlgInfosStr[] = "FileOpenDlgInfos"; /* windows property description string */
static const char LookInInfosStr[] = "LookInInfos"; /* LOOKIN combo box property */
static SIZE MemDialogSize = { 0, 0}; /* keep size of the (resizable) dialog */
'L','a','s','t','V','i','s','i','t','e','d','M','R','U',0};
static const WCHAR MRUListW[] = {'M','R','U','L','i','s','t',0};
+static const WCHAR filedlg_info_propnameW[] = {'F','i','l','e','O','p','e','n','D','l','g','I','n','f','o','s',0};
+
+FileOpenDlgInfos *get_filedlg_infoptr(HWND hwnd)
+{
+ return GetPropW(hwnd, filedlg_info_propnameW);
+}
+
+static BOOL is_dialog_hooked(const FileOpenDlgInfos *info)
+{
+ return (info->ofnInfos->Flags & OFN_ENABLEHOOK) && info->ofnInfos->lpfnHook;
+}
+
+static BOOL filedialog_is_readonly_hidden(const FileOpenDlgInfos *info)
+{
+ return (info->ofnInfos->Flags & OFN_HIDEREADONLY) || (info->DlgInfos.dwDlgProp & FODPROP_SAVEDLG);
+}
+
/***********************************************************************
* Prototypes
*/
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);
static void FILEDLG95_MRU_load_filename(LPWSTR stored_path);
static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret);
static void FILEDLG95_MRU_save_filename(LPCWSTR filename);
+#ifdef __REACTOS__
+static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext);
+static void FILEDLG95_MRU_save_ext(LPCWSTR filename);
+#endif
/* Miscellaneous tool functions */
static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName);
static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
static UINT GetNumSelected( IDataObject *doSelected );
-
-/* Shell memory allocation */
-static void *MemAlloc(UINT size);
-static void MemFree(void *mem);
+static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium);
static INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
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)
+{
+ 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;
+ HRESULT hr;
+ WCHAR *str;
+
+ sprintfW(nameW, placeW, i);
+ if (get_config_key_dword(hkey, nameW, &value))
+ {
+ hr = SHGetSpecialFolderLocation(NULL, value, &fodInfos->places[i]);
+ if (FAILED(hr))
+ WARN("Unrecognized special folder %u.\n", value);
+ }
+ else if (get_config_key_string(hkey, nameW, &str))
+ {
+ hr = SHParseDisplayName(str, NULL, &fodInfos->places[i], 0, NULL);
+ if (FAILED(hr))
+ WARN("Failed to parse custom places location, %s.\n", debugstr_w(str));
+ 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]);
+}
+
/***********************************************************************
* GetFileName95
*
*/
static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
{
-
LRESULT lRes;
- LPVOID template;
+ void *template;
HRSRC hRes;
HANDLE hDlgTmpl = 0;
- HRESULT hr;
- DWORD dwSize;
- LPDLGTEMPLATE hDialogTemplate;
+ WORD templateid;
/* test for missing functionality */
if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
/* 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;
}
if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
- !(dwSize = SizeofResource(COMDLG32_hInstance, hRes )) ||
- !(hDialogTemplate = malloc(dwSize)) ||
!(template = LockResource( hDlgTmpl )))
{
COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
return FALSE;
}
- /* Copy the read only resource */
- memcpy(hDialogTemplate, template, dwSize);
-
/* msdn: explorer style dialogs permit sizing by default.
* The OFN_ENABLESIZING flag is only needed when a hook or
- * custom tmeplate is provided */
+ * custom template is provided */
if( (fodInfos->ofnInfos->Flags & OFN_EXPLORER) &&
!(fodInfos->ofnInfos->Flags & ( OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)))
fodInfos->ofnInfos->Flags |= OFN_ENABLESIZING;
if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
{
- hDialogTemplate->style |= WS_SIZEBOX;
fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0;
fodInfos->initial_size.x = fodInfos->initial_size.y = 0;
}
- else
- hDialogTemplate->style &= ~WS_SIZEBOX;
-
/* old style hook messages */
- if (IsHooked(fodInfos))
+ if (is_dialog_hooked(fodInfos))
{
fodInfos->HookMsg.fileokstring = RegisterWindowMessageW(FILEOKSTRINGW);
fodInfos->HookMsg.lbselchstring = RegisterWindowMessageW(LBSELCHSTRINGW);
fodInfos->HookMsg.sharevistring = RegisterWindowMessageW(SHAREVISTRINGW);
}
- /* Some shell namespace extensions depend on COM being initialized. */
- hr = OleInitialize(NULL);
-
if (fodInfos->unicode)
lRes = DialogBoxIndirectParamW(COMDLG32_hInstance,
- hDialogTemplate,
+ template,
fodInfos->ofnInfos->hwndOwner,
FileOpenDlgProc95,
(LPARAM) fodInfos);
else
lRes = DialogBoxIndirectParamA(COMDLG32_hInstance,
- hDialogTemplate,
+ template,
fodInfos->ofnInfos->hwndOwner,
FileOpenDlgProc95,
(LPARAM) fodInfos);
- if (SUCCEEDED(hr))
+ if (fodInfos->ole_initialized)
OleUninitialize();
- free(hDialogTemplate);
-
/* Unable to create the dialog */
if( lRes == -1)
return FALSE;
return lRes;
}
-/***********************************************************************
- * GetFileDialog95A
- *
- * Call GetFileName95 with this structure and clean the memory.
- *
- * IN : The OPENFILENAMEA initialisation structure passed to
- * GetOpenFileNameA win api function (see filedlg.c)
- */
-static BOOL GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
+static WCHAR *heap_strdupAtoW(const char *str)
{
- BOOL ret;
- FileOpenDlgInfos fodInfos;
- LPSTR lpstrSavDir = NULL;
- LPWSTR title = NULL;
- LPWSTR defext = NULL;
- LPWSTR filter = NULL;
- LPWSTR customfilter = NULL;
+ WCHAR *ret;
+ INT len;
- /* Initialize CommDlgExtendedError() */
- COMDLG32_SetCommDlgExtendedError(0);
+ if (!str)
+ return NULL;
- /* Initialize FileOpenDlgInfos structure */
- ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
+ ret = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
- /* Pass in the original ofn */
- fodInfos.ofnInfos = (LPOPENFILENAMEW)ofn;
+ return ret;
+}
- /* save current directory */
- if (ofn->Flags & OFN_NOCHANGEDIR)
- {
- lpstrSavDir = MemAlloc(MAX_PATH);
- GetCurrentDirectoryA(MAX_PATH, lpstrSavDir);
- }
+static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info)
+{
+ INITCOMMONCONTROLSEX icc;
- fodInfos.unicode = FALSE;
+ /* Initialize ComboBoxEx32 */
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_USEREX_CLASSES;
+ InitCommonControlsEx(&icc);
- /* convert all the input strings to unicode */
- if(ofn->lpstrInitialDir)
- {
- DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, NULL, 0 );
- fodInfos.initdir = MemAlloc((len+1)*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, fodInfos.initdir, len);
- }
- else
- fodInfos.initdir = NULL;
+ /* Initialize CommDlgExtendedError() */
+ COMDLG32_SetCommDlgExtendedError(0);
- if(ofn->lpstrFile)
- {
- fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFile, -1, fodInfos.filename, ofn->nMaxFile);
- }
- else
- fodInfos.filename = NULL;
+ memset(info, 0, sizeof(*info));
- if(ofn->lpstrDefExt)
- {
- DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, NULL, 0 );
- defext = MemAlloc((len+1)*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, defext, len);
- }
- fodInfos.defext = defext;
+ /* Pass in the original ofn */
+ info->ofnInfos = ofn;
- if(ofn->lpstrTitle)
- {
- DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, NULL, 0 );
- title = MemAlloc((len+1)*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, title, len);
- }
- fodInfos.title = title;
+ info->title = ofn->lpstrTitle;
+ info->defext = ofn->lpstrDefExt;
+ info->filter = ofn->lpstrFilter;
+ info->customfilter = ofn->lpstrCustomFilter;
- if (ofn->lpstrFilter)
- {
- LPCSTR s;
- int n, len;
-
- /* filter is a list... title\0ext\0......\0\0 */
- s = ofn->lpstrFilter;
- while (*s) s = s+strlen(s)+1;
- s++;
- n = s - ofn->lpstrFilter;
- len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0 );
- filter = MemAlloc(len*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, filter, len );
- }
- fodInfos.filter = filter;
+ if (ofn->lpstrFile)
+ {
+ info->filename = heap_alloc(ofn->nMaxFile * sizeof(WCHAR));
+ lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile);
+ }
- /* convert lpstrCustomFilter */
- if (ofn->lpstrCustomFilter)
- {
- LPCSTR s;
- int n, len;
-
- /* customfilter contains a pair of strings... title\0ext\0 */
- s = ofn->lpstrCustomFilter;
- if (*s) s = s+strlen(s)+1;
- if (*s) s = s+strlen(s)+1;
- n = s - ofn->lpstrCustomFilter;
- len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0 );
- customfilter = MemAlloc(len*sizeof(WCHAR));
- MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, customfilter, len );
- }
- fodInfos.customfilter = customfilter;
+ if (ofn->lpstrInitialDir)
+ {
+ DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0);
+ if (len)
+ {
+ info->initdir = heap_alloc(len * sizeof(WCHAR));
+ ExpandEnvironmentStringsW(ofn->lpstrInitialDir, info->initdir, len);
+ }
+ }
- /* Initialize the dialog property */
- fodInfos.DlgInfos.dwDlgProp = 0;
- fodInfos.DlgInfos.hwndCustomDlg = NULL;
+ info->unicode = TRUE;
+}
- switch(iDlgType)
- {
- case OPEN_DIALOG :
- ret = GetFileName95(&fodInfos);
- break;
- case SAVE_DIALOG :
- fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
- ret = GetFileName95(&fodInfos);
- break;
- default :
- ret = 0;
- }
+static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
+{
+ OPENFILENAMEW ofnW;
+ int len;
- if (lpstrSavDir)
- {
- SetCurrentDirectoryA(lpstrSavDir);
- MemFree(lpstrSavDir);
- }
+ ofnW = *(OPENFILENAMEW *)ofn;
- MemFree(title);
- MemFree(defext);
- MemFree(filter);
- MemFree(customfilter);
- MemFree(fodInfos.initdir);
- MemFree(fodInfos.filename);
+ ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir);
+ ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt);
+ ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle);
- TRACE("selected file: %s\n",ofn->lpstrFile);
+ if (ofn->lpstrFile)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, NULL, 0);
+ ofnW.lpstrFile = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, ofnW.lpstrFile, len);
+ ofnW.nMaxFile = len;
+ }
- return ret;
+ if (ofn->lpstrFilter)
+ {
+ LPCSTR s;
+ int n;
+
+ /* filter is a list... title\0ext\0......\0\0 */
+ s = ofn->lpstrFilter;
+ while (*s) s = s+strlen(s)+1;
+ s++;
+ n = s - ofn->lpstrFilter;
+ len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0);
+ ofnW.lpstrFilter = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, (WCHAR *)ofnW.lpstrFilter, len);
+ }
+
+ /* convert lpstrCustomFilter */
+ if (ofn->lpstrCustomFilter)
+ {
+ int n, len;
+ LPCSTR s;
+
+ /* customfilter contains a pair of strings... title\0ext\0 */
+ s = ofn->lpstrCustomFilter;
+ if (*s) s = s+strlen(s)+1;
+ if (*s) s = s+strlen(s)+1;
+ n = s - ofn->lpstrCustomFilter;
+ len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0);
+ ofnW.lpstrCustomFilter = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, ofnW.lpstrCustomFilter, len);
+ }
+
+ init_filedlg_infoW(&ofnW, info);
+
+ /* fixup A-specific fields */
+ info->ofnInfos = (OPENFILENAMEW *)ofn;
+ info->unicode = FALSE;
+
+ /* free what was duplicated */
+ heap_free((void *)ofnW.lpstrInitialDir);
+ heap_free(ofnW.lpstrFile);
}
/***********************************************************************
- * GetFileDialog95W
+ * GetFileDialog95
*
- * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
* Call GetFileName95 with this structure and clean the memory.
- *
*/
-static BOOL GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
+static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
{
- BOOL ret;
- FileOpenDlgInfos fodInfos;
- LPWSTR lpstrSavDir = NULL;
+ WCHAR *current_dir = NULL;
+ unsigned int i;
+ BOOL ret;
- /* Initialize CommDlgExtendedError() */
- COMDLG32_SetCommDlgExtendedError(0);
-
- /* Initialize FileOpenDlgInfos structure */
- ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
-
- /* Pass in the original ofn */
- fodInfos.ofnInfos = ofn;
-
- fodInfos.title = ofn->lpstrTitle;
- fodInfos.defext = ofn->lpstrDefExt;
- fodInfos.filter = ofn->lpstrFilter;
- fodInfos.customfilter = ofn->lpstrCustomFilter;
+ /* save current directory */
+ if (info->ofnInfos->Flags & OFN_NOCHANGEDIR)
+ {
+ current_dir = heap_alloc(MAX_PATH * sizeof(WCHAR));
+ GetCurrentDirectoryW(MAX_PATH, current_dir);
+ }
- /* convert string arguments, save others */
- if(ofn->lpstrFile)
- {
- fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR));
- lstrcpynW(fodInfos.filename,ofn->lpstrFile,ofn->nMaxFile);
- }
- else
- fodInfos.filename = NULL;
+ switch (dlg_type)
+ {
+ case OPEN_DIALOG:
+ ret = GetFileName95(info);
+ break;
+ case SAVE_DIALOG:
+ info->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
+ ret = GetFileName95(info);
+ break;
+ default:
+ ret = FALSE;
+ }
- if(ofn->lpstrInitialDir)
- {
- /* fodInfos.initdir = strdupW(ofn->lpstrInitialDir); */
- DWORD len = lstrlenW(ofn->lpstrInitialDir)+1;
- fodInfos.initdir = MemAlloc(len*sizeof(WCHAR));
- memcpy(fodInfos.initdir,ofn->lpstrInitialDir,len*sizeof(WCHAR));
- }
- else
- fodInfos.initdir = NULL;
+ /* set the lpstrFileTitle */
+ if (ret && info->ofnInfos->lpstrFile && info->ofnInfos->lpstrFileTitle)
+ {
+ if (info->unicode)
+ {
+ LPOPENFILENAMEW ofn = info->ofnInfos;
+ WCHAR *file_title = PathFindFileNameW(ofn->lpstrFile);
+ lstrcpynW(ofn->lpstrFileTitle, file_title, ofn->nMaxFileTitle);
+ }
+ else
+ {
+ LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)info->ofnInfos;
+ char *file_title = PathFindFileNameA(ofn->lpstrFile);
+ lstrcpynA(ofn->lpstrFileTitle, file_title, ofn->nMaxFileTitle);
+ }
+ }
- /* save current directory */
- if (ofn->Flags & OFN_NOCHANGEDIR)
- {
- lpstrSavDir = MemAlloc(MAX_PATH*sizeof(WCHAR));
- GetCurrentDirectoryW(MAX_PATH, lpstrSavDir);
- }
+ if (current_dir)
+ {
+ SetCurrentDirectoryW(current_dir);
+ heap_free(current_dir);
+ }
- fodInfos.unicode = TRUE;
+ if (!info->unicode)
+ {
+ heap_free((void *)info->defext);
+ heap_free((void *)info->title);
+ heap_free((void *)info->filter);
+ heap_free((void *)info->customfilter);
+ }
- switch(iDlgType)
- {
- case OPEN_DIALOG :
- ret = GetFileName95(&fodInfos);
- break;
- case SAVE_DIALOG :
- fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
- ret = GetFileName95(&fodInfos);
- break;
- default :
- ret = 0;
- }
+ heap_free(info->filename);
+ heap_free(info->initdir);
- if (lpstrSavDir)
- {
- SetCurrentDirectoryW(lpstrSavDir);
- MemFree(lpstrSavDir);
- }
+ for (i = 0; i < ARRAY_SIZE(info->places); i++)
+ ILFree(info->places[i]);
- /* restore saved IN arguments and convert OUT arguments back */
- MemFree(fodInfos.filename);
- MemFree(fodInfos.initdir);
- return ret;
+ return ret;
}
/******************************************************************************
}
PathAddBackslashW(lpstrPathAndFile);
- TRACE("current directory=%s\n", debugstr_w(lpstrPathAndFile));
+ TRACE("current directory=%s, file=%s\n", debugstr_w(lpstrPathAndFile), debugstr_w(lpstrFile));
/* if the user specified a fully qualified path use it */
if(PathIsRelativeW(lpstrFile))
/* we might get single filename without any '"',
* so we need nStrLen + terminating \0 + end-of-list \0 */
- *lpstrFileList = MemAlloc( (nStrLen+2)*sizeof(WCHAR) );
+ *lpstrFileList = heap_alloc((nStrLen + 2) * sizeof(WCHAR));
*sizeUsed = 0;
/* build delimited file list from filenames */
if ( lpstrEdit[nStrCharCount]=='"' )
{
nStrCharCount++;
- while ((lpstrEdit[nStrCharCount]!='"') && (nStrCharCount <= nStrLen))
+ while ((nStrCharCount <= nStrLen) && (lpstrEdit[nStrCharCount]!='"'))
{
(*lpstrFileList)[nFileIndex++] = lpstrEdit[nStrCharCount];
nStrCharCount++;
HANDLE hDlgTmpl = 0;
HWND hChildDlg = 0;
- TRACE("\n");
+ TRACE("%p, %p\n", fodInfos, hwnd);
/*
* If OFN_ENABLETEMPLATEHANDLE is specified, the OPENFILENAME
}
if (fodInfos->unicode)
hChildDlg = CreateDialogIndirectParamW(hinst, template, hwnd,
- IsHooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
+ is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
(LPARAM)fodInfos->ofnInfos);
else
hChildDlg = CreateDialogIndirectParamA(hinst, template, hwnd,
- IsHooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
+ is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
(LPARAM)fodInfos->ofnInfos);
return hChildDlg;
}
- else if( IsHooked(fodInfos))
+ else if (is_dialog_hooked(fodInfos))
{
RECT rectHwnd;
struct {
LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
{
- LRESULT hook_result = 0;
- FileOpenDlgInfos *fodInfos = GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg);
+ LRESULT hook_result;
+ OFNOTIFYW ofnNotify;
- TRACE("%p 0x%04x\n",hwndParentDlg, uCode);
+ TRACE("%p %d\n", hwndParentDlg, uCode);
- if(!fodInfos) return 0;
+ if (!fodInfos || !fodInfos->DlgInfos.hwndCustomDlg)
+ return 0;
+
+ TRACE("CALL NOTIFY for %d\n", uCode);
+
+ ofnNotify.hdr.hwndFrom = hwndParentDlg;
+ ofnNotify.hdr.idFrom = 0;
+ ofnNotify.hdr.code = uCode;
+ ofnNotify.lpOFN = fodInfos->ofnInfos;
+ ofnNotify.pszFile = NULL;
+
+ if (fodInfos->unicode)
+ hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
+ else
+ hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
+
+ TRACE("RET NOTIFY retval %#lx\n", hook_result);
- if(fodInfos->DlgInfos.hwndCustomDlg)
- {
- TRACE("CALL NOTIFY for %x\n", uCode);
- if(fodInfos->unicode)
- {
- OFNOTIFYW ofnNotify;
- ofnNotify.hdr.hwndFrom=hwndParentDlg;
- ofnNotify.hdr.idFrom=0;
- ofnNotify.hdr.code = uCode;
- ofnNotify.lpOFN = fodInfos->ofnInfos;
- ofnNotify.pszFile = NULL;
- hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
- }
- else
- {
- OFNOTIFYA ofnNotify;
- ofnNotify.hdr.hwndFrom=hwndParentDlg;
- ofnNotify.hdr.idFrom=0;
- ofnNotify.hdr.code = uCode;
- ofnNotify.lpOFN = (LPOPENFILENAMEA)fodInfos->ofnInfos;
- ofnNotify.pszFile = NULL;
- hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
- }
- TRACE("RET NOTIFY\n");
- }
- TRACE("Retval: 0x%08lx\n", hook_result);
return hook_result;
}
{
UINT len, total;
WCHAR *p, *buffer;
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("CDM_GETFILEPATH:\n");
/* get path and filenames */
len = SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0 );
- buffer = HeapAlloc( GetProcessHeap(), 0, (len + 2 + MAX_PATH) * sizeof(WCHAR) );
+ buffer = heap_alloc( (len + 2 + MAX_PATH) * sizeof(WCHAR) );
COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, buffer );
if (len)
{
if (total <= size) WideCharToMultiByte( CP_ACP, 0, buffer, -1, result, size, NULL, NULL );
TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_a(result));
}
- HeapFree( GetProcessHeap(), 0, buffer );
+ heap_free( buffer );
return total;
}
*/
static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
WCHAR lpstrPath[MAX_PATH];
INT_PTR retval;
break;
case CDM_GETFOLDERIDLIST:
- retval = COMDLG32_PIDL_ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent);
+ retval = ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent);
if (retval <= wParam)
memcpy((void*)lParam, fodInfos->ShellInfos.pidlAbsCurrent, retval);
break;
*/
static LRESULT FILEDLG95_OnWMGetMMI( HWND hwnd, LPMINMAXINFO mmiptr)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
if( fodInfos->initial_size.x || fodInfos->initial_size.y)
{
FileOpenDlgInfos *fodInfos;
if( wParam != SIZE_RESTORED) return FALSE;
- fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ fodInfos = get_filedlg_infoptr(hwnd);
if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
/* get the new dialog rectangle */
GetWindowRect( hwnd, &rc);
- TRACE("Size from %d,%d to %d,%d\n", fodInfos->sizedlg.cx, fodInfos->sizedlg.cy,
+ TRACE("%p, size from %d,%d to %d,%d\n", hwnd, fodInfos->sizedlg.cx, fodInfos->sizedlg.cy,
rc.right -rc.left, rc.bottom -rc.top);
/* not initialized yet */
if( (fodInfos->sizedlg.cx == 0 && fodInfos->sizedlg.cy == 0) ||
* move to bottom */
switch( ctrlid)
{
- /* file name box and file types combo change also width */
+ /* file name (edit or comboboxex) and file types combo change also width */
case edt1:
+ case cmb13:
case cmb1:
DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
rc.right - rc.left + chgx, rc.bottom - rc.top,
rc.bottom - rc.top + chgy,
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
break;
+ case IDC_TOOLBARPLACES:
+ DeferWindowPos( hdwp, ctrl, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top + chgy,
+ SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+ break;
}
}
}
int gripx = GetSystemMetrics( SM_CYHSCROLL);
int gripy = GetSystemMetrics( SM_CYVSCROLL);
- /* Adds the FileOpenDlgInfos in the property list of the dialog
- so it will be easily accessible through a GetPropA(...) */
- SetPropA(hwnd, FileOpenDlgInfosStr, fodInfos);
+ /* Some shell namespace extensions depend on COM being initialized. */
+ if (SUCCEEDED(OleInitialize(NULL)))
+ fodInfos->ole_initialized = TRUE;
+
+ SetPropW(hwnd, filedlg_info_propnameW, fodInfos);
FILEDLG95_InitControls(hwnd);
if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
{
- GetWindowRect( hwnd, &rc);
+ DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+ DWORD ex_style = GetWindowLongW(hwnd, GWL_EXSTYLE);
+ RECT client, client_adjusted;
+
+ if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
+ {
+ style |= WS_SIZEBOX;
+ ex_style |= WS_EX_WINDOWEDGE;
+ }
+ else
+ style &= ~WS_SIZEBOX;
+ SetWindowLongW(hwnd, GWL_STYLE, style);
+ SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style);
+
+ GetClientRect( hwnd, &client );
+ GetClientRect( hwnd, &client_adjusted );
+ AdjustWindowRectEx( &client_adjusted, style, FALSE, ex_style );
+
+ GetWindowRect( hwnd, &rc );
+ rc.right += client_adjusted.right - client.right;
+ rc.bottom += client_adjusted.bottom - client.bottom;
+ SetWindowPos(hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED | SWP_NOACTIVATE |
+ SWP_NOZORDER | SWP_NOMOVE);
+
+ GetWindowRect( hwnd, &rc );
fodInfos->DlgInfos.hwndGrip =
CreateWindowExA( 0, "SCROLLBAR", NULL,
WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
case WM_DESTROY:
{
- FileOpenDlgInfos * fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ 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;
- RemovePropA(hwnd, FileOpenDlgInfosStr);
+
+ if (places_bar)
+ {
+ himl = (HIMAGELIST)SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_GETIMAGELIST, 0, 0);
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0);
+ ImageList_Destroy(himl);
+ }
return FALSE;
}
+
+ case WM_NCDESTROY:
+ RemovePropW(hwnd, filedlg_info_propnameW);
+ return 0;
+
case WM_NOTIFY:
{
LPNMHDR lpnmh = (LPNMHDR)lParam;
}
}
+static inline BOOL filename_is_edit( const FileOpenDlgInfos *info )
+{
+ return (info->ofnInfos->lStructSize == OPENFILENAME_SIZE_VERSION_400W) &&
+ (info->ofnInfos->Flags & (OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE));
+}
+
/***********************************************************************
* FILEDLG95_InitControls
*
*/
static LRESULT FILEDLG95_InitControls(HWND hwnd)
{
- int win2000plus = 0;
- int win98plus = 0;
- int handledPath = FALSE;
+ BOOL win2000plus = FALSE;
+ BOOL win98plus = FALSE;
+ BOOL handledPath = FALSE;
OSVERSIONINFOW osVi;
static const WCHAR szwSlash[] = { '\\', 0 };
static const WCHAR szwStar[] = { '*',0 };
RECT rectlook;
HIMAGELIST toolbarImageList;
- SHFILEINFOA shFileInfo;
ITEMIDLIST *desktopPidl;
+ SHFILEINFOW fileinfo;
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("%p\n", fodInfos);
}
TRACE("Running on 2000+ %d, 98+ %d\n", win2000plus, win98plus);
+
+ /* Use either the edit or the comboboxex for the filename control */
+ if (filename_is_edit( fodInfos ))
+ {
+ DestroyWindow( GetDlgItem( hwnd, cmb13 ) );
+ fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, edt1 );
+ }
+ else
+ {
+ DestroyWindow( GetDlgItem( hwnd, edt1 ) );
+ fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, cmb13 );
+ }
+
/* Get the hwnd of the controls */
- fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
if (fodInfos->unicode)
fodInfos->DlgInfos.hwndTB = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
- WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
+ WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE,
rectTB.left, rectTB.top,
rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
else
fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL,
- WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
+ WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE,
rectTB.left, rectTB.top,
rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
/* 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))
+ {
+ 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);
+
+ filedlg_collect_places_pidls(fodInfos);
+ for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
+ {
+ int index;
+
+ if (!fodInfos->places[i])
+ continue;
+
+ memset(&fileinfo, 0, sizeof(fileinfo));
+ SHGetFileInfoW((const WCHAR *)fodInfos->places[i], 0, &fileinfo, sizeof(fileinfo),
+ SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON);
+ index = ImageList_AddIcon(himl, fileinfo.hIcon);
+
+ tb.iBitmap = index;
+ tb.iString = (INT_PTR)fileinfo.szDisplayName;
+ tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
+ tb.idCommand = TBPLACES_CMDID_PLACE0 + i;
+ SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_ADDBUTTONSW, 1, (LPARAM)&tb);
+
+ DestroyIcon(fileinfo.hIcon);
+ }
+
+ 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)
{
else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
{
WCHAR buf[64];
- LoadStringW(COMDLG32_hInstance, IDS_SAVE_AS, buf, sizeof(buf)/sizeof(WCHAR));
+ LoadStringW(COMDLG32_hInstance, IDS_SAVE_AS, buf, ARRAY_SIZE(buf));
SetWindowTextW(hwnd, buf);
}
result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit);
if (result) {
- /* nameBit is always shorter than the original filename */
- lstrcpyW(fodInfos->filename,nameBit);
+ /* nameBit is always shorter than the original filename. It may be NULL
+ * when the filename contains only a drive name instead of file name */
+ if (nameBit)
+ {
+ lstrcpyW(fodInfos->filename,nameBit);
+ *nameBit = 0x00;
+ }
+ else
+ *fodInfos->filename = '\0';
- *nameBit = 0x00;
- MemFree(fodInfos->initdir);
- fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
lstrcpyW(fodInfos->initdir, tmpBuf);
handledPath = TRUE;
TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n",
debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
}
- SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+ SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
} else {
- SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+ SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
}
}
/* 2. (All platforms) If initdir is not null, then use it */
- if ((handledPath == FALSE) && (fodInfos->initdir!=NULL) &&
- (*fodInfos->initdir!=0x00))
+ if (!handledPath && fodInfos->initdir && *fodInfos->initdir)
{
- /* Work out the proper path as supplied one might be relative */
- /* (Here because supplying '.' as dir browses to My Computer) */
- if (handledPath==FALSE) {
- WCHAR tmpBuf[MAX_PATH];
- WCHAR tmpBuf2[MAX_PATH];
- WCHAR *nameBit;
- DWORD result;
-
- lstrcpyW(tmpBuf, fodInfos->initdir);
- if( PathFileExistsW(tmpBuf) ) {
- /* initdir does not have to be a directory. If a file is
- * specified, the dir part is taken */
- if( PathIsDirectoryW(tmpBuf)) {
- if (tmpBuf[lstrlenW(tmpBuf)-1] != '\\') {
- lstrcatW(tmpBuf, szwSlash);
- }
- lstrcatW(tmpBuf, szwStar);
- }
- result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
- if (result) {
- *nameBit = 0x00;
- MemFree(fodInfos->initdir);
- fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf2) + 1)*sizeof(WCHAR));
- lstrcpyW(fodInfos->initdir, tmpBuf2);
- handledPath = TRUE;
- TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
- }
- }
- else if (fodInfos->initdir)
- {
- MemFree(fodInfos->initdir);
- fodInfos->initdir = NULL;
- TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
+ /* Work out the proper path as supplied one might be relative */
+ /* (Here because supplying '.' as dir browses to My Computer) */
+ WCHAR tmpBuf[MAX_PATH];
+ WCHAR tmpBuf2[MAX_PATH];
+ WCHAR *nameBit;
+ DWORD result;
+
+ lstrcpyW(tmpBuf, fodInfos->initdir);
+ if (PathFileExistsW(tmpBuf)) {
+ /* initdir does not have to be a directory. If a file is
+ * specified, the dir part is taken */
+ if (PathIsDirectoryW(tmpBuf)) {
+ PathAddBackslashW(tmpBuf);
+ lstrcatW(tmpBuf, szwStar);
+ }
+ result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
+ if (result) {
+ *nameBit = 0x00;
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf2) + 1) * sizeof(WCHAR));
+ lstrcpyW(fodInfos->initdir, tmpBuf2);
+ handledPath = TRUE;
+ TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
+ }
+ }
+ else if (fodInfos->initdir)
+ {
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = NULL;
+ TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
+ }
+ }
+
+#ifdef __REACTOS__
+ if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
+ {
+ /* 2.5. Win2000+: Recently used defext */
+ if (win2000plus) {
+ fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
+ fodInfos->initdir[0] = '\0';
+
+ FILEDLG95_MRU_load_ext(fodInfos->initdir, MAX_PATH, fodInfos->defext);
+
+ if (fodInfos->initdir[0] && PathIsDirectoryW(fodInfos->initdir)) {
+ handledPath = TRUE;
+ } else {
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = NULL;
}
}
}
+#endif
- if ((handledPath == FALSE) && ((fodInfos->initdir==NULL) ||
- (*fodInfos->initdir==0x00)))
+ if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
{
/* 3. All except w2k+: if filename contains a path use it */
if (!win2000plus && fodInfos->filename &&
*nameBit = 0x00;
len = lstrlenW(tmpBuf);
- MemFree(fodInfos->initdir);
- fodInfos->initdir = MemAlloc((len+1)*sizeof(WCHAR));
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = heap_alloc((len+1)*sizeof(WCHAR));
lstrcpyW(fodInfos->initdir, tmpBuf);
handledPath = TRUE;
TRACE("Value in Filename includes path, overriding initdir: %s, %s\n",
debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
}
- SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+ SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
}
/* 4. Win2000+: Recently used */
- if (handledPath == FALSE && win2000plus) {
- fodInfos->initdir = MemAlloc(MAX_PATH * sizeof(WCHAR));
+ if (!handledPath && win2000plus) {
+ fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
fodInfos->initdir[0] = '\0';
FILEDLG95_MRU_load_filename(fodInfos->initdir);
if (fodInfos->initdir[0] && PathFileExistsW(fodInfos->initdir)){
handledPath = TRUE;
}else{
- MemFree(fodInfos->initdir);
+ heap_free(fodInfos->initdir);
fodInfos->initdir = NULL;
}
}
/* 5. win98+ and win2000+ if any files of specified filter types in
current directory, use it */
- if ( win98plus && handledPath == FALSE &&
- fodInfos->filter && *fodInfos->filter) {
+ if (win98plus && !handledPath && fodInfos->filter && *fodInfos->filter) {
LPCWSTR lpstrPos = fodInfos->filter;
WIN32_FIND_DATAW FindFileData;
} else {
- MemFree(fodInfos->initdir);
- fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+ heap_free(fodInfos->initdir);
+ fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
handledPath = TRUE;
}
/* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
- if (handledPath == FALSE && (win2000plus || win98plus)) {
- fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+ if (!handledPath && (win2000plus || win98plus)) {
+ fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
- if(!COMDLG32_SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir))
+ if (SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir) == S_OK)
{
- if(!COMDLG32_SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir))
- {
- /* last fallback */
- GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
- TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
- } else {
+ if (SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir) == S_OK)
+ {
+ /* last fallback */
+ GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
+ TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
+ }
+ else
TRACE("No personal dir, using desktop instead: %s\n", debugstr_w(fodInfos->initdir));
- }
- } else {
- TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
}
+ else
+ TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
+
handledPath = TRUE;
- } else if (handledPath==FALSE) {
- fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+ } else if (!handledPath) {
+ fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
handledPath = TRUE;
TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir));
}
}
- SetFocus(GetDlgItem(hwnd, IDC_FILENAME));
+ SetFocus( fodInfos->DlgInfos.hwndFileName );
TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
/* Must the open as read only check box be checked ?*/
}
/* Must the open as read only check box be hidden? */
- if(fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY)
+ if (filedialog_is_readonly_hidden(fodInfos))
{
ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
EnableWindow(GetDlgItem(hwnd, IDC_OPENREADONLY), FALSE);
if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
{
WCHAR buf[16];
- LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, sizeof(buf)/sizeof(WCHAR));
+ LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, ARRAY_SIZE(buf));
SetDlgItemTextW(hwnd, IDOK, buf);
- LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, sizeof(buf)/sizeof(WCHAR));
+ LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, ARRAY_SIZE(buf));
SetDlgItemTextW(hwnd, IDC_LOOKINSTATIC, buf);
}
UINT flags = SWP_NOACTIVATE;
ArrangeCtrlPositions(fodInfos->DlgInfos.hwndCustomDlg, hwnd,
- (fodInfos->ofnInfos->Flags & (OFN_HIDEREADONLY | OFN_SHOWHELP)) == OFN_HIDEREADONLY);
+ filedialog_is_readonly_hidden(fodInfos) && !(fodInfos->ofnInfos->Flags & OFN_SHOWHELP));
/* resize the custom dialog to the parent size */
if (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))
flags |= SWP_NOSIZE;
SetRectEmpty(&rc);
}
- SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
- 0, 0, rc.right, rc.bottom, flags);
+ SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
+ 0, 0, rc.right, rc.bottom, flags);
}
else
{
- /* Resize the height, if open as read only checkbox ad help button are
+ /* Resize the height; if opened as read-only, checkbox and help button are
* hidden and we are not using a custom template nor a customDialog
*/
- if ( (fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY) &&
+ if (filedialog_is_readonly_hidden(fodInfos) &&
(!(fodInfos->ofnInfos->Flags &
(OFN_SHOWHELP|OFN_ENABLETEMPLATE|OFN_ENABLETEMPLATEHANDLE))))
{
/* Browse to the initial directory */
IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
- /* Free pidlItem memory */
- COMDLG32_SHFree(pidlItemId);
+ ILFree(pidlItemId);
return TRUE;
}
FILEDLG95_LOOKIN_Clean(hwnd);
FILEDLG95_SHELL_Clean(hwnd);
}
+
+
+/***********************************************************************
+ * Browse to arbitrary pidl
+ */
+static void filedlg_browse_to_pidl(const FileOpenDlgInfos *info, LPITEMIDLIST pidl)
+{
+ TRACE("%p, %p\n", info->ShellInfos.hwndOwner, pidl);
+
+ IShellBrowser_BrowseObject(info->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
+ if (info->ofnInfos->Flags & OFN_EXPLORER)
+ SendCustomDlgNotificationMessage(info->ShellInfos.hwndOwner, CDN_FOLDERCHANGE);
+}
+
/***********************************************************************
* FILEDLG95_OnWMCommand
*
*/
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 */
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ WORD id = LOWORD(wParam); /* item, control, or accelerator identifier */
- switch(wID)
+ switch (id)
{
/* OK button */
case IDOK:
case FCIDM_TB_REPORTVIEW:
FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
break;
- /* Details option button */
+
case FCIDM_TB_DESKTOP:
- FILEDLG95_SHELL_BrowseToDesktop(hwnd);
+ {
+ LPITEMIDLIST pidl;
+
+ SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidl);
+ filedlg_browse_to_pidl(fodInfos, pidl);
+ ILFree(pidl);
+ break;
+ }
+
+ /* 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 IDC_FILENAME:
+ case edt1:
+ case cmb13:
break;
}
*/
static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("\n");
static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
{
/* ask the hook if we can close */
- if(IsHooked(fodInfos))
+ if (is_dialog_hooked(fodInfos))
{
LRESULT retval = 0;
*/
BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
{
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
WCHAR lpstrPathSpec[MAX_PATH] = {0};
UINT nCount, nSizePath;
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("\n");
/* move to the next file in the list of files */
lpstrTemp += lstrlenW(lpstrTemp) + 1;
- COMDLG32_SHFree(pidl);
+ ILFree(pidl);
}
}
HKEY hkey;
/* get the current executable's name */
- if(!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, sizeof(module_path)/sizeof(module_path[0]))) {
+ if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
+ {
WARN("GotModuleFileName failed: %d\n", GetLastError());
return;
}
final_len = path_len + lstrlenW(module_name) + 2;
- final = MemAlloc(final_len * sizeof(WCHAR));
+ final = heap_alloc(final_len * sizeof(WCHAR));
if(!final)
return;
lstrcpyW(final, module_name);
final_len * sizeof(WCHAR));
if(ret){
WARN("Error saving MRU data to slot %s: %d\n", wine_dbgstr_w(slot_name), ret);
- MemFree(final);
+ heap_free(final);
RegCloseKey(hkey);
return;
}
- MemFree(final);
+ heap_free(final);
}
{ /* update MRUList value */
}
}
-/* load the most-recently-used path for this module */
-static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
+/* load the most-recently-used path for this module */
+static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
+{
+ WCHAR module_path[MAX_PATH], *module_name;
+
+ /* get the current executable's name */
+ if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
+ {
+ WARN("GotModuleFileName failed: %d\n", GetLastError());
+ return;
+ }
+ module_name = strrchrW(module_path, '\\');
+ if(!module_name)
+ module_name = module_path;
+ else
+ module_name += 1;
+
+ FILEDLG95_MRU_get_slot(module_name, stored_path, NULL);
+ TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
+}
+#ifdef __REACTOS__
+static const WCHAR s_subkey[] =
+{
+ 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s',
+ 'i','o','n','\\','E','x','p','l','o','r','e','r','\\','C','o','m','D','l','g',
+ '3','2','\\','O','p','e','n','S','a','v','e','M','R','U',0
+};
+static const WCHAR s_szAst[] = { '*', 0 };
+
+typedef INT (CALLBACK *MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs);
+typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
+
+/* https://docs.microsoft.com/en-us/windows/desktop/shell/mruinfo */
+typedef struct tagMRUINFOW
+{
+ DWORD cbSize;
+ UINT uMax;
+ UINT fFlags;
+ HKEY hKey;
+ LPCWSTR lpszSubKey;
+ union
+ {
+ MRUStringCmpFnW string_cmpfn;
+ MRUBinaryCmpFn binary_cmpfn;
+ } u;
+} MRUINFOW, *LPMRUINFOW;
+
+/* flags for MRUINFOW.fFlags */
+#define MRU_STRING 0x0000
+#define MRU_BINARY 0x0001
+#define MRU_CACHEWRITE 0x0002
+
+static HINSTANCE s_hComCtl32 = NULL;
+
+/* comctl32.400: CreateMRUListW */
+typedef HANDLE (WINAPI *CREATEMRULISTW)(const MRUINFOW *);
+static CREATEMRULISTW s_pCreateMRUListW = NULL;
+
+/* comctl32.401: AddMRUStringW */
+typedef INT (WINAPI *ADDMRUSTRINGW)(HANDLE, LPCWSTR);
+static ADDMRUSTRINGW s_pAddMRUStringW = NULL;
+
+/* comctl32.402: FindMRUStringW */
+typedef INT (WINAPI *FINDMRUSTRINGW)(HANDLE, LPCWSTR, LPINT);
+static FINDMRUSTRINGW s_pFindMRUStringW = NULL;
+
+/* comctl32.403: EnumMRUListW */
+typedef INT (WINAPI *ENUMMRULISTW)(HANDLE, INT, LPVOID, DWORD);
+static ENUMMRULISTW s_pEnumMRUListW = NULL;
+
+/* comctl32.152: FreeMRUList */
+typedef void (WINAPI *FREEMRULIST)(HANDLE);
+static FREEMRULIST s_pFreeMRUList = NULL;
+
+static BOOL FILEDLG_InitMRUList(void)
+{
+ if (s_hComCtl32)
+ return TRUE;
+
+ s_hComCtl32 = GetModuleHandleA("comctl32");
+ if (!s_hComCtl32)
+ return FALSE;
+
+ s_pCreateMRUListW = (CREATEMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)400);
+ s_pAddMRUStringW = (ADDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)401);
+ s_pFindMRUStringW = (FINDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)402);
+ s_pEnumMRUListW = (ENUMMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)403);
+ s_pFreeMRUList = (FREEMRULIST)GetProcAddress(s_hComCtl32, (LPCSTR)152);
+ if (!s_pCreateMRUListW ||
+ !s_pAddMRUStringW ||
+ !s_pFindMRUStringW ||
+ !s_pEnumMRUListW ||
+ !s_pFreeMRUList)
+ {
+ s_hComCtl32 = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL ExtIsPicture(LPCWSTR ext)
+{
+ static const WCHAR s_image_exts[][6] =
+ {
+ { 'b','m','p',0 },
+ { 'd','i','b',0 },
+ { 'j','p','g',0 },
+ { 'j','p','e','g',0 },
+ { 'j','p','e',0 },
+ { 'j','f','i','f',0 },
+ { 'p','n','g',0 },
+ { 'g','i','f',0 },
+ { 't','i','f',0 },
+ { 't','i','f','f',0 }
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(s_image_exts); ++i)
+ {
+ if (lstrcmpiW(ext, s_image_exts[i]) == 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext)
+{
+ HKEY hOpenSaveMRT = NULL;
+ LONG result;
+ MRUINFOW mi;
+ HANDLE hList;
+ WCHAR szText[MAX_PATH];
+ INT ret = 0;
+
+ stored_path[0] = 0;
+
+ if (!defext || !*defext || !FILEDLG_InitMRUList())
+ {
+ return;
+ }
+
+ if (*defext == '.')
+ ++defext;
+
+ result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
+ if (!result && hOpenSaveMRT)
+ {
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.uMax = 26;
+ mi.fFlags = MRU_STRING;
+ mi.hKey = hOpenSaveMRT;
+ mi.lpszSubKey = defext;
+ mi.u.string_cmpfn = lstrcmpiW;
+ hList = (*s_pCreateMRUListW)(&mi);
+ if (hList)
+ {
+ ret = (*s_pEnumMRUListW)(hList, 0, szText, sizeof(szText));
+ if (ret > 0)
+ {
+ lstrcpynW(stored_path, szText, cchMax);
+ PathRemoveFileSpecW(stored_path);
+ }
+ (*s_pFreeMRUList)(hList);
+ }
+
+ if (stored_path[0] == 0)
+ {
+ mi.cbSize = sizeof(mi);
+ mi.uMax = 26;
+ mi.fFlags = MRU_STRING;
+ mi.hKey = hOpenSaveMRT;
+ mi.lpszSubKey = s_szAst;
+ mi.u.string_cmpfn = lstrcmpiW;
+ hList = (*s_pCreateMRUListW)(&mi);
+ if (hList)
+ {
+ ret = (*s_pEnumMRUListW)(hList, 0, szText, sizeof(szText));
+ if (ret > 0)
+ {
+ lstrcpynW(stored_path, szText, cchMax);
+ PathRemoveFileSpecW(stored_path);
+ }
+ (*s_pFreeMRUList)(hList);
+ }
+ }
+
+ RegCloseKey(hOpenSaveMRT);
+ }
+
+ if (stored_path[0] == 0)
+ {
+ LPITEMIDLIST pidl;
+ if (ExtIsPicture(defext))
+ {
+ SHGetSpecialFolderLocation(NULL, CSIDL_MYPICTURES, &pidl);
+ }
+ else
+ {
+ SHGetSpecialFolderLocation(NULL, CSIDL_MYDOCUMENTS, &pidl);
+ }
+ SHGetPathFromIDListW(pidl, stored_path);
+ ILFree(pidl);
+ }
+}
+
+static void FILEDLG95_MRU_save_ext(LPCWSTR filename)
{
- WCHAR module_path[MAX_PATH], *module_name;
+ HKEY hOpenSaveMRT = NULL;
+ LONG result;
+ MRUINFOW mi;
+ HANDLE hList;
+ LPCWSTR defext = PathFindExtensionW(filename);
- /* get the current executable's name */
- if(!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, sizeof(module_path)/sizeof(module_path[0]))) {
- WARN("GotModuleFileName failed: %d\n", GetLastError());
+ if (!defext || !*defext || !FILEDLG_InitMRUList())
+ {
return;
}
- module_name = strrchrW(module_path, '\\');
- if(!module_name)
- module_name = module_path;
- else
- module_name += 1;
- FILEDLG95_MRU_get_slot(module_name, stored_path, NULL);
- TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
+ if (*defext == '.')
+ ++defext;
+
+ result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
+ if (!result && hOpenSaveMRT)
+ {
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.uMax = 26;
+ mi.fFlags = MRU_STRING;
+ mi.hKey = hOpenSaveMRT;
+ mi.lpszSubKey = defext;
+ mi.u.string_cmpfn = lstrcmpiW;
+ hList = (*s_pCreateMRUListW)(&mi);
+ if (hList)
+ {
+ (*s_pAddMRUStringW)(hList, filename);
+ (*s_pFreeMRUList)(hList);
+ }
+
+ mi.cbSize = sizeof(mi);
+ mi.uMax = 26;
+ mi.fFlags = MRU_STRING;
+ mi.hKey = hOpenSaveMRT;
+ mi.lpszSubKey = s_szAst;
+ mi.u.string_cmpfn = lstrcmpiW;
+ hList = (*s_pCreateMRUListW)(&mi);
+ if (hList)
+ {
+ (*s_pAddMRUStringW)(hList, filename);
+ (*s_pFreeMRUList)(hList);
+ }
+
+ RegCloseKey(hOpenSaveMRT);
+ }
}
+#endif
void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
{
WCHAR strMsgTitle[MAX_PATH];
WCHAR strMsgText [MAX_PATH];
if (idCaption)
- LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, sizeof(strMsgTitle)/sizeof(WCHAR));
+ LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, ARRAY_SIZE(strMsgTitle));
else
strMsgTitle[0] = '\0';
- LoadStringW(COMDLG32_hInstance, idText, strMsgText, sizeof(strMsgText)/sizeof(WCHAR));
+ LoadStringW(COMDLG32_hInstance, idText, strMsgText, ARRAY_SIZE(strMsgText));
MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
}
nOpenAction = ONOPEN_OPEN;
break;
}
- COMDLG32_SHFree(pidl);
+ ILFree(pidl);
pidl = NULL;
}
else if (!(flags & OFN_NOVALIDATE))
break;
}
}
- if(pidl) COMDLG32_SHFree(pidl);
+ ILFree(pidl);
return nOpenAction;
}
*/
BOOL FILEDLG95_OnOpen(HWND hwnd)
{
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
LPWSTR lpstrFileList;
UINT nFileCount = 0;
UINT sizeUsed = 0;
WCHAR lpstrPathAndFile[MAX_PATH];
LPSHELLFOLDER lpsf = NULL;
int nOpenAction;
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("hwnd=%p\n", hwnd);
*/
COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile);
- MemFree(lpstrFileList);
+ heap_free(lpstrFileList);
/*
Step 2: here we have a cleaned up path
DWORD len;
/* replace the current filter */
- MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
+ heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
len = lstrlenW(lpszTemp)+1;
- fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc(len * sizeof(WCHAR));
+ fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc(len * sizeof(WCHAR));
lstrcpyW( fodInfos->ShellInfos.lpstrCurrentFilter, lpszTemp);
/* set the filter cb to the extension when possible */
if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB, lpszTemp)))
- CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, iPos);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, iPos, 0);
}
/* fall through */
case ONOPEN_BROWSE: /* browse to the highest folder we could bind to */
LPITEMIDLIST pidlCurrent;
IPersistFolder2_GetCurFolder(ppf2, &pidlCurrent);
IPersistFolder2_Release(ppf2);
- if( ! COMDLG32_PIDL_ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
+ if (!ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
{
if (SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidlCurrent, SBSP_ABSOLUTE))
&& fodInfos->ofnInfos->Flags & OFN_EXPLORER)
{
SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE);
+ SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_SETTEXT, 0, (LPARAM)"");
}
}
else if( nOpenAction == ONOPEN_SEARCH )
if (fodInfos->Shell.FOIShellView)
IShellView_Refresh(fodInfos->Shell.FOIShellView);
}
- COMDLG32_SHFree(pidlCurrent);
- SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+ ILFree(pidlCurrent);
+ if (filename_is_edit( fodInfos ))
+ SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+ else
+ {
+ HWND hwnd;
+
+ hwnd = (HWND)SendMessageA(fodInfos->DlgInfos.hwndFileName, CBEM_GETEDITCONTROL, 0, 0);
+ SendMessageW(hwnd, EM_SETSEL, 0, -1);
+ }
}
}
ret = FALSE;
/* Attach the file extension with file name*/
ext = PathFindExtensionW(lpstrPathAndFile);
- if (! *ext)
+ if (! *ext && fodInfos->defext)
{
/* if no extension is specified with file name, then */
/* attach the extension from file filter or default one */
- const WCHAR *filterExt = NULL;
+ WCHAR *filterExt = NULL;
LPWSTR lpstrFilter = NULL;
static const WCHAR szwDot[] = {'.',0};
int PathLength = lstrlenW(lpstrPathAndFile);
fodInfos->ofnInfos->nFilterIndex-1);
if (lpstrFilter != (LPWSTR)CB_ERR) /* control is not empty */
- filterExt = PathFindExtensionW(lpstrFilter);
+ {
+ WCHAR* filterSearchIndex;
+ filterExt = heap_alloc((lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR));
+ strcpyW(filterExt, lpstrFilter);
+
+ /* if a semicolon-separated list of file extensions was given, do not include the
+ semicolon or anything after it in the extension.
+ example: if filterExt was "*.abc;*.def", it will become "*.abc" */
+ filterSearchIndex = strchrW(filterExt, ';');
+ if (filterSearchIndex)
+ {
+ filterSearchIndex[0] = '\0';
+ }
+
+ /* find the file extension by searching for the first dot in filterExt */
+ /* strip the * or anything else from the extension, "*.abc" becomes "abc" */
+ /* if the extension is invalid or contains a glob, ignore it */
+ filterSearchIndex = strchrW(filterExt, '.');
+ if (filterSearchIndex++ && !strchrW(filterSearchIndex, '*') && !strchrW(filterSearchIndex, '?'))
+ {
+ strcpyW(filterExt, filterSearchIndex);
+ }
+ else
+ {
+ heap_free(filterExt);
+ filterExt = NULL;
+ }
+ }
- if ( filterExt && *filterExt ) /* attach the file extension from file type filter*/
- filterExt = filterExt + 1;
- else if ( fodInfos->defext ) /* attach the default file extension*/
- filterExt = fodInfos->defext;
+ if (!filterExt)
+ {
+ /* use the default file extension */
+ filterExt = heap_alloc((lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
+ strcpyW(filterExt, fodInfos->defext);
+ }
- /* If extension contains a glob, ignore it */
- if ( filterExt && !strchrW(filterExt, '*') && !strchrW(filterExt, '?') )
+ if (*filterExt) /* ignore filterExt="" */
{
/* Attach the dot*/
lstrcatW(lpstrPathAndFile, szwDot);
/* Attach the extension */
- lstrcatW(lpstrPathAndFile, filterExt );
+ lstrcatW(lpstrPathAndFile, filterExt);
}
+ heap_free(filterExt);
+
/* In Open dialog: if file does not exist try without extension */
if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
lpstrPathAndFile[PathLength] = '\0';
- }
- if (fodInfos->defext) /* add default extension */
- {
- /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
- if (*ext)
- ext++;
- if (!lstrcmpiW(fodInfos->defext, ext))
- fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
- else
- fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
+ /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
+ if (*ext)
+ ext++;
+ if (!lstrcmpiW(fodInfos->defext, ext))
+ fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
+ else
+ fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
}
/* In Save dialog: check if the file already exists */
}
else
{
- LPSTR lpszTemp;
- LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
+ LPSTR lpszTemp;
+ CHAR tempFileA[MAX_PATH];
+
+ /* avoid using fodInfos->ofnInfos->lpstrFile since it can be NULL */
+ WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1,
+ tempFileA, sizeof(tempFileA), NULL, NULL);
/* set filename offset */
- lpszTemp = PathFindFileNameA(ofn->lpstrFile);
- fodInfos->ofnInfos->nFileOffset = (lpszTemp - ofn->lpstrFile);
+ lpszTemp = PathFindFileNameA(tempFileA);
+ fodInfos->ofnInfos->nFileOffset = (lpszTemp - tempFileA);
/* set extension offset */
- lpszTemp = PathFindExtensionA(ofn->lpstrFile);
- fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - ofn->lpstrFile) + 1 : 0;
+ lpszTemp = PathFindExtensionA(tempFileA);
+ fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - tempFileA) + 1 : 0;
}
- /* set the lpstrFileTitle */
- if(fodInfos->ofnInfos->lpstrFileTitle)
- {
- LPWSTR lpstrFileTitle = PathFindFileNameW(lpstrPathAndFile);
- if(fodInfos->unicode)
- {
- LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
- lstrcpynW(ofn->lpstrFileTitle, lpstrFileTitle, ofn->nMaxFileTitle);
- }
- else
- {
- LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
- WideCharToMultiByte(CP_ACP, 0, lpstrFileTitle, -1,
- ofn->lpstrFileTitle, ofn->nMaxFileTitle, NULL, NULL);
- }
- }
-
/* copy currently selected filter to lpstrCustomFilter */
if (fodInfos->ofnInfos->lpstrCustomFilter)
{
goto ret;
FILEDLG95_MRU_save_filename(lpstrPathAndFile);
+#ifdef __REACTOS__
+ FILEDLG95_MRU_save_ext(lpstrPathAndFile);
+#endif
TRACE("close\n");
FILEDLG95_Clean(hwnd);
if (fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT)
size += 1;
/* return needed size in first two bytes of lpstrFile */
- *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
+ if(fodInfos->ofnInfos->lpstrFile)
+ *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
FILEDLG95_Clean(hwnd);
ret = EndDialog(hwnd, FALSE);
COMDLG32_SetCommDlgExtendedError(FNERR_BUFFERTOOSMALL);
*/
static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
- TRACE("\n");
+ TRACE("%p\n", hwnd);
/*
* Initialisation of the FileOpenDialogInfos structure
*/
static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
IContextMenu * pcm;
TRACE("(%p,%p)\n", hwnd, lpVerb);
*/
static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("\n");
}
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 = GetPropA(hwnd,FileOpenDlgInfosStr);
- 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
*
*/
static void FILEDLG95_SHELL_Clean(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("\n");
- COMDLG32_SHFree(fodInfos->ShellInfos.pidlAbsCurrent);
+ ILFree(fodInfos->ShellInfos.pidlAbsCurrent);
/* clean Shell interfaces */
if (fodInfos->Shell.FOIShellView)
IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
IShellView_Release(fodInfos->Shell.FOIShellView);
}
- IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
+ if (fodInfos->Shell.FOIShellFolder)
+ IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
if (fodInfos->Shell.FOIDataObject)
IDataObject_Release(fodInfos->Shell.FOIDataObject);
*/
static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
int nFilters = 0; /* number of filters */
int nFilterIndexCB;
- TRACE("\n");
+ TRACE("%p\n", hwnd);
if(fodInfos->customfilter)
{
/* Copy the extensions */
if (! *lpstrPos) return E_FAIL; /* malformed filter */
- if (!(lpstrExt = MemAlloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
+ if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
lstrcpyW(lpstrExt,lpstrPos);
/* Add the item at the end of the combo */
- CBAddString(fodInfos->DlgInfos.hwndFileTypeCB, fodInfos->customfilter);
- CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, nFilters, lpstrExt);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)fodInfos->customfilter);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters, (LPARAM)lpstrExt);
+
nFilters++;
}
if(fodInfos->filter)
lpstrDisplay = lpstrPos;
lpstrPos += lstrlenW(lpstrPos) + 1;
- CBAddString(fodInfos->DlgInfos.hwndFileTypeCB, lpstrDisplay);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)lpstrDisplay);
nFilters++;
/* Copy the extensions */
- if (!(lpstrExt = MemAlloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
+ if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
lstrcpyW(lpstrExt,lpstrPos);
lpstrPos += lstrlenW(lpstrPos) + 1;
/* Add the item at the end of the combo */
- CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, nFilters-1, lpstrExt);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters - 1, (LPARAM)lpstrExt);
/* malformed filters are added anyway... */
if (!*lpstrExt) break;
nFilterIndexCB--;
/* Set the current index selection. */
- CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, nFilterIndexCB);
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, nFilterIndexCB, 0);
/* Get the corresponding text string from the combo box. */
lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
DWORD len;
CharLowerW(lpstrFilter); /* lowercase */
len = lstrlenW(lpstrFilter)+1;
- fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc( len * sizeof(WCHAR) );
+ fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
}
} else
*/
static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
switch(wNotifyCode)
{
LPWSTR lpstrFilter;
/* Get the current item of the filetype combo box */
- int iItem = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
+ int iItem = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCURSEL, 0, 0);
/* set the current filter index */
fodInfos->ofnInfos->nFilterIndex = iItem +
(fodInfos->customfilter == NULL ? 1 : 0);
/* Set the current filter with the current selection */
- MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
+ heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
iItem);
DWORD len;
CharLowerW(lpstrFilter); /* lowercase */
len = lstrlenW(lpstrFilter)+1;
- fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc( len * sizeof(WCHAR) );
+ fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
SendCustomDlgNotificationMessage(hwnd,CDN_TYPECHANGE);
*/
static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt)
{
- int i, iCount = CBGetCount(hwnd);
+ int i, iCount;
+
+ iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
TRACE("%s\n", debugstr_w(lpstrExt));
*/
static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
int iPos;
- int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
+ int iCount;
+
+ iCount = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCOUNT, 0, 0);
TRACE("\n");
{
for(iPos = iCount-1;iPos>=0;iPos--)
{
- MemFree((LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
- CBDeleteString(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
+ heap_free((void *)CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
+ SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_DELETESTRING, iPos, 0);
}
}
/* Current filter */
- MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
-
+ heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
}
/***********************************************************************
IShellFolder *psfRoot, *psfDrives;
IEnumIDList *lpeRoot, *lpeDrives;
LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
+ HDC hdc;
+ TEXTMETRICW tm;
+ LookInInfos *liInfos = heap_alloc_zero(sizeof(*liInfos));
- LookInInfos *liInfos = MemAlloc(sizeof(LookInInfos));
-
- TRACE("\n");
+ TRACE("%p\n", hwndCombo);
liInfos->iMaxIndentation = 0;
SetPropA(hwndCombo, LookInInfosStr, liInfos);
+ hdc = GetDC( hwndCombo );
+ SelectObject( hdc, (HFONT)SendMessageW( hwndCombo, WM_GETFONT, 0, 0 ));
+ GetTextMetricsW( hdc, &tm );
+ ReleaseDC( hwndCombo, hdc );
+
/* set item height for both text field and listbox */
- CBSetItemHeight(hwndCombo,-1,GetSystemMetrics(SM_CYSMICON));
- CBSetItemHeight(hwndCombo,0,GetSystemMetrics(SM_CYSMICON));
-
+ SendMessageW(hwndCombo, CB_SETITEMHEIGHT, -1, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
+ SendMessageW(hwndCombo, CB_SETITEMHEIGHT, 0, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
+
/* Turn on the extended UI for the combo box like Windows does */
- CBSetExtendedUI(hwndCombo, TRUE);
+ SendMessageW(hwndCombo, CB_SETEXTENDEDUI, TRUE, 0);
/* Initialise data of Desktop folder */
SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp);
FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
- COMDLG32_SHFree(pidlTmp);
+ ILFree(pidlTmp);
SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives);
if (!FILEDLG95_unixfs_is_rooted_at_desktop())
{
/* special handling for CSIDL_DRIVES */
- if (COMDLG32_PIDL_ILIsEqual(pidlTmp, pidlDrives))
+ if (ILIsEqual(pidlTmp, pidlDrives))
{
if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
{
{
while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
{
- pidlAbsTmp = COMDLG32_PIDL_ILCombine(pidlTmp, pidlTmp1);
+ pidlAbsTmp = ILCombine(pidlTmp, pidlTmp1);
FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
- COMDLG32_SHFree(pidlAbsTmp);
- COMDLG32_SHFree(pidlTmp1);
+ ILFree(pidlAbsTmp);
+ ILFree(pidlTmp1);
}
IEnumIDList_Release(lpeDrives);
}
}
}
- COMDLG32_SHFree(pidlTmp);
+ ILFree(pidlTmp);
}
IEnumIDList_Release(lpeRoot);
}
IShellFolder_Release(psfRoot);
}
- COMDLG32_SHFree(pidlDrives);
+ ILFree(pidlDrives);
}
/***********************************************************************
int iIndentation;
TEXTMETRICW tm;
LPSFOLDER tmpFolder;
- LookInInfos *liInfos = GetPropA(pDIStruct->hwndItem,LookInInfosStr);
+ UINT shgfi_flags = SHGFI_PIDL | SHGFI_OPENICON | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME;
+ UINT icon_width, icon_height;
TRACE("\n");
return 0;
- if(pDIStruct->itemID == liInfos->uSelectedItem)
- {
- ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
- 0,
- &sfi,
- sizeof (sfi),
- SHGFI_PIDL | SHGFI_SMALLICON |
- SHGFI_OPENICON | SHGFI_SYSICONINDEX |
- SHGFI_DISPLAYNAME );
- }
- else
+ icon_width = GetSystemMetrics(SM_CXICON);
+ icon_height = GetSystemMetrics(SM_CYICON);
+ if (pDIStruct->rcItem.bottom - pDIStruct->rcItem.top < icon_height)
{
- ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
- 0,
- &sfi,
- sizeof (sfi),
- SHGFI_PIDL | SHGFI_SMALLICON |
- SHGFI_SYSICONINDEX |
- SHGFI_DISPLAYNAME);
+ icon_width = GetSystemMetrics(SM_CXSMICON);
+ icon_height = GetSystemMetrics(SM_CYSMICON);
+ shgfi_flags |= SHGFI_SMALLICON;
}
+ ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
+ 0, &sfi, sizeof (sfi), shgfi_flags );
+
/* Is this item selected ? */
if(pDIStruct->itemState & ODS_SELECTED)
{
/* Do not indent item if drawing in the edit of the combo */
if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
- {
iIndentation = 0;
- ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
- 0,
- &sfi,
- sizeof (sfi),
- SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON
- | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME );
-
- }
else
- {
iIndentation = tmpFolder->m_iIndent;
- }
+
/* Draw text and icon */
/* Initialise the icon display area */
- rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
- rectIcon.top = pDIStruct->rcItem.top;
- rectIcon.right = rectIcon.left + ICONWIDTH;
- rectIcon.bottom = pDIStruct->rcItem.bottom;
+ rectIcon.left = pDIStruct->rcItem.left + 1 + icon_width/2 * iIndentation;
+ rectIcon.top = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - icon_height) / 2;
+ rectIcon.right = rectIcon.left + icon_width + XTEXTOFFSET;
+ rectIcon.bottom = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + icon_height) / 2;
/* Initialise the text display area */
GetTextMetricsW(pDIStruct->hDC, &tm);
rectText.left = rectIcon.right;
rectText.top =
(pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - tm.tmHeight) / 2;
- rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
+ rectText.right = pDIStruct->rcItem.right;
rectText.bottom =
(pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + tm.tmHeight) / 2;
*/
static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
TRACE("%p\n", fodInfos);
LPSFOLDER tmpFolder;
int iItem;
- iItem = CBGetCurSel(fodInfos->DlgInfos.hwndLookInCB);
+ iItem = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCURSEL, 0, 0);
if( iItem == CB_ERR) return FALSE;
SFOLDER *tmpFolder;
LookInInfos *liInfos;
- TRACE("%08x\n", iInsertId);
+ TRACE("%p, %p, %d\n", hwnd, pidl, iInsertId);
if(!pidl)
return -1;
if(!(liInfos = GetPropA(hwnd,LookInInfosStr)))
return -1;
- tmpFolder = MemAlloc(sizeof(SFOLDER));
+ tmpFolder = heap_alloc_zero(sizeof(*tmpFolder));
tmpFolder->m_iIndent = 0;
/* Calculate the indentation of the item in the lookin*/
pidlNext = pidl;
- while( (pidlNext=COMDLG32_PIDL_ILGetNext(pidlNext)) )
+ while ((pidlNext = ILGetNext(pidlNext)))
{
tmpFolder->m_iIndent++;
}
- tmpFolder->pidlItem = COMDLG32_PIDL_ILClone(pidl);
+ tmpFolder->pidlItem = ILClone(pidl);
if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
liInfos->iMaxIndentation = tmpFolder->m_iIndent;
0,
&sfi,
sizeof(sfi),
- SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX
- | SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED);
+ SHGFI_DISPLAYNAME | SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED);
- TRACE("-- Add %s attr=%08x\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes);
+ TRACE("-- Add %s attr=0x%08x\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes);
if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
{
/* Add the item at the end of the list */
if(iInsertId < 0)
{
- iItemID = CBAddString(hwnd,sfi.szDisplayName);
+ iItemID = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)sfi.szDisplayName);
}
/* Insert the item at the iInsertId position*/
else
{
- iItemID = CBInsertString(hwnd,sfi.szDisplayName,iInsertId);
+ iItemID = SendMessageW(hwnd, CB_INSERTSTRING, iInsertId, (LPARAM)sfi.szDisplayName);
}
- CBSetItemDataPtr(hwnd,iItemID,tmpFolder);
+ SendMessageW(hwnd, CB_SETITEMDATA, iItemID, (LPARAM)tmpFolder);
return iItemID;
}
- COMDLG32_SHFree( tmpFolder->pidlItem );
- MemFree( tmpFolder );
+ ILFree( tmpFolder->pidlItem );
+ heap_free( tmpFolder );
return -1;
}
iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
}
- /* Free pidlParent memory */
- COMDLG32_SHFree(pidlParent);
+ ILFree(pidlParent);
return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
}
int iItemPos;
LookInInfos *liInfos;
- TRACE("\n");
+ TRACE("%p, %p\n", hwnd, pidl);
iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
}
}
- CBSetCurSel(hwnd,iItemPos);
+ SendMessageW(hwnd, CB_SETCURSEL, iItemPos, 0);
liInfos->uSelectedItem = iItemPos;
return 0;
if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
{
SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
- COMDLG32_SHFree(tmpFolder->pidlItem);
- MemFree(tmpFolder);
- CBDeleteString(hwnd,iItemPos);
+ ILFree(tmpFolder->pidlItem);
+ heap_free(tmpFolder);
+ SendMessageW(hwnd, CB_DELETESTRING, iItemPos, 0);
liInfos->iMaxIndentation--;
return iItemPos;
static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
{
int i = 0;
- int iCount = CBGetCount(hwnd);
+ int iCount;
+
+ iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
TRACE("0x%08lx 0x%x\n",searchArg, iSearchMethod);
{
LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
- if(iSearchMethod == SEARCH_PIDL && COMDLG32_PIDL_ILIsEqual((LPITEMIDLIST)searchArg,tmpFolder->pidlItem))
+ if (iSearchMethod == SEARCH_PIDL && ILIsEqual((LPITEMIDLIST)searchArg, tmpFolder->pidlItem))
return i;
if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
return i;
*/
static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
- int iPos;
- int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
+ int iPos, iCount;
+
+ iCount = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCOUNT, 0, 0);
TRACE("\n");
for(iPos = iCount-1;iPos>=0;iPos--)
{
SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos);
- COMDLG32_SHFree(tmpFolder->pidlItem);
- MemFree(tmpFolder);
- CBDeleteString(fodInfos->DlgInfos.hwndLookInCB,iPos);
+ ILFree(tmpFolder->pidlItem);
+ heap_free(tmpFolder);
+ SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_DELETESTRING, iPos, 0);
}
}
/* LookInInfos structure */
- MemFree(liInfos);
+ heap_free(liInfos);
RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
}
+/***********************************************************************
+ * get_def_format
+ *
+ * Fill the FORMATETC used in the shell id list
+ */
+static FORMATETC get_def_format(void)
+{
+ static CLIPFORMAT cfFormat;
+ FORMATETC formatetc;
+
+ if (!cfFormat) cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLISTA);
+ formatetc.cfFormat = cfFormat;
+ formatetc.ptd = 0;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.lindex = -1;
+ formatetc.tymed = TYMED_HGLOBAL;
+ return formatetc;
+}
+
/***********************************************************************
* FILEDLG95_FILENAME_FillFromSelection
*
*/
void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
{
- FileOpenDlgInfos *fodInfos;
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
LPITEMIDLIST pidl;
- UINT nFiles = 0, nFileToOpen, nFileSelected, nLength = 0;
- WCHAR lpstrTemp[MAX_PATH];
- LPWSTR lpstrAllFile, lpstrCurrFile;
+ LPWSTR lpstrAllFiles, lpstrTmp;
+ UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength;
+ STGMEDIUM medium;
+ LPIDA cida;
+ FORMATETC formatetc = get_def_format();
TRACE("\n");
- fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
-
- /* Count how many files we have */
- nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
-
- /* calculate the string length, count files */
- if (nFileSelected >= 1)
- {
- nLength += 3; /* first and last quotes, trailing \0 */
- for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
- {
- pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
- if (pidl)
- {
- /* get the total length of the selected file names */
- lpstrTemp[0] = '\0';
- GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+ if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium)))
+ return;
- if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */
- {
- nLength += lstrlenW( lpstrTemp ) + 3;
- nFiles++;
- }
- COMDLG32_SHFree( pidl );
- }
- }
- }
+ cida = GlobalLock(medium.u.hGlobal);
+ nFileSelected = cida->cidl;
- /* allocate the buffer */
- if (nFiles <= 1) nLength = MAX_PATH;
- lpstrAllFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
+ /* Allocate a buffer */
+ nAllFilesMaxLength = MAX_PATH + 3;
+ lpstrAllFiles = heap_alloc_zero(nAllFilesMaxLength * sizeof(WCHAR));
+ if (!lpstrAllFiles)
+ goto ret;
- /* Generate the string for the edit control */
- if(nFiles >= 1)
+ /* Loop through the selection, handle only files (not folders) */
+ for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++)
{
- lpstrCurrFile = lpstrAllFile;
- for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
- {
- pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
-
+ pidl = (LPITEMIDLIST)((LPBYTE)cida + cida->aoffset[nFileToOpen + 1]);
if (pidl)
- {
- /* get the file name */
- lpstrTemp[0] = '\0';
- GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+ {
+ if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl))
+ {
+ if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength)
+ {
+ nAllFilesMaxLength *= 2;
+ lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR));
+ if (!lpstrTmp)
+ goto ret;
+ lpstrAllFiles = lpstrTmp;
+ }
+ nFiles += 1;
+ lpstrAllFiles[nAllFilesLength++] = '"';
+ GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength);
+ nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength);
+ nAllFilesLength += nThisFileLength;
+ lpstrAllFiles[nAllFilesLength++] = '"';
+ lpstrAllFiles[nAllFilesLength++] = ' ';
+ }
+ }
+ }
- if (! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) /* Ignore folders */
- {
- if ( nFiles > 1)
- {
- *lpstrCurrFile++ = '\"';
- lstrcpyW( lpstrCurrFile, lpstrTemp );
- lpstrCurrFile += lstrlenW( lpstrTemp );
- *lpstrCurrFile++ = '\"';
- *lpstrCurrFile++ = ' ';
- *lpstrCurrFile = 0;
- }
- else
- {
- lstrcpyW( lpstrAllFile, lpstrTemp );
- }
- }
- COMDLG32_SHFree( pidl );
- }
- }
- SetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrAllFile );
-
- /* Select the file name like Windows does */
- SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+ if (nFiles != 0)
+ {
+ /* If there's only one file, use the name as-is without quotes */
+ lpstrTmp = lpstrAllFiles;
+ if (nFiles == 1)
+ {
+ lpstrTmp += 1;
+ lpstrTmp[nThisFileLength] = 0;
+ }
+ SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp);
+ /* Select the file name like Windows does */
+ if (filename_is_edit(fodInfos))
+ SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
}
- HeapFree(GetProcessHeap(),0, lpstrAllFile );
+
+ret:
+ heap_free(lpstrAllFiles);
+ COMCTL32_ReleaseStgMedium(medium);
}
{
case STRRET_WSTR:
lstrcpynW(dest, src->u.pOleStr, len);
- COMDLG32_SHFree(src->u.pOleStr);
+ CoTaskMemFree(src->u.pOleStr);
break;
case STRRET_CSTR:
*/
static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed)
{
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
UINT nFileCount = 0; /* number of files */
UINT nStrLen = 0; /* length of string in edit control */
LPWSTR lpstrEdit; /* buffer for string from edit control */
TRACE("\n");
- /* get the filenames from the edit control */
- nStrLen = SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0);
- lpstrEdit = MemAlloc( (nStrLen+1)*sizeof(WCHAR) );
- GetDlgItemTextW(hwnd, IDC_FILENAME, lpstrEdit, nStrLen+1);
+ /* get the filenames from the filename control */
+ nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName );
+ lpstrEdit = heap_alloc( (nStrLen+1)*sizeof(WCHAR) );
+ GetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrEdit, nStrLen+1);
TRACE("nStrLen=%u str=%s\n", nStrLen, debugstr_w(lpstrEdit));
nFileCount = COMDLG32_SplitFileNames(lpstrEdit, nStrLen, lpstrFileList, sizeUsed);
- MemFree(lpstrEdit);
+ heap_free(lpstrEdit);
return nFileCount;
}
-#define SETDefFormatEtc(fe,cf,med) \
-{ \
- (fe).cfFormat = cf;\
- (fe).dwAspect = DVASPECT_CONTENT; \
- (fe).ptd =NULL;\
- (fe).tymed = med;\
- (fe).lindex = -1;\
-};
-
/*
* DATAOBJECT Helper functions
*/
{
STGMEDIUM medium;
- FORMATETC formatetc;
+ FORMATETC formatetc = get_def_format();
LPITEMIDLIST pidl = NULL;
TRACE("sv=%p index=%u\n", doSelected, nPidlIndex);
if (!doSelected)
return NULL;
-
- /* Set the FORMATETC structure*/
- SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
/* Get the pidls from IDataObject */
if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
LPIDA cida = GlobalLock(medium.u.hGlobal);
if(nPidlIndex <= cida->cidl)
{
- pidl = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
+ pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
}
COMCTL32_ReleaseStgMedium(medium);
}
{
UINT retVal = 0;
STGMEDIUM medium;
- FORMATETC formatetc;
+ FORMATETC formatetc = get_def_format();
TRACE("sv=%p\n", doSelected);
if (!doSelected) return 0;
- /* Set the FORMATETC structure*/
- SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
-
/* Get the pidls from IDataObject */
if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
{
TRACE("%p\n", pidl);
- pidlParent = COMDLG32_PIDL_ILClone(pidl);
- COMDLG32_PIDL_ILRemoveLastID(pidlParent);
+ pidlParent = ILClone(pidl);
+ ILRemoveLastID(pidlParent);
return pidlParent;
}
*/
static BOOL BrowseSelectedFolder(HWND hwnd)
{
+ FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
BOOL bBrowseSelFolder = FALSE;
- FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("\n");
if ( FAILED( IShellBrowser_BrowseObject( fodInfos->Shell.FOIShellBrowser,
pidlSelection, SBSP_RELATIVE ) ) )
{
- static const WCHAR notexist[] = {'P','a','t','h',' ','d','o','e','s',
- ' ','n','o','t',' ','e','x','i','s','t',0};
- MessageBoxW( hwnd, notexist, fodInfos->title, MB_OK | MB_ICONEXCLAMATION );
+ WCHAR buf[64];
+ LoadStringW( COMDLG32_hInstance, IDS_PATHNOTEXISTING, buf, ARRAY_SIZE(buf));
+ MessageBoxW( hwnd, buf, fodInfos->title, MB_OK | MB_ICONEXCLAMATION );
}
bBrowseSelFolder = TRUE;
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
SendCustomDlgNotificationMessage(hwnd,CDN_FOLDERCHANGE);
}
- COMDLG32_SHFree( pidlSelection );
+ ILFree( pidlSelection );
}
return bBrowseSelFolder;
}
-/*
- * Memory allocation methods */
-static void *MemAlloc(UINT size)
-{
- return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
-}
-
-static void MemFree(void *mem)
-{
- HeapFree(GetProcessHeap(),0,mem);
-}
-
-/*
- * Old-style (win3.1) dialogs */
-
-/***********************************************************************
- * FD32_GetTemplate [internal]
- *
- * Get a template (or FALSE if failure) when 16 bits dialogs are used
- * by a 32 bits application
- *
- */
-BOOL FD32_GetTemplate(PFD31_DATA lfs)
-{
- LPOPENFILENAMEW ofnW = lfs->ofnW;
- LPOPENFILENAMEA ofnA = lfs->ofnA;
- HANDLE hDlgTmpl;
-
- if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
- {
- if (!(lfs->template = LockResource( ofnW->hInstance )))
- {
- COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
- return FALSE;
- }
- }
- else if (ofnW->Flags & OFN_ENABLETEMPLATE)
- {
- HRSRC hResInfo;
- if (ofnA)
- hResInfo = FindResourceA(ofnA->hInstance,
- ofnA->lpTemplateName,
- (LPSTR)RT_DIALOG);
- else
- hResInfo = FindResourceW(ofnW->hInstance,
- ofnW->lpTemplateName,
- (LPWSTR)RT_DIALOG);
- if (!hResInfo)
- {
- COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
- return FALSE;
- }
- if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
- hResInfo)) ||
- !(lfs->template = LockResource(hDlgTmpl)))
- {
- COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
- return FALSE;
- }
- } else { /* get it from internal Wine resource */
- HRSRC hResInfo;
- if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
- lfs->open? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
- {
- COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
- return FALSE;
- }
- if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
- !(lfs->template = LockResource( hDlgTmpl )))
- {
- COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-/***********************************************************************
- * FD32_WMMeasureItem [internal]
- */
-static LONG FD32_WMMeasureItem(LPARAM lParam)
-{
- LPMEASUREITEMSTRUCT lpmeasure;
-
- lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
- lpmeasure->itemHeight = FD31_GetFldrHeight();
- return TRUE;
-}
-
-
-/***********************************************************************
- * FileOpenDlgProc [internal]
- * Used for open and save, in fact.
- */
-static INT_PTR CALLBACK FD32_FileOpenDlgProc(HWND hWnd, UINT wMsg,
- WPARAM wParam, LPARAM lParam)
-{
- PFD31_DATA lfs = (PFD31_DATA)GetPropA(hWnd,FD31_OFN_PROP);
-
- TRACE("msg=%x wparam=%lx lParam=%lx\n", wMsg, wParam, lParam);
- if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
- {
- INT_PTR lRet;
- lRet = (INT_PTR)FD31_CallWindowProc(lfs, wMsg, wParam, lParam);
- if (lRet)
- return lRet; /* else continue message processing */
- }
- switch (wMsg)
- {
- case WM_INITDIALOG:
- return FD31_WMInitDialog(hWnd, wParam, lParam);
-
- case WM_MEASUREITEM:
- return FD32_WMMeasureItem(lParam);
-
- case WM_DRAWITEM:
- return FD31_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
-
- case WM_COMMAND:
- return FD31_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
-#if 0
- case WM_CTLCOLOR:
- SetBkColor((HDC16)wParam, 0x00C0C0C0);
- switch (HIWORD(lParam))
- {
- case CTLCOLOR_BTN:
- SetTextColor((HDC16)wParam, 0x00000000);
- return hGRAYBrush;
- case CTLCOLOR_STATIC:
- SetTextColor((HDC16)wParam, 0x00000000);
- return hGRAYBrush;
- }
- break;
-#endif
- }
- return FALSE;
-}
-
-
-/***********************************************************************
- * GetFileName31A [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save.
- */
-static BOOL GetFileName31A(LPOPENFILENAMEA lpofn, /* address of structure with data*/
- UINT dlgType /* type dialogue : open/save */
- )
+static inline BOOL valid_struct_size( DWORD size )
{
- BOOL bRet = FALSE;
- PFD31_DATA lfs;
-
- if (!lpofn || !FD31_Init()) return FALSE;
-
- TRACE("ofn flags %08x\n", lpofn->Flags);
- lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE);
- if (lfs)
- {
- bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
- FD32_FileOpenDlgProc, (LPARAM)lfs);
- FD31_DestroyPrivate(lfs);
- }
-
- TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
- return bRet;
+ return (size == OPENFILENAME_SIZE_VERSION_400W) ||
+ (size == sizeof( OPENFILENAMEW ));
}
-/***********************************************************************
- * GetFileName31W [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save
- */
-static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with data*/
- UINT dlgType /* type dialogue : open/save */
- )
+static inline BOOL is_win16_looks(DWORD flags)
{
- BOOL bRet = FALSE;
- PFD31_DATA lfs;
-
- if (!lpofn || !FD31_Init()) return FALSE;
-
- lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE);
- if (lfs)
- {
- bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
- FD32_FileOpenDlgProc, (LPARAM)lfs);
- FD31_DestroyPrivate(lfs);
- }
-
- TRACE("file %s, file offset %d, ext offset %d\n",
- debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension);
- return bRet;
+ return (flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE) &&
+ !(flags & OFN_EXPLORER));
}
/* ------------------ APIs ---------------------- */
* FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
*
*/
-BOOL WINAPI GetOpenFileNameA(
- LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn)
{
- BOOL win16look = FALSE;
+ TRACE("flags 0x%08x\n", ofn->Flags);
- TRACE("flags %08x\n", ofn->Flags);
+ if (!valid_struct_size( ofn->lStructSize ))
+ {
+ COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+ return FALSE;
+ }
/* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
if (ofn->Flags & OFN_FILEMUSTEXIST)
ofn->Flags |= OFN_PATHMUSTEXIST;
- if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
- win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
- if (win16look)
+ if (is_win16_looks(ofn->Flags))
return GetFileName31A(ofn, OPEN_DIALOG);
else
- return GetFileDialog95A(ofn, OPEN_DIALOG);
+ {
+ FileOpenDlgInfos info;
+
+ init_filedlg_infoA(ofn, &info);
+ return GetFileDialog95(&info, OPEN_DIALOG);
+ }
}
/***********************************************************************
* FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
*
*/
-BOOL WINAPI GetOpenFileNameW(
- LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
{
- BOOL win16look = FALSE;
+ TRACE("flags 0x%08x\n", ofn->Flags);
- TRACE("flags %08x\n", ofn->Flags);
+ if (!valid_struct_size( ofn->lStructSize ))
+ {
+ COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+ return FALSE;
+ }
/* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
if (ofn->Flags & OFN_FILEMUSTEXIST)
ofn->Flags |= OFN_PATHMUSTEXIST;
- if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
- win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
- if (win16look)
+ if (is_win16_looks(ofn->Flags))
return GetFileName31W(ofn, OPEN_DIALOG);
else
- return GetFileDialog95W(ofn, OPEN_DIALOG);
+ {
+ FileOpenDlgInfos info;
+
+ init_filedlg_infoW(ofn, &info);
+ return GetFileDialog95(&info, OPEN_DIALOG);
+ }
}
* FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
*
*/
-BOOL WINAPI GetSaveFileNameA(
- LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn)
{
- BOOL win16look = FALSE;
-
- if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
- win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+ if (!valid_struct_size( ofn->lStructSize ))
+ {
+ COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+ return FALSE;
+ }
- if (win16look)
+ if (is_win16_looks(ofn->Flags))
return GetFileName31A(ofn, SAVE_DIALOG);
else
- return GetFileDialog95A(ofn, SAVE_DIALOG);
+ {
+ FileOpenDlgInfos info;
+
+ init_filedlg_infoA(ofn, &info);
+ return GetFileDialog95(&info, SAVE_DIALOG);
+ }
}
/***********************************************************************
BOOL WINAPI GetSaveFileNameW(
LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
{
- BOOL win16look = FALSE;
-
- if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
- win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+ if (!valid_struct_size( ofn->lStructSize ))
+ {
+ COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+ return FALSE;
+ }
- if (win16look)
+ if (is_win16_looks(ofn->Flags))
return GetFileName31W(ofn, SAVE_DIALOG);
else
- return GetFileDialog95W(ofn, SAVE_DIALOG);
+ {
+ FileOpenDlgInfos info;
+
+ init_filedlg_infoW(ofn, &info);
+ return GetFileDialog95(&info, SAVE_DIALOG);
+ }
}
/***********************************************************************
LPWSTR lpWTitle;
RtlCreateUnicodeStringFromAsciiz(&strWFile, lpFile);
- lpWTitle = RtlAllocateHeap( GetProcessHeap(), 0, cbBuf*sizeof(WCHAR));
+ lpWTitle = heap_alloc(cbBuf * sizeof(WCHAR));
ret = GetFileTitleW(strWFile.Buffer, lpWTitle, cbBuf);
if (!ret) WideCharToMultiByte( CP_ACP, 0, lpWTitle, -1, lpTitle, cbBuf, NULL, NULL );
RtlFreeUnicodeString( &strWFile );
- RtlFreeHeap( GetProcessHeap(), 0, lpWTitle );
+ heap_free( lpWTitle );
return ret;
}