简体   繁体   English

确定进程的输入线程 ID

[英]Determine Input Thread ID of a Process

Does anyone know of a way to determine the input thread of a process?有谁知道确定进程输入线程的方法?

The scenario is that I would like to call GetKeyboardLayout , passing in the input thread ID from within a separate application (could be any program).这种情况是我想调用GetKeyboardLayout ,从单独的应用程序(可以是任何程序)中传入输入线程 ID。 Each thread can have its own keyboard input language set, but finding out the appropriate input thread ID for another process seems like something that perhaps isn't possible.每个线程都可以有自己的键盘输入语言集,但是为另一个进程找到合适的输入线程 ID 似乎是不可能的。

For example, I create a function into which I pass the process ID of Notepad, this function internally determines the input thread ID and returns the value from GetKeyboardLayout.例如,我创建了一个函数,将记事本的进程 ID 传递给该函数,该函数在内部确定输入线程 ID 并从 GetKeyboardLayout 返回值。 The caller of this function would then display on-screen the input language selected for Notepad.然后,此函数的调用者将在屏幕上显示为记事本选择的输入语言。

Any of you fine folks have any ideas?你们中的任何一个好人有什么想法吗?

Windows doesn't require a process to have a specific thread that interacts with the user. Windows 不需要进程具有与用户交互的特定线程。 It doesn't have to be the startup thread of the process, although it often is.它不一定是进程的启动线程,尽管它经常是。 And it doesn't limit a program to a single thread, although it often does use only one thread.并且它不会将程序限制为单个线程,尽管它通常只使用一个线程。

You'll need to start by finding the window first.您需要首先找到窗口。 With api functions like FindWindow, FindWindowEx or EnumWindows.使用诸如 FindWindow、FindWindowEx 或 EnumWindows 之类的 api 函数。 Once you got that, you can find out what thread owns the window with GetWindowThreadProcessId().一旦你得到了它,你就可以用 GetWindowThreadProcessId() 找出哪个线程拥有这个窗口。 Watch out for hidden helper windows that a worker thread might create.注意工作线程可能创建的隐藏帮助窗口。 Spy++ is your basic debugging tool here. Spy++ 是您在这里的基本调试工具。

You might try that, it walks thru all toplevel-windows and searches for the one belonging to the process-id:您可以尝试这样做,它会遍历所有顶级窗口并搜索属于进程 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);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM