利用 AttachThreadInput 改變其它進程的輸入法狀態

利用 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);

?

以上代碼十分清晰,我就不解說了。

相關文章
相關標籤/搜索