// virtual
BOOL CMyApp::PumpMessage()
{
DWORD const res = ::MsgWaitForMultipleObjects
(1, &handle_I_am_interested in, TRUE, INFINITE, QS_ALLINPUT);
switch (res)
{
case WAIT_OBJECT_0 + 0:
// the handle was signalled, strut your stuff here
return TRUE;
case WAIT_OBJECT_0 + 1:
// there is a message in the queue, let MFC handle it
return __super::PumpMessage();
}
// Shouldn't happen
return TRUE;
}
5 回答
我会做这两个中的一个:
在某个地方的消息循环中调用
WaitForSingleObject()
或超时为零的任何内容(可能必须将循环更改为PeekMessage()
或添加WM_TIMER
消息以确保每隔一段时间检查一次)或者更好的是,产生一个具有非常小的堆栈的线程(您可以在
CreateThread()
调用中自定义)仅等待此子进程,然后将消息发布到您的消息循环 .我更喜欢选项2,因为一个小堆栈的线程除了等待东西之外什么都不做,这几乎不是资源消耗 .
当进程结束时,您可以使用RegisterWaitForSingleObject()通过回调获得通知 .
RegisterWaitForSingleObject
函数指示thread pool中的等待线程等待进程,因此这应该是资源的最佳使用 . 正如Raymond Chen评论的那样:下面是Win32 GUI应用程序的最小示例 . 代码创建一个窗口,然后它创建自己的另一个实例作为子进程,由"/child"参数指示 . 它注册等待回调函数并运行常规消息循环 . 您可以调整窗口大小并移动窗口以查看GUI未被阻止 . 当子进程结束时,系统异步调用等待回调,该回调将应用程序定义的消息(
WM_APP
)发布到窗口 . 当窗口收到消息时,它立即调用UnregisterWait()
取消等待 . 作为参考状态,在等待完成时必须取消使用WT_EXECUTEONLYONCE
的等待操作(但不是在回调中!) . 然后窗口显示一个消息框,以证明它已收到消息 .为简洁起见,省略了错误处理 . 您应检查每个API函数的返回值,并在返回
FALSE
时调用GetLastError()
.Bonus OldNewThing read :Why bother with RegisterWaitForSingleObject when you have MsgWaitForMultipleObjects?
如果您可以修改子进程的代码,您可以添加一个反向通道,该通道将在它即将离开时通过
SendMessage
通知父进程 . 如果你不能这样做,你可以创建一个中继过程,它只传递原始的子过程数据(如果有的话),但会在孩子离开时完成信息工作 . 当然,这至少要比仅仅使用专用线程和例如线程要少得多 .WaitForSingleObject
.解决方案是在创建应用程序时创建一个线程 . 然后等待一个应该在需要时发出脉冲的事件 . 例:
触发线程进入操作:
你的应用程序结束时销毁线程:
好消息! Windows拥有您正在寻找的API:MsgWaitForMultipleObjects () .
Tricker,是为了让它进入MFC的消息泵,但是我发现this link建议执行以下操作(代码未经测试,修复(!),并且适合仅在一个句柄上等待):
我不得不说这段代码对我来说仍然不太理想,但它可能足够接近 . 我不太了解MFC进一步评论 .
Please note: 在MFC通过消息泵之前,此代码不会看到句柄已发出信号 . 例如,当
MessageBox()
具有控制权时,可能会发生这种情况 . 如果这让您感到困扰,请考虑使用RegisterWaitForSingleObject,正如传奇Raymond Chen所推荐的那样 .