https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c8e1460ac57e7862ccef0b5602764b6d72167a70

commit c8e1460ac57e7862ccef0b5602764b6d72167a70
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sat Sep 26 21:26:06 2020 +0900
Commit:     GitHub <[email protected]>
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;
       }
 

Reply via email to