显示断言对话框时提供 Windows 消息服务吗?
我有一个 MFC 应用程序,它生成许多不同的工作线程,并使用 VS2003 进行编译。
当调用 CTreeCtrl::GetItemState() 时,我偶尔会弹出一个调试断言对话框。我假设这是因为我传递了一个无效项目的句柄,但这不是我直接关心的问题。
我担心的是:从我的日志来看,在显示断言对话框的同时,MFC 线程似乎继续为许多 Windows 消息提供服务。我认为断言对话框是模态的,所以我想知道这是否可能?
I have an MFC application that spawns a number of different worker threads and is compiled with VS2003.
When calling CTreeCtrl::GetItemState() I'm occasionally getting a debug assertion dialog popup. I'm assuming that this is because I've passed in a handle to an invalid item but this isn't my immediate concern.
My concern is: From my logs, it looks as though the MFC thread continues to service a number of windows messages whilst the assert dialog is being displayed. I thought the assert dialog was modal so I was wondering if this was even possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
显示断言失败的消息框有一个用于其自身目的的消息泵。但它会调度所有传入的消息,而不仅仅是消息框的消息(否则可能会被阻止)。
对于普通的模式对话框,这不是问题,因为父窗口通常在对话框期间处于禁用状态。
启动断言对话框的代码一定无法找出父窗口,因此它没有被禁用。如果您的主窗口在断言时不是活动窗口,则可能会发生这种情况。其他事情也可能出错。
您可以使用 _CrtSetReportMode。您可以使其在调试器中停止和/或记录到输出窗口,而不是尝试显示对话框。
The message box that shows the assertion failure has a message pump for its own purposes. But it'll dispatch all messages that come in, not just those for the message box (otherwise things could get blocked).
With a normal modal dialog, this isn't a problem because the parent window is typically disabled for the duration of the dialog.
The code that launches the assertion dialog must've failed to figure out the parent window, and thus it wasn't disabled. This can happen if your main window isn't the active window at the time of the assertion. Other things can go wrong as well.
You can change how Visual Studio's C run-time library reports assertion failures with _CrtSetReportMode. You can make it stop in the debugger and/or log to the output window instead of trying to show the dialog.
对话框(甚至消息框)需要泵送消息队列,即使它们是模态的。否则他们怎么知道你点击了“确定”按钮?
如果您需要在断言触发时停止所有操作,那么编写自己的
assert()
(或ASSERT()
或其他)实现通常不会太困难,该实现将中断调试器,而不是显示一个消息框,询问您是否要中断调试器(可能仅当它确定已附加调试器时)。Dialogs (even a messagebox) need to pump the message queue, even if they're modal. Otherwise how would they know you clicked on the "OK" button?
If you need to stop everything when an assert triggers it's usually not too difficult to write your own implementation of
assert()
(orASSERT()
or whatever) that will break into the debugger instead of displaying a messagebox that asks if you want to break into the debugger (maybe only if it determines that the debugger is attached).