OSDN Git Service

Make the keyboard hook thread local. snap-64bit
authorKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Fri, 22 Apr 2011 15:34:15 +0000 (00:34 +0900)
committerKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Thu, 26 May 2011 23:35:43 +0000 (08:35 +0900)
Set and release the hook when DLL ataches and detaches to threads or
processes. Disable the keyboard hook when other hooks are released.

xkeymacsdll/xkeymacsdll.cpp
xkeymacsdll/xkeymacsdll.h

index 9c61792..05d7d78 100644 (file)
@@ -18,7 +18,8 @@ static char THIS_FILE[] = __FILE__;
 \r
 static AFX_EXTENSION_MODULE XkeymacsdllDLL = { NULL, NULL };\r
 \r
-static HINSTANCE g_hDllInst = NULL;\r
+static __declspec(thread) HINSTANCE g_hDllInst = NULL;\r
+static __declspec(thread) HHOOK g_hHookKeyboard = NULL;\r
 \r
 extern "C" int APIENTRY\r
 DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
@@ -28,7 +29,8 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
        // Remove this if you use lpReserved\r
        UNREFERENCED_PARAMETER(lpReserved);\r
 \r
-       if (dwReason == DLL_PROCESS_ATTACH) {\r
+       switch (dwReason) {\r
+       case DLL_PROCESS_ATTACH:\r
                TRACE0("XKEYMACSDLL.DLL Initializing!\n");\r
                \r
                // Extension DLL one-time initialization\r
@@ -55,10 +57,15 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
                        e->Delete();\r
 //                     CUtils::Log("DllMain: 'new' threw an exception");\r
                }\r
-       } else if (dwReason == DLL_PROCESS_DETACH) {\r
+       case DLL_THREAD_ATTACH:\r
+               CXkeymacsDll::SetKeyboardHook();\r
+               break;\r
+       case DLL_PROCESS_DETACH:\r
                TRACE0("XKEYMACSDLL.DLL Terminating!\n");\r
                // Terminate the library before destructors are called\r
                AfxTermExtensionModule(XkeymacsdllDLL);\r
+       case DLL_THREAD_DETACH:\r
+               CXkeymacsDll::ReleaseKeyboardHook();\r
        }\r
        return 1;   // ok\r
 }\r
@@ -69,7 +76,7 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
 \r
 #include "xkeymacsDll.h"\r
 #pragma data_seg(".xkmcs")\r
-       HHOOK   CXkeymacsDll::m_hHookKeyboard = NULL;\r
+       BOOL    CXkeymacsDll::m_bEnableKeyboardHook = FALSE;\r
        HHOOK   CXkeymacsDll::m_hHookCallWnd = NULL;\r
        HHOOK   CXkeymacsDll::m_hHookCallWndRet = NULL;\r
        HHOOK   CXkeymacsDll::m_hHookGetMessage = NULL;\r
@@ -206,19 +213,23 @@ void CXkeymacsDll::DeleteShell_NotifyIcon(ICON_TYPE icon)
 // set hooks\r
 void CXkeymacsDll::SetHooks()\r
 {\r
-       m_hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, 0);\r
+       m_bEnableKeyboardHook = TRUE;\r
        m_hHookCallWnd = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc, g_hDllInst, 0);\r
        m_hHookCallWndRet = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC)CallWndRetProc, g_hDllInst, 0);\r
        m_hHookGetMessage = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hDllInst, 0);\r
        m_hHookShell = SetWindowsHookEx(WH_SHELL, (HOOKPROC)ShellProc, g_hDllInst, 0);\r
 }\r
 \r
+void CXkeymacsDll::SetKeyboardHook()\r
+{\r
+       if (!g_hHookKeyboard)\r
+               SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, GetCurrentThreadId());\r
+}\r
+\r
 // release hooks\r
 void CXkeymacsDll::ReleaseHooks()\r
 {\r
-       if (m_hHookKeyboard)\r
-               UnhookWindowsHookEx(m_hHookKeyboard);\r
-       m_hHookKeyboard = NULL;\r
+       m_bEnableKeyboardHook = FALSE;\r
        if (m_hHookCallWnd)\r
                UnhookWindowsHookEx(m_hHookCallWnd);\r
        m_hHookCallWnd = NULL;\r
@@ -233,6 +244,13 @@ void CXkeymacsDll::ReleaseHooks()
        m_hHookShell = NULL;\r
 }\r
 \r
+void CXkeymacsDll::ReleaseKeyboardHook()\r
+{\r
+       if (g_hHookKeyboard)\r
+               UnhookWindowsHookEx(g_hHookKeyboard);\r
+       g_hHookKeyboard = NULL;\r
+}\r
+\r
 void CXkeymacsDll::SetKeyboardHookFlag(BOOL bFlag)\r
 {\r
        m_bHook = bFlag;\r
@@ -679,6 +697,9 @@ LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
 \r
 //     CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %#x"), nCode, nKey, lParam);\r
 \r
+       if (!m_bEnableKeyboardHook)\r
+               return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
+\r
        if (nCode < 0 || nCode == HC_NOREMOVE) {\r
                goto DO_NOTHING;\r
        }\r
@@ -1129,7 +1150,7 @@ DO_NOTHING:
                bDefiningMacro = m_bDefiningMacro;\r
        }\r
 \r
-       return CallNextHookEx(m_hHookKeyboard, nCode, wParam, lParam);\r
+       return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
 \r
 RECURSIVE:\r
        Kdu(RECURSIVE_KEY, 1, FALSE);\r
index 4aa2c53..28201f9 100644 (file)
@@ -194,10 +194,12 @@ public:
        void SetAtIbeamCursorOnly(int nApplicationID, int nCommandType, int nKey, BOOL bAtIbeamCursorOnly);\r
        void SetApplicationName(int nApplicationID, CString szApplicationName);\r
        static void ReleaseHooks();\r
+       static void ReleaseKeyboardHook();\r
        void SetEnableCUA(int nApplicationID, BOOL bEnableCUA);\r
        void SetIgnoreUndefinedC_x(int nApplicationID, BOOL bIgnoreUndefinedC_x);\r
        void SetIgnoreUndefinedMetaCtrl(int nApplicationID, BOOL bIgnoreUndefinedMetaCtrl);\r
        static void SetHooks();\r
+       static void SetKeyboardHook();\r
        void SetSettingStyle(int nApplicationID, int nSettingStyle);\r
        void SetUseDialogSetting(int nApplicationID, BOOL bUseDialogSetting);\r
        static void AddKillRing(BOOL bNewData = TRUE);\r
@@ -232,7 +234,7 @@ private:
        static LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam);\r
        static BOOL IsMatchWindowText(CString szWindowText);\r
        static TCHAR m_szWindowText[MAX_APP][WINDOW_TEXT_LENGTH];\r
-       static HHOOK m_hHookKeyboard;\r
+       static BOOL m_bEnableKeyboardHook;\r
        static HHOOK m_hHookCallWnd;\r
        static HHOOK m_hHookGetMessage;\r
        static HHOOK m_hHookShell;\r