确定进程的输入线程ID

时间:2012-11-24 15:11:43

标签: c++ windows winapi

有谁知道确定进程输入线程的方法?

场景是我想调用GetKeyboardLayout,从单独的应用程序(可能是任何程序)中传入输入线程ID。每个线程都可以拥有自己的键盘输入语言集,但是为另一个进程找到合适的输入线程ID似乎是可能无法实现的。

例如,我创建了一个函数,我传递了Notepad的进程ID,该函数在内部确定输入线程ID并从GetKeyboardLayout返回值。然后,此功能的调用者将在屏幕上显示为记事本选择的输入语言。

你们中的任何一个人都有什么想法吗?

2 个答案:

答案 0 :(得分:2)

Windows不需要进程具有与用户交互的特定线程。它不一定是该过程的启动线程,尽管它经常是。并且它不会将程序限制为单个线程,尽管它通常只使用一个线程。

您需要先找到窗口。使用FindWindow,FindWindowEx或EnumWindows等api函数。一旦你得到了,你可以通过GetWindowThreadProcessId()找出该窗口拥有的线程。注意工作线程可能创建的隐藏辅助窗口。 Spy ++是你的基本调试工具。

答案 1 :(得分:1)

你可以尝试一下,它遍历所有toplevel-windows并搜索属于process-id的那个:

// complle and link with: cl layout.cxx user32.lib
#include <windows.h>
#include <stdio.h>
#include <assert.h>
DWORD desiredProcId;
BOOL CALLBACK enumCallBack(HWND hwnd, LPARAM lParam) {
  DWORD procId;
  DWORD winThread=GetWindowThreadProcessId(hwnd, &procId);
  if (procId==desiredProcId) {
    HKL hkl=GetKeyboardLayout(winThread);
    char buf[1000];
    GetWindowText (hwnd, buf, sizeof(buf));
    printf ("hwnd=%x name=%s, winThread=%x, HKL=%x\n", hwnd, buf, winThread, hkl);
    return false;
  }
  return true; 
}
int main (int argc, char *argv[]) {
  if (argc==1) {
    printf ("usage: %s processId (in decimal like from taskmanager)\n", argv[0]);
  }
  else {
    sscanf (argv[1], "%d", &desiredProcId);
    EnumWindows (enumCallBack, 0);
  }
}