【问题标题】:Determine Input Thread ID of a Process确定进程的输入线程 ID
【发布时间】:2012-11-25 00:24:38
【问题描述】:

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

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

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

各位好心人有什么想法吗?

【问题讨论】:

  • 哦,并且没有创建系统范围的挂钩来捕获 WM_INPUTLANGCHANGE。并不是说我肯定会 100% 覆盖它,但这根本不是一个选择(就我的情况而言)。
  • 如果您对某个特定窗口感兴趣,可以使用GetWindowThreadProcessId 获取创建该窗口的线程的线程ID。

标签: c++ windows winapi


【解决方案1】:

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

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

【讨论】:

  • 对,我就是这么想的。但是,通常这是可以接受的,因为这是针对我的程序的单个用户的自定义请求,因此“由于不确定的因素,它可能并不总是有效”的警告很好。我的程序(StrokesPlus)的性质已经有了鼠标手势开始的窗口句柄,所以这是一个超级简单的添加,因为它使用 Lua,我什至不必重新编译,只需绑定到 user32 和 viola!非常感谢大家。
【解决方案2】:

你可以试试,它会遍历所有顶层窗口并搜索属于 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);
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多