【问题标题】:How does GetGuiThreadInfo() work?GetGuiThreadInfo() 是如何工作的?
【发布时间】:2010-03-26 18:33:37
【问题描述】:

我正在尝试获取当前聚焦窗口的 HWND 和 ThreadID。

通常 GetForegroundWindow() 然后调用 GetThreadProcessId() 会给我正确的信息。

但是在 IE8 的情况下,GetForegroundwindow() 的 HWnd 给了我 IE 框架的 HWND,但实际上焦点窗口(文档对象或 Internet Explorer_server)是不同的(在不同的进程中运行)。所以 GetForegroundWindow() 方法不起作用。

所以我使用了 GetGuiThreadInfo(DWORD tid) ,并将我从 GetForegroundWindow 获得的 threadId 传递给它。类似这样的东西;

DWORD tid = GetWindowThreadProcessId(GetForegroundWindow(),0);
GetGuiThreadInfo(tid,&guiThreadInfoObject);
HWND focus = guiThreadInfoObject.hwndFocus;

使用上述方法,我得到了正确的 Internet Explorer_server 对象的 HWND。 但是我不明白,即使 GetGuiThreadInfo() 正在获取不同进程(即 IE 框架)中的线程的 ThreadId ,为什么它能够让我获得有关位于不同进程和线程上的 Internet Explorer_server 对象的线程信息?

谢谢

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    使用 GetFocus() 很容易获得具有焦点的窗口。虽然我认为 GetGuiThreadInfo() 使用来自窗口管理器的内部数据。如果 IE 被最小化或没有焦点,您的方法可能会失败。

    改为使用 EnumChildWindows(),对您找到的每个子项进行迭代,直到您获得一个窗口,其 GetClassName() 调用返回“Internet Explorer_Server”。

    感谢您提出这个问题。 SetParent() 的文档中明确禁止 IE 所做的事情。我只知道 Acrobat 违反了此规则,但现在您提供了 Microsoft 程序这样做的证据。这样就解决了,这不再是规则!

    【讨论】:

    • 谢谢,但 GetFocus() 总是返回 0,因为具有焦点的窗口位于不同的线程上。应用程序可以是任何东西..IE8 只是其中之一。所以我想要一些通用的东西,所以我不能使用 EnumChildWindows() 来寻找 Internet Explorer_server 。
    • “通用的东西”没有意义。如果你想弄乱另一个进程的窗口,你需要自定义你的代码来处理特定的进程及其实现细节。
    【解决方案2】:

    GetWindowThreadProcessId 检索创建(在您的情况下为前台)窗口的线程 ID。
    guiThreadInfoObject.hwndFocus 是具有输入焦点的窗口。

    这里有一些余地 - 我还没有找到任何地方专门说明前景窗口是具有输入焦点的窗口。 (也许它已经检索到顶级父/所有者?)。

    此外,AttachThreadInput 可能会稍微改变游戏 - 通过将线程输入焦点设置到不同进程的窗口。

    无论如何,由于没有明确说明,我不会把我的生命押在这种行为上 - 这意味着要在许多系统上进行测试,并将该方法视为一个弱点,如果可能的话应该加以改进。

    【讨论】:

    • 谢谢。现在,当我得到正确的结果时……这是否意味着情况总是如此。意思是我想知道这是否是 GetGUIThreadInfo() 方法的预期行为,它对于任何其他应用程序的行为是否与 IE8 一样。
    • 正如我所说,这是有道理的,但在文档中没有明确说明。
    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 2010-10-17
    • 2017-07-24
    • 2016-11-13
    • 2017-10-11
    • 2021-10-13
    • 2011-02-24
    • 2013-11-16
    相关资源
    最近更新 更多