Author: hbelusca
Date: Sun Jul 3 18:07:40 2016
New Revision: 71799
URL:
http://svn.reactos.org/svn/reactos?rev=71799&view=rev
Log:
[SHELL32]: Implement RunFileDlg notification (in RunDlgProc), as described in
http://www.codeproject.com/KB/shell/runfiledlg.aspx .
CORE-11390
Modified:
trunk/reactos/dll/win32/shell32/dialogs/dialogs.cpp
trunk/reactos/sdk/include/reactos/undocshell.h
Modified: trunk/reactos/dll/win32/shell32/dialogs/dialogs.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/dialogs/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/dialogs/dialogs.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/dialogs/dialogs.cpp [iso-8859-1] Sun Jul 3 18:07:40
2016
@@ -376,8 +376,10 @@
}
if (prfdp->uFlags & RFF_NOLABEL)
ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_LABEL), SW_HIDE);
- if (prfdp->uFlags & RFF_CALCDIRECTORY)
- FIXME("RFF_CALCDIRECTORY not supported\n");
+ if (prfdp->uFlags & RFF_NOSEPARATEMEM)
+ {
+ FIXME("RFF_NOSEPARATEMEM not supported\n");
+ }
/* Use the default Shell Run icon if no one is specified */
if (prfdp->hIcon == NULL)
@@ -403,53 +405,101 @@
{
case IDOK:
{
- int ic;
+ LRESULT lRet;
HWND htxt = GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH);
- if ((ic = GetWindowTextLengthW(htxt)))
+ INT ic;
+ WCHAR *psz, *parent = NULL;
+ SHELLEXECUTEINFOW sei;
+ NMRUNFILEDLGW nmrfd;
+
+ ic = GetWindowTextLengthW(htxt);
+ if (ic == 0)
{
- WCHAR *psz, *parent = NULL;
- SHELLEXECUTEINFOW sei;
-
- ZeroMemory(&sei, sizeof(sei));
- sei.cbSize = sizeof(sei);
- psz = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (ic +
1)*sizeof(WCHAR));
-
- if (psz)
- {
- GetWindowTextW(htxt, psz, ic + 1);
-
- /* according to
http://www.codeproject.com/KB/shell/runfiledlg.aspx we should send a
- * WM_NOTIFY before execution */
-
- sei.hwnd = hwnd;
- sei.nShow = SW_SHOWNORMAL;
- sei.lpFile = psz;
-
- if (prfdp->lpstrDirectory)
- sei.lpDirectory = prfdp->lpstrDirectory;
- else
- sei.lpDirectory = parent =
RunDlg_GetParentDir(sei.lpFile);
-
- if (!ShellExecuteExW(&sei))
+ EndDialog(hwnd, IDCANCEL);
+ return TRUE;
+ }
+
+ ZeroMemory(&sei, sizeof(sei));
+ sei.cbSize = sizeof(sei);
+ psz = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (ic +
1)*sizeof(WCHAR));
+ if (!psz)
+ {
+ EndDialog(hwnd, IDCANCEL);
+ return TRUE;
+ }
+
+ GetWindowTextW(htxt, psz, ic + 1);
+
+ sei.hwnd = hwnd;
+ sei.nShow = SW_SHOWNORMAL;
+ sei.lpFile = psz;
+
+ /*
+ * The precedence is the following: first the user-given
+ * current directory is used; if there is none, a current
+ * directory is computed if the RFF_CALCDIRECTORY is set,
+ * otherwise no current directory is defined.
+ */
+ if (prfdp->lpstrDirectory)
+ sei.lpDirectory = prfdp->lpstrDirectory;
+ else if (prfdp->uFlags & RFF_CALCDIRECTORY)
+ sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile);
+ else
+ sei.lpDirectory = NULL;
+
+ /* Hide the dialog for now on, we will show it up in case of retry
*/
+ ShowWindow(hwnd, SW_HIDE);
+
+ /*
+ * As shown by manual tests on Windows, modifying the contents
+ * of the notification structure will not modify what the
+ * Run-Dialog will use for the nShow parameter. However the
+ * lpFile and lpDirectory pointers are set to the buffers used
+ * by the Run-Dialog, as a consequence they can be modified by
+ * the notification receiver, as long as it respects the lengths
+ * of the buffers (to avoid buffer overflows).
+ */
+ nmrfd.hdr.code = RFN_VALIDATE;
+ nmrfd.hdr.hwndFrom = hwnd;
+ nmrfd.hdr.idFrom = 0;
+ nmrfd.lpFile = sei.lpFile;
+ nmrfd.lpDirectory = sei.lpDirectory;
+ nmrfd.nShow = sei.nShow;
+
+ lRet = SendMessageW(prfdp->hwndOwner, WM_NOTIFY, 0,
(LPARAM)&nmrfd.hdr);
+
+ switch (lRet)
+ {
+ case RF_CANCEL:
+ EndDialog(hwnd, IDCANCEL);
+ break;
+
+ case RF_OK:
+ if (ShellExecuteExW(&sei))
{
- HeapFree(GetProcessHeap(), 0, psz);
- HeapFree(GetProcessHeap(), 0, parent);
- SendMessageW(htxt, CB_SETEDITSEL, 0, MAKELPARAM (0,
-1));
- return TRUE;
+ /* Call again GetWindowText in case the contents of the
edit box has changed? */
+ GetWindowTextW(htxt, psz, ic + 1);
+ FillList(htxt, psz, FALSE);
+ EndDialog(hwnd, IDOK);
+ break;
}
- GetWindowTextW(htxt, psz, ic + 1);
- FillList(htxt, psz, FALSE);
-
- HeapFree(GetProcessHeap(), 0, psz);
- HeapFree(GetProcessHeap(), 0, parent);
- EndDialog(hwnd, 0);
- }
+ /* Fall-back */
+ case RF_RETRY:
+ default:
+ SendMessageW(htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1));
+ /* Show back the dialog */
+ ShowWindow(hwnd, SW_SHOW);
+ break;
}
+
+ HeapFree(GetProcessHeap(), 0, parent);
+ HeapFree(GetProcessHeap(), 0, psz);
+ return TRUE;
}
case IDCANCEL:
- EndDialog(hwnd, 0);
+ EndDialog(hwnd, IDCANCEL);
return TRUE;
case IDC_RUNDLG_BROWSE:
Modified: trunk/reactos/sdk/include/reactos/undocshell.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/reactos/undocs…
==============================================================================
--- trunk/reactos/sdk/include/reactos/undocshell.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/reactos/undocshell.h [iso-8859-1] Sun Jul 3 18:07:40 2016
@@ -98,17 +98,28 @@
#define RFF_NOLABEL 0x08 /* Removes the edit box label */
#define RFF_NOSEPARATEMEM 0x20 /* Removes the Separate Memory Space check box
(Windows NT only) */
-#define DE_SAMEFILE 0x71
-#define DE_DESTSAMETREE 0x7D
-
-/* RunFileFlg notification structure */
-typedef struct
-{
- NMHDR hdr;
- LPCSTR lpFile;
- LPCSTR lpDirectory;
- int nShow;
-} NM_RUNFILEDLG, * LPNM_RUNFILEDLG;
+/* RunFileFlg notification value and structure */
+#define RFN_VALIDATE (-510)
+#if 0 // Deprecated ANSI structure
+typedef struct _NMRUNFILEDLGA
+{
+ NMHDR hdr;
+ LPCSTR lpFile;
+ LPCSTR lpDirectory;
+ UINT nShow;
+} NMRUNFILEDLGA, *PNMRUNFILEDLGA, *LPNMRUNFILEDLGA;
+#endif
+typedef struct _NMRUNFILEDLGW
+{
+ NMHDR hdr;
+ LPCWSTR lpFile;
+ LPCWSTR lpDirectory;
+ UINT nShow;
+} NMRUNFILEDLGW, *PNMRUNFILEDLGW, *LPNMRUNFILEDLGW;
+
+typedef NMRUNFILEDLGW NMRUNFILEDLG;
+typedef PNMRUNFILEDLGW PNMRUNFILEDLG;
+typedef LPNMRUNFILEDLGW LPNMRUNFILEDLG;
/* RunFileDlg notification return values */
#define RF_OK 0x00