https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c8e1460ac57e7862ccef0…
commit c8e1460ac57e7862ccef0b5602764b6d72167a70
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Sep 26 21:26:06 2020 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Sep 26 21:26:06 2020 +0900
[COMDLG32] Support shortcut keys on Open/Save Dialog (#3238)
Enable key accelerators on File Open/Save Dialog. CORE-14332
---
dll/win32/comdlg32/cdlg.h | 3 ++
dll/win32/comdlg32/cdlg32.c | 9 +++++
dll/win32/comdlg32/filedlg.c | 94 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 106 insertions(+)
diff --git a/dll/win32/comdlg32/cdlg.h b/dll/win32/comdlg32/cdlg.h
index 28bb7e75268..7570acebb9e 100644
--- a/dll/win32/comdlg32/cdlg.h
+++ b/dll/win32/comdlg32/cdlg.h
@@ -27,6 +27,9 @@
#define COMDLG32_Atom MAKEINTATOM(0xa000) /* MS uses this one to identify props */
extern HINSTANCE COMDLG32_hInstance DECLSPEC_HIDDEN;
+#ifdef __REACTOS__
+extern CRITICAL_SECTION COMDLG32_OpenFileLock DECLSPEC_HIDDEN;
+#endif
void COMDLG32_SetCommDlgExtendedError(DWORD err) DECLSPEC_HIDDEN;
LPVOID COMDLG32_AllocMem(int size) __WINE_ALLOC_SIZE(1) DECLSPEC_HIDDEN;
diff --git a/dll/win32/comdlg32/cdlg32.c b/dll/win32/comdlg32/cdlg32.c
index 1c21025cfd0..95692c00a37 100644
--- a/dll/win32/comdlg32/cdlg32.c
+++ b/dll/win32/comdlg32/cdlg32.c
@@ -40,6 +40,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance = 0;
+#ifdef __REACTOS__
+CRITICAL_SECTION COMDLG32_OpenFileLock DECLSPEC_HIDDEN;
+#endif
static DWORD COMDLG32_TlsIndex = TLS_OUT_OF_INDEXES;
@@ -76,6 +79,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
DisableThreadLibraryCalls(hInstance);
SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL");
+#ifdef __REACTOS__
+ InitializeCriticalSection(&COMDLG32_OpenFileLock);
+#endif
/* SHELL */
GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162);
@@ -84,6 +90,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
case DLL_PROCESS_DETACH:
if (Reserved) break;
if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex);
+#ifdef __REACTOS__
+ DeleteCriticalSection(&COMDLG32_OpenFileLock);
+#endif
break;
}
return TRUE;
diff --git a/dll/win32/comdlg32/filedlg.c b/dll/win32/comdlg32/filedlg.c
index 6e5134f6ce3..49bd1d006b1 100644
--- a/dll/win32/comdlg32/filedlg.c
+++ b/dll/win32/comdlg32/filedlg.c
@@ -106,6 +106,78 @@ typedef struct tagLookInInfo
UINT uSelectedItem;
} LookInInfos;
+#ifdef __REACTOS__
+/* We have to call IShellView::TranslateAccelerator to handle the standard
+ key bindings of File Open Dialog. We use hook to realize them. */
+static HHOOK s_hFileDialogHook = NULL;
+static LONG s_nFileDialogHookCount = 0;
+
+#define MAX_TRANSLATE 8
+static HWND s_ahwndTranslate[MAX_TRANSLATE] = { NULL };
+
+static void FILEDLG95_AddRemoveTranslate(HWND hwndOld, HWND hwndNew)
+{
+ LONG i;
+ for (i = 0; i < MAX_TRANSLATE; ++i)
+ {
+ if (s_ahwndTranslate[i] == hwndOld)
+ {
+ s_ahwndTranslate[i] = hwndNew;
+ break;
+ }
+ }
+}
+
+static __inline BOOL
+FILEDLG95_DoTranslate(LONG i, HWND hwndFocus, LPMSG pMsg)
+{
+ FileOpenDlgInfos *fodInfos;
+ HWND hwndView;
+
+ if (s_ahwndTranslate[i] == NULL)
+ return FALSE;
+
+ fodInfos = get_filedlg_infoptr(s_ahwndTranslate[i]);
+ if (fodInfos == NULL)
+ return FALSE;
+
+ hwndView = fodInfos->ShellInfos.hwndView;
+ if (hwndView == hwndFocus || IsChild(hwndView, hwndFocus))
+ {
+ IShellView_TranslateAccelerator(fodInfos->Shell.FOIShellView, pMsg);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* WH_MSGFILTER hook procedure */
+static LRESULT CALLBACK
+FILEDLG95_TranslateMsgProc(INT nCode, WPARAM wParam, LPARAM lParam)
+{
+ LPMSG pMsg;
+
+ if (nCode < 0)
+ return CallNextHookEx(s_hFileDialogHook, nCode, wParam, lParam);
+ if (nCode != MSGF_DIALOGBOX)
+ return 0;
+
+ pMsg = (LPMSG)lParam;
+ if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
+ {
+ LONG i;
+ HWND hwndFocus = GetFocus();
+ EnterCriticalSection(&COMDLG32_OpenFileLock);
+ for (i = 0; i < MAX_TRANSLATE; ++i)
+ {
+ if (FILEDLG95_DoTranslate(i, hwndFocus, pMsg))
+ break;
+ }
+ LeaveCriticalSection(&COMDLG32_OpenFileLock);
+ }
+
+ return 0;
+}
+#endif
/***********************************************************************
* Defines and global variables
@@ -1428,6 +1500,17 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM l
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
SendCustomDlgNotificationMessage(hwnd,CDN_SELCHANGE);
+#ifdef __REACTOS__
+ /* Enable hook and translate */
+ EnterCriticalSection(&COMDLG32_OpenFileLock);
+ if (++s_nFileDialogHookCount == 1)
+ {
+ s_hFileDialogHook = SetWindowsHookEx(WH_MSGFILTER,
FILEDLG95_TranslateMsgProc,
+ 0, GetCurrentThreadId());
+ }
+ FILEDLG95_AddRemoveTranslate(NULL, hwnd);
+ LeaveCriticalSection(&COMDLG32_OpenFileLock);
+#endif
return 0;
}
case WM_SIZE:
@@ -1465,6 +1548,17 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM l
SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0);
ImageList_Destroy(himl);
}
+#ifdef __REACTOS__
+ /* Disable hook and translate */
+ EnterCriticalSection(&COMDLG32_OpenFileLock);
+ FILEDLG95_AddRemoveTranslate(hwnd, NULL);
+ if (--s_nFileDialogHookCount == 0)
+ {
+ UnhookWindowsHookEx(s_hFileDialogHook);
+ s_hFileDialogHook = NULL;
+ }
+ LeaveCriticalSection(&COMDLG32_OpenFileLock);
+#endif
return FALSE;
}