OSDN Git Service

Make the keyboard hook local to each thread. Remove the code to
authorKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Wed, 20 Jul 2011 12:37:11 +0000 (21:37 +0900)
committerKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Thu, 21 Jul 2011 00:52:26 +0000 (09:52 +0900)
control IME with a window message.

xkeymacs/xkeymacs64.cpp
xkeymacsdll/Commands.cpp
xkeymacsdll/Commands.h
xkeymacsdll/xkeymacsdll.cpp
xkeymacsdll/xkeymacsdll.h

index 4ae33e3..8dbe5d7 100644 (file)
@@ -63,7 +63,7 @@ UINT PollIPCMessage(LPVOID lpParam)
                        CXkeymacsDll::LoadConfig();\r
                        break;\r
                case XKEYMACS_RESET:\r
-                       //CXkeymacsDll::ResetHooks();\r
+                       CXkeymacsDll::ResetHooks();\r
                        break;\r
                }\r
        }\r
index 9c937c7..addd908 100644 (file)
@@ -2612,24 +2612,7 @@ int CCommands::CompleteCloseInputMethod()
        return Reset(GOTO_HOOK);\r
 }\r
 \r
-inline HWND ObtainFocus()\r
-{\r
-       const HWND hWnd = GetFocus();\r
-       if (hWnd)\r
-               return hWnd;\r
-       GUITHREADINFO gui;\r
-       gui.cbSize = sizeof(gui);\r
-       return GetGUIThreadInfo(GetWindowThreadProcessId(GetForegroundWindow(), 0), &gui) ? gui.hwndFocus : GetForegroundWindow();\r
-}\r
-\r
-void CCommands::SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete) {\r
-       extern UINT g_ImeManipulationMessage;\r
-       HWND hWnd = ObtainFocus();\r
-       //CUtils::Log(_T(" post ime manip, %d, %d, %p"), status, isComplete, hWnd);\r
-       PostMessage(hWnd, g_ImeManipulationMessage, status, isComplete);\r
-}\r
-\r
-void CCommands::DoSetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete)\r
+void CCommands::SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete)\r
 {\r
        ClearNumericArgument();\r
        HKL hKL = GetKeyboardLayout(0);\r
@@ -2637,7 +2620,7 @@ void CCommands::DoSetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL
                Kdu(VK_KANJI);\r
        } else if (ImmIsIME(hKL)) {\r
                // default\r
-               HWND hWnd = ObtainFocus();\r
+               HWND hWnd = GetFocus();\r
                HIMC hIMC = ImmGetContext(hWnd);\r
                //CUtils::Log(_T(" do ime manip, %d, %d, %d, %p, %p"), status, isComplete, ImmGetOpenStatus(hIMC), hWnd, hIMC);\r
 \r
index 1e929c6..e560a62 100644 (file)
@@ -176,7 +176,6 @@ public:
        static int GetDefaultCommandType(int nComID, int nIndex);\r
        static int GetDefaultCommandKey(int nComID, int nIndex);\r
        static int GetDefaultControlID(int nComID, int nIndex);\r
-       static void DoSetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete = FALSE);\r
 \r
 private:\r
        static BOOL CutFollowingWord();\r
index cb0f25d..12ec0c8 100644 (file)
@@ -133,46 +133,8 @@ static const int MAX_KEYNAME = _countof(KeyNames);
 \r
 static AFX_EXTENSION_MODULE XkeymacsdllDLL = { NULL, NULL };\r
 \r
-HINSTANCE g_hDllInst = NULL;\r
-UINT g_ImeManipulationMessage = 0;\r
-#pragma data_seg(".xkmcs")\r
-HHOOK g_hHookKeyboard = NULL;\r
-HHOOK g_hHookDummy = NULL;\r
-#pragma data_seg()\r
-\r
-inline bool IsWow64(HANDLE mod)\r
-{\r
-       typedef BOOL (WINAPI *pfnIsWow64Process_t)(HANDLE, PBOOL);\r
-       if (const pfnIsWow64Process_t IsWow64Process = (pfnIsWow64Process_t)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process")) {\r
-               BOOL b;\r
-               return IsWow64Process(mod, &b) && b;\r
-       }\r
-       return false;\r
-}\r
-\r
-inline bool Is64System()\r
-{\r
-       SYSTEM_INFO info;\r
-       GetNativeSystemInfo(&info);\r
-       return info.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL;\r
-}\r
-\r
-inline bool Is64Process(HANDLE mod)\r
-{\r
-       return Is64System() && !IsWow64(mod);\r
-}\r
-\r
-const bool IsDll64 = sizeof(void *) == 8;\r
-\r
-inline bool Is64ProcessHwnd(HWND hwnd)\r
-{\r
-       DWORD pid;\r
-       GetWindowThreadProcessId(hwnd, &pid);\r
-       HANDLE hmod = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);\r
-       bool b = Is64Process(hmod);\r
-       CloseHandle(hmod);\r
-       return b;\r
-}\r
+static 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
@@ -185,7 +147,6 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
        switch (dwReason) {\r
        case DLL_PROCESS_ATTACH:\r
                TRACE0("XKEYMACSDLL.DLL Initializing!\n");\r
-               g_ImeManipulationMessage = RegisterWindowMessage(_T("XkManipulateIME"));\r
 \r
                // Extension DLL one-time initialization\r
                if (!AfxInitExtensionModule(XkeymacsdllDLL, hInstance)) {\r
@@ -216,6 +177,9 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
                TRACE0("XKEYMACSDLL.DLL Terminating!\n");\r
                // Terminate the library before destructors are called\r
                AfxTermExtensionModule(XkeymacsdllDLL);\r
+               // fall through\r
+       case DLL_THREAD_DETACH:\r
+               CXkeymacsDll::ReleaseKeyboardHook();\r
                break;\r
        }\r
        return 1;   // ok\r
@@ -227,6 +191,7 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
 \r
 #include "xkeymacsDll.h"\r
 #pragma data_seg(".xkmcs")\r
+       bool    CXkeymacsDll::m_bEnableKeyboardHook = false;\r
        DWORD   CXkeymacsDll::m_nHookAltRelease = 0;\r
        HHOOK   CXkeymacsDll::m_hHookCallWnd = NULL;\r
        HHOOK   CXkeymacsDll::m_hHookCallWndRet = NULL;\r
@@ -289,19 +254,19 @@ void CXkeymacsDll::SetConfig(const CONFIG& config)
        m_Config = config;\r
 }\r
 \r
