Winapi 正在寻找WaitForInputIdle函数的替代品,可随时使用

Winapi 正在寻找WaitForInputIdle函数的替代品,可随时使用,winapi,Winapi,我正在开发一个自动化程序,WaitForInputIdle函数帮助我确定目标应用程序的窗口何时完成初始化。问题是,在我的例子中,它只对第一个窗口起作用-这就是WaitForInputIdle的工作方式,只有一次 WaitForInputIdle的功能是否可以以不同的方式实现,以便每次目标进程繁忙时都可以调用它,并等待它完成 我想发布一条假消息,但我不认为有办法知道它何时从队列中移除 编辑:我想出了一个丑陋的、骇人的解决方案,似乎奏效了: RECT rc; if(!GetUpdateRect(h

我正在开发一个自动化程序,
WaitForInputIdle
函数帮助我确定目标应用程序的窗口何时完成初始化。问题是,在我的例子中,它只对第一个窗口起作用-这就是
WaitForInputIdle
的工作方式,只有一次

WaitForInputIdle
的功能是否可以以不同的方式实现,以便每次目标进程繁忙时都可以调用它,并等待它完成


我想发布一条假消息,但我不认为有办法知道它何时从队列中移除

编辑:我想出了一个丑陋的、骇人的解决方案,似乎奏效了:

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
,正如陈雷蒙所建议的那样,对我很有效

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

旧信息:我想出了一个解决我问题的解决方案,仍然是一个黑客,但没有那么丑陋

这个想法是误用了
PrintWindow
函数,它基本上是POST发送WM_PAINT消息并等待窗口处理它——这正是我所需要的。 下面是带有一些信息性注释的代码

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

// 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,以尽量减少可能的副作用。这些都不能保证,你不知道程序响应后会做什么。评论是不正确的<代码>打印窗口不发布
WM_PAINT
。它发送它。我假设它是发布的,因为a)
WM_PAINT
通常不发送,b)
PrintWindow
是在ring0中实现的,所以我假设它使用了某种黑魔法。Wine实际上只是发送了一条消息:向窗口发送一条WM_NULL消息。谢谢Raymond,这对我的案子起到了作用。事实上,我曾考虑过使用WM_NULL,但我认为它不起作用,因为发送的消息可以在各种意外情况下进行处理,例如
TrackPopupMenu
SendMessage
,可能还有我不知道的其他函数。它与您的
PrintWindow
方法一样工作,它会发送一条
WM_PAINT
消息。(
WM_PAINT
大部分是发布的,但是如果有人在等待结果,它会被发送,就像你一样。)“我想发布一条假消息,但我认为没有办法知道它何时从队列中删除。”-你可以使用WH_GETMESSAGE钩子来实现这一点。您可以使用GetWindowThreadProcessId()将钩子限制为仅拥有您要发布到的窗口的线程。WH_XXX钩子涉及DLL注入,这对于我的需要来说太重了。事实上,我偶然发现了
WH\u FOREGROUNDIDLE
,这可能正是我所需要的,但它不适合相同的原因。现在我使用的是
WM_NULL
方法,对于特定的应用程序,我使用的是
getupdate
方法。