利用 AttachThreadInput 和 WM_INPUTLANGCHANGEREQUEST 消息 改變 其它 進程 的 輸入 狀態 ? 衆所周知,經過 ActivateKeyboardLayout 函數能夠 改變 當前線程的 輸入 法 狀態 ,不過最近發現經過 AttachThreadInput 和 WM_INPUTLANGCHANGEREQUEST 連用能夠函數
利用 AttachThreadInput 和 WM_INPUTLANGCHANGEREQUEST 消息改變其它進程的輸入狀態spa
?線程
衆所周知,經過 ActivateKeyboardLayout 函數能夠改變當前線程的輸入法狀態,不過最近發現經過 AttachThreadInput 和 WM_INPUTLANGCHANGEREQUEST 連用能夠改變任意進程內線程的輸入法狀態,代碼以下:code
?blog
如下代碼經過 GetKeyboardLayoutList 取得首選的中文輸入法的 HKL(Keybroad Layout Handle):進程
?get
HKL g_hklRPC = NULL; BOOL InitHklRPC() { // Find RPC hkl UINT nMaxHklCnt = GetKeyboardLayoutList(0, NULL); HKL* p_hklList = (HKL*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nMaxHklCnt * sizeof(HKL)); UINT nHklCnt = GetKeyboardLayoutList(nMaxHklCnt, p_hklList); for(UINT i=0;i<nHklCnt;i++) { if(LOWORD(p_hklList[i]) == 0x0804) { g_hklRPC = p_hklList[i]; break; } } HeapFree(GetProcessHeap(), NULL, p_hklList); return (g_hklRPC == NULL)? FALSE : TRUE; }
?it
有關 HKL 參見 MSDN「Languages, Locales, and Keyboard Layouts」,HKL 實際上是一個混合值,Loword 是一個 Language IDentifier,Hiword 是一個 Device Handle。以上代碼只是簡單的經過檢查HKL的低字是否爲中文 RPC(0x804),並取回第一個中文 RPC 的 HKL。class
?List
有了 HKL,有趣的節目開始了~~~? 注意,如下代碼把當前 focus 所在窗口的輸入法狀態設爲中文:
?
HWND hWnd = GetForegroundWindow(); ASSERT(IsWindow(hWnd)) // Get Target Thread ID and Attach Thread Input DWORD ProcID; DWORD ThreadID = GetWindowThreadProcessId(hWnd, &ProcID); AttachThreadInput(GetCurrentThreadId(), ThreadID, TRUE); // Get Target Window HWND hWndFocus = GetFocus(); // Post Input Messages ASSERT(IsWindow(hWndFocus)); // Change Input Language PostMessage(hWndFocus, WM_INPUTLANGCHANGEREQUEST, (WPARAM)TRUE, (LPARAM)g_hklRPC); // Use Language ID 0x0804(Chinese PRC) // Detach Thread Input AttachThreadInput(GetCurrentThreadId(), ThreadID, FALSE);
?
以上代碼十分清晰,我就不解說了。