【问题标题】:Looking for an alternative to the WaitForInputIdle function, available at any time寻找 WaitForInputIdle 函数的替代方案,随时可用
【发布时间】:2013-06-22 22:37:22
【问题描述】:

我正在开发一个自动化程序,WaitForInputIdle 函数帮助我确定目标应用程序的窗口何时完成初始化。问题是,就我而言,它只适用于第一个窗口——WaitForInputIdle 就是这样工作的,只有一次。

WaitForInputIdle 的功能能否以不同的方式实现,这样每次目标进程忙时都可以调用它,并等到它完成?

我考虑过发布一条虚拟消息,但我认为没有办法找出它何时从队列中删除。

编辑:我想出了一些东西,一个看起来很有效的丑陋和 hacky 解决方案:

RECT rc;

if(!GetUpdateRect(hWnd, &rc, FALSE))
{
    rc.left = rc.top = 0;
    rc.right = rc.bottom = 1;
    InvalidateRect(hWnd, &rc, FALSE);
}

do {
    Sleep(100);
} while(GetUpdateRect(hWnd, &rc, FALSE));

我真的希望有比这更好的东西。

【问题讨论】:

  • 向窗口发送 WM_NULL 消息。
  • 谢谢雷蒙德,这对我的情况有用。事实上,我考虑过使用 WM_NULL,但我认为它不会起作用,因为发送的消息可以在各种意想不到的场景中处理,例如TrackPopupMenuSendMessage 可能还有其他我不知道的功能。
  • 它与您的 PrintWindow 方法一样有效,该方法发送 WM_PAINT 消息。 (WM_PAINT 主要是发布,但如果有人在等待结果,就会发送,就像你一样。)
  • “我想过发布一条虚拟消息,但我认为没有办法找出它何时从队列中删除。” - 您可以为此使用 WH_GETMESSAGE 挂钩。您可以使用 GetWindowThreadProcessId() 将挂钩限制为仅拥有您要发布到的窗口的线程。
  • WH_XXX 挂钩涉及 DLL 注入,这对我的需求来说太重了。事实上,我偶然发现了WH_FOREGROUNDIDLE,这可能正是我所需要的,但出于同样的原因它不适合。目前我使用的是WM_NULL 方法,对于特定的应用程序-GetUpdateRect 方法。

标签: winapi


【解决方案1】:

编辑:按照 Raymond Chen 的建议发送 WM_NULL 对我有用。

PrintWindow hack 似乎没有任何优势,因为它在内部只是发送 WM_PAINT 消息。

旧消息:我想出了一个解决我的问题的解决方案,仍然是一个 hack,但没有那么难看。

这个想法是滥用PrintWindow 函数,它基本上 posts 发送一条 WM_PAINT 消息并等待窗口处理它——这正是我所需要的。 下面是一些信息丰富的 cmets 的代码。

它在 Windows XP 和 Windows 8 上进行了测试,并且按预期工作,即尽管 HDC 值为 NULL,但它不会失败。

// BEWARE: HACK BELOW
// PrintWindow is misused here as a synchronization tool
// When calling it, the system sends WM_PAINT and waits for it to be processed
// Note: if hWnd is hung, the following call will hang as well
PrintWindow(hWnd, NULL, 0);

【讨论】:

  • 这是使用 SendMessage 代替 PostMessage 的一种非常精细的方法。否则是使程序崩溃的好方法。
  • 好吧,改用 SendMessage。发送一些无辜的东西,比如 WM_GETTEXTLENGTH,以尽量减少可能的副作用。这些实际上都不能提供保证,您不知道程序响应后会做什么。
  • 评论不正确。 PrintWindow 不发布 WM_PAINT。它发送它。
  • 我认为它被发布是因为 a) WM_PAINT 通常不发送,b) PrintWindow 在 ring0 中实现,所以我认为它使用了某种黑魔法。不过,Wine 实际上只是发送一条消息:source.winehq.org/source/dlls/user32/painting.c#L1699
猜你喜欢
  • 2011-11-14
  • 1970-01-01
  • 2021-12-14
  • 2016-06-04
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
相关资源
最近更新 更多