利用 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);
?
以上代码十分清晰,我就不解说了。