-// set hooks\r
-LRESULT WINAPI DummyProc(int code, WPARAM wp, LPARAM lp) {\r
-       return CallNextHookEx(0, code, wp, lp);\r
-}\r
-\r
 void CXkeymacsDll::SetHooks()\r
 {\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
-       g_hHookDummy = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)DummyProc, g_hDllInst, 0);\r
-       g_hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, 0);\r
+       m_bEnableKeyboardHook = true;\r
+}\r
+\r
+void CXkeymacsDll::SetKeyboardHook()\r
+{\r
+       if (!g_hHookKeyboard)\r
+               g_hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, GetCurrentThreadId());\r
 }\r
 \r
 inline void unhook(HHOOK &hh) {\r
@@ -316,15 +281,18 @@ void CXkeymacsDll::ResetHooks()
        SetHooks();\r
 }\r
 \r
-// release hooks\r
 void CXkeymacsDll::ReleaseHooks()\r
 {\r
        unhook(m_hHookCallWnd);\r
        unhook(m_hHookCallWndRet);\r
        unhook(m_hHookGetMessage);\r
        unhook(m_hHookShell);\r
+       m_bEnableKeyboardHook = false;\r
+}\r
+\r
+void CXkeymacsDll::ReleaseKeyboardHook()\r
+{\r
        unhook(g_hHookKeyboard);\r
-       unhook(g_hHookDummy);\r
 }\r
 \r
 void CXkeymacsDll::ToggleKeyboardHookState()\r
@@ -364,6 +332,7 @@ BOOL CXkeymacsDll::IsKeyboardHook()
 \r
 LRESULT CALLBACK CXkeymacsDll::CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)\r
 {\r
+       SetKeyboardHook();\r
        if (nCode < 0)\r
                return CallNextHookEx(m_hHookCallWnd, nCode, wParam, lParam);\r
        const CWPSTRUCT *cwps = reinterpret_cast<CWPSTRUCT *>(lParam);\r
@@ -410,11 +379,6 @@ LRESULT CALLBACK CXkeymacsDll::CallWndRetProc(int nCode, WPARAM wParam, LPARAM l
 LRESULT CALLBACK CXkeymacsDll::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)\r
 {\r
        const MSG *msg = reinterpret_cast<MSG *>(lParam);\r
-       if (msg->message == g_ImeManipulationMessage) {\r
-               if (wParam)\r
-                       CCommands::DoSetInputMethodOpenStatus(static_cast<INPUT_METHOD_OPEN_STATUS>(msg->wParam), static_cast<BOOL>(msg->lParam));\r
-               return 1;\r
-       }\r
        switch (msg->message) {\r
        case WM_IME_STARTCOMPOSITION:\r
                InitKeyboardProc(TRUE);\r
@@ -627,7 +591,7 @@ LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
 \r
 //     CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %p, %d, %d"), nCode, nOrigKey, lParam, IsDll64, Is64ProcessHwnd(GetForegroundWindow()));\r
 \r
-       if (Is64ProcessHwnd(GetForegroundWindow()) != IsDll64 || CUtils::IsXkeymacs() ||\r
+       if (!m_bEnableKeyboardHook || CUtils::IsXkeymacs() ||\r
                        nCode < 0 || nCode == HC_NOREMOVE)\r
                return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
 \r
index 1e98ada..beaaf79 100644 (file)
@@ -77,7 +77,9 @@ public:
        static void Clear(int nAppID);\r
        static BOOL IsKeyboardHook();\r
        static void ReleaseHooks();\r
+       static void ReleaseKeyboardHook();\r
        static void SetHooks();\r
+       static void SetKeyboardHook();\r
        static void ResetHooks();\r
        static void AddKillRing(BOOL bNewData = TRUE);\r
        static void CallMacro();\r
@@ -98,6 +100,7 @@ public:
        static BOOL SendIconMessage(ICONMSG *pMsg, DWORD num);\r
 \r
 private:\r
+       static bool m_bEnableKeyboardHook;\r
        static DWORD m_nHookAltRelease;\r
        static TCHAR m_M_xTip[128];\r
        static void InvokeM_x(const TCHAR* const szPath);\r
@@ -149,6 +152,4 @@ private:
        static CONFIG m_Config;\r
 };\r
 \r
-extern UINT g_ImeManipulationMessage;\r
-\r
 #endif // !defined(AFX_XKEYMACS_H__88552DEC_1233_4A0A_BE62_9EF7BC618EC6__INCLUDED_)\r