我们有一个MFC Visual-C ++应用程序,它不会对任何用户输入做出反应。
(注意:目前只在一台机器上才知道。行为偶尔会重复出现,但只有在应用程序运行了好几天后才会出现!)
当我们通过Alt-Tab(或任务栏)切换到应用程序 时重新绘制它,但是我们不能通过单击标题栏来激活它的主窗口。
我们已经使用WinDbg提取了4个转储并检查了有效指令。我们总是在一些重绘代码或主线程内部(GUI线程)。我们肯定在模态消息循环中不并且主线程的堆栈总是看起来“OK”。 (大多数/所有工作线程都在闲置,等待某个事件,也没有可疑代码。)
在使用Spy++调查问题时,我们也看到了in this separate question指定的行为,即我们似乎得到了绘制和激活消息,但是没有用户输入被路由到应用程序< / strong>即可。当我在屏幕上显示应用程序窗口,并选择它以显示主窗口的消息时,
它只会显示“通用”“referesh”消息,而不显示任何其他内容
如果我深入钻取,并选择整个过程的所有消息,
这就是我们所看到的:
该应用程序显然只处理一个隐藏子窗口(00CB09F0)上的消息,我们看到的是每秒 200 WM_PAINT消息的持续流。
通常,此子窗口根本不处理任何消息(Windows发送时刷新WM_PAINT等除外)。它通常用作绘图区域,绘图通过其父(010A09B8)窗口上的WM_TIMER消息进行。 (但是这个WM_TIMER消息不会显示在挂起的应用程序上。)
process explorer中显示的性能配置文件如下所示(100%内核时间,或多或少):
答案 0 :(得分:0)
我会说你在该窗口中有一个重绘循环,它接收WM_PAINT泛洪。
如果您通过直接或间接处理WM_PAINT消息来调用Invalidate
或类似内容,通常会发生这种情况。
其他可能性是,因为你说你正在使用计时器来重绘窗口,所以实际绘图花费的时间比自己的时间长,因此消息堆积在队列中。
另一个可能性是你从不同的线程使窗口无效而不是制作绘画的那个。
无论如何,您应该确保正确地调用Invalidate*()
(您没有显示代码),并且绝不会来自OnPaint
事件。并且避免调用UpdateWindow()
,因为如果在没有一点小心的情况下调用它,这个函数就会弄乱。
答案 1 :(得分:0)
当从对话框中抛出异常时,我已经看到了这个问题。 MFC的DoModal函数禁用主程序窗口,然后在对话框返回时重新启用它;异常绕过重新启用部分,主窗口永远保持禁用状态。