return Reset(GOTO_HOOK);\r
}\r
\r
-void CCommands::SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete)\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
{\r
ClearNumericArgument();\r
HKL hKL = GetKeyboardLayout(0);\r
Kdu(VK_KANJI);\r
} else if (ImmIsIME(hKL)) {\r
// default\r
- HWND hWnd = GetFocus();\r
+ HWND hWnd = ObtainFocus();\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
if (isComplete && ImmGetOpenStatus(hIMC)) {\r
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);\r
\r
static AFX_EXTENSION_MODULE XkeymacsdllDLL = { NULL, NULL };\r
\r
-static __declspec(thread) HINSTANCE g_hDllInst = NULL;\r
-static __declspec(thread) HHOOK g_hHookKeyboard = NULL;\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
+ 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
+ SYSTEM_INFO info;\r
+ GetNativeSystemInfo(&info);\r
+ return info.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL;\r
+}\r
+\r
+inline bool Is64Process(HANDLE mod) {\r
+ return Is64System() && !IsWow64(mod);\r
+}\r
+\r
+const bool IsDll64 = sizeof(void *) == 8;\r
+\r
+inline bool Is64ProcessHwnd(HWND hwnd) {\r
+ DWORD pid;\r
+ GetWindowThreadProcessId(hwnd, &pid);\r
+ HANDLE hmod = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);\r
+ bool b = Is64Process(hmod);\r
+ CloseHandle(hmod);\r
+ return b;\r
+}\r
\r
extern "C" int APIENTRY\r
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
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
e->Delete();\r
// CUtils::Log("DllMain: 'new' threw an exception");\r
}\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
+ break;\r
}\r
return 1; // ok\r
}\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
}\r
\r
void CXkeymacsDll::EnableKeyboardHook()\r
m_bEnableKeyboardHook = TRUE;\r
}\r
\r
-void CXkeymacsDll::SetKeyboardHook()\r
+inline void unhook(HHOOK &hh) {\r
+ if (hh)\r
+ UnhookWindowsHookEx(hh);\r
+ hh = NULL;\r
+}\r
+\r
+void CXkeymacsDll::ResetHook() \r
{\r
- if (!g_hHookKeyboard)\r
- SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, GetCurrentThreadId());\r
+ unhook(m_hHookCallWnd);\r
+ unhook(m_hHookCallWndRet);\r
+ unhook(m_hHookGetMessage);\r
+ unhook(m_hHookShell);\r
+ unhook(g_hHookKeyboard);\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_hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, 0);\r
}\r
\r
// release hooks\r
void CXkeymacsDll::ReleaseHooks()\r
{\r
m_bEnableKeyboardHook = FALSE;\r
- if (m_hHookCallWnd)\r
- UnhookWindowsHookEx(m_hHookCallWnd);\r
- m_hHookCallWnd = NULL;\r
- if (m_hHookCallWndRet)\r
- UnhookWindowsHookEx(m_hHookCallWndRet);\r
- m_hHookCallWndRet = NULL;\r
- if (m_hHookGetMessage)\r
- UnhookWindowsHookEx(m_hHookGetMessage);\r
- m_hHookGetMessage = NULL;\r
- if (m_hHookShell)\r
- UnhookWindowsHookEx(m_hHookShell);\r
- m_hHookShell = NULL;\r
-}\r
-\r
-void CXkeymacsDll::ReleaseKeyboardHook()\r
-{\r
- if (g_hHookKeyboard)\r
- UnhookWindowsHookEx(g_hHookKeyboard);\r
- g_hHookKeyboard = NULL;\r
+ unhook(m_hHookCallWnd);\r
+ unhook(m_hHookCallWndRet);\r
+ unhook(m_hHookGetMessage);\r
+ unhook(m_hHookShell);\r
+ unhook(g_hHookKeyboard);\r
+ unhook(g_hHookDummy);\r
}\r
\r
void CXkeymacsDll::SetKeyboardHookFlag(BOOL bFlag)\r
LRESULT CALLBACK CXkeymacsDll::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)\r
{\r
MSG &msg = (*(MSG *)lParam);\r
-\r
+ if (msg.message == g_ImeManipulationMessage) {\r
+ if (wParam)\r
+ CCommands::DoSetInputMethodOpenStatus((INPUT_METHOD_OPEN_STATUS)msg.wParam, msg.lParam);\r
+ return 1;\r
+ }\r
switch (msg.message) {\r
case WM_IME_STARTCOMPOSITION:\r
InitKeyboardProc(TRUE);\r
static BYTE nOneShotModifier[MAX_KEY] = {'\0'};\r
static BOOL bCherryOneShotModifier = FALSE;\r
\r
-// CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %#x"), nCode, nKey, lParam);\r
+// CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %p, en = %d, %d, %d"), nCode, nKey, lParam, m_bEnableKeyboardHook, IsDll64, Is64ProcessHwnd(GetForegroundWindow()));\r
\r
- if (!m_bEnableKeyboardHook)\r
+ if (Is64ProcessHwnd(GetForegroundWindow()) != IsDll64 || CUtils::IsXkeymacs())\r
return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
\r
if (nCode < 0 || nCode == HC_NOREMOVE) {\r