确定进程的输入线程 ID

Determine Input Thread ID of a Process

本文关键字:线程 ID 输入 进程      更新时间:2023-10-16

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

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

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

你们这些好人有什么想法吗?

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

您需要首先找到窗口。 具有 FindWindow、FindWindowEx 或 EnumWindows 等 api 函数。 一旦你得到它,你可以找出哪个线程拥有这个窗口与GetWindowThreadProcessId()。 注意工作线程可能创建的隐藏帮助程序窗口。 Spy++是这里的基本调试工具。

你可以试试,它会遍历所有顶级窗口并搜索属于进程 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=%xn", 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);
  }
}