https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c8e1460ac57e7862ccef0b...
commit c8e1460ac57e7862ccef0b5602764b6d72167a70 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sat Sep 26 21:26:06 2020 +0900 Commit: GitHub noreply@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; }