【问题标题】:How does windows OS determine to which window a message should be postedwindows操作系统如何确定应该将消息发布到哪个窗口
【发布时间】:2020-07-11 04:53:20
【问题描述】:

问题:

假设我有一个带有主窗口和子窗口的进程。当我使用键盘键入时,操作系统如何确定要向其发送 WM_KEYDOWN 消息的 HWND?

我知道事件循环和函数GetMessage、TranslateMessage和DispatchMessage,但我不明白hwnd字段是如何在MSG结构中设置的。

示例:

使用 Spy++ 我看到有时子窗口会收到 WM_KEYDOWN 消息,有时会收到父窗口。

在 winforms 中,具有焦点的文本框接收消息。但是在其他 UI 中,消息会跳过子窗口并直接发布到主窗口。

【问题讨论】:

  • 进入焦点窗口。
  • GUITHREADINFO::hwndFcous。还有Keyboard input model。子窗口可以通过捕获WM_SETFOCUS 并将焦点设置到其父窗口来拒绝焦点。
  • "但是在其他 UI 中,消息会跳过子窗口并直接发布到主窗口。"你能举一个这种用户界面的例子吗?
  • @RitaHan-MSFT ,这是一个大型机模拟器。我不知道我是否可以提及 UI 的名称,但基本上它有一个顶级窗口和一个子窗口,即终端本身,但是子窗口不接收键盘输入,只有父窗口。我猜在这个特定的应用程序中,只有顶级窗口具有键盘焦点并处理键盘事件。
  • @EtanGrundstein:GetGUIThreadInfo 也应该适用于其他进程。如果您明确将WM_KEYDOWN 发送给孩子,它可以以编程方式将其重新发送给其父母。这只是几行代码。这种转发甚至可以是有条件的,具体取决于密钥和其他因素; Windows 对这种逻辑一无所知。 Windows 只处理第一次传递给焦点 HWND。

标签: windows winapi


【解决方案1】:

输入被发送到有焦点的窗口

根据 MSalters 的评论:

GITHREADINFO 结构包含变量:

HWND  hwndFocus;

Type: HWND

A handle to the window that has the keyboard focus.

这是默认行为。如果程序将消息转发到另一个窗口,则该行为是由开发人员实现的。

检测和处理输入的方法有很多,但标准方法是使用消息队列。您可能会发现程序在没有焦点的情况下检测输入,这可能是因为它们使用了另一种读取输入的方法,例如 GetKeyboardState()。

【讨论】:

  • 感谢您的回答。似乎 GetGUIThreadInfo 可以解决问题。但是,当我从不同的进程运行 GetGUIThreadInfo 时,只有当目标进程中的窗口被激活时,它才会返回带有非空白字段的 GUITHREADINFO 结构。 (我用不同的应用程序检查过,记事本就是其中之一)。有没有办法让结构充满没有激活的窗口?
  • @EtanGrundstein "如果指定的线程不存在或没有输入队列,函数将失败。"也许这意味着当窗口不活动/焦点输入队列不存在时?不确定
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2011-10-07
  • 2022-10-13
  • 2011-12-24
  • 1970-01-01
相关资源
最近更新 更多