为什么不显示消息框? [英] Why would a message box be not displaying?

查看:19
本文介绍了为什么不显示消息框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 MFC 项目有一个非常奇怪的窗口模式设置.我认为这种设置搞砸了自有消息框的显示方式.

I am on a MFC project that has a very strange windowing mode setup. I think this setup is screwing up how a owned message box is being displayed.

在按下 ALT 键之前,消息框将不可见.

What is happening is that the message box will not be visible until the ALT key is pressed.

我仍在尝试围绕他们正在使用的窗口设置进行思考,但也许有人可以给我一个线索,让我知道要寻找什么?

I'm still trying to wrap my head around the window setup they are using, but perhaps someone would be able to give me a clue as to what to look for?

我编写了一个解决方法,我将所有者窗口和消息框的标题传递给一个类,该类生成一个线程,该线程遍历所有窗口并找到一个由指定所有者拥有的消息框对话框,该对话框具有指定的标题.但是,我必须搜索和替换 1000 多个实例才能使其在系统范围内工作.

I wrote a workaround where I pass the owner window and the title of the message box to a class which spawns a thread that goes through all the windows and finds a message box dialogue that is owned by the specified owner with the title specified. However, I would have to do a search and replace of over 1000 instances to get this to work system wide.

更好的选择是找到根本原因.但是这其中的复杂性是相当令人生畏的.任何我应该寻找的可能导致这种行为的线索将不胜感激.

A better option would be to find the root cause. But the complexity of this is quite daunting. Any clues to what I should be looking for which could cause this behaviour would be greatly appreciated.

推荐答案

这是由 MFC CDialog DoModal 不能显示窗口如果父窗口消息队列是'忙' '功能' 如果消息队列包含任何消息,则不会显示系统消息框.(请对该错误进行投票或评论.这种行为非常出乎意料.)

This is caused by the MFC CDialog DoModal can't show window if parent window message queue is 'busy' 'feature' where if the message queue contains any messages, it will not show the system message box. (Please vote or comment on that bug. The behaviour is very unexpected.)

我通过尝试使用以下方法抓取队列中的所有消息来追踪这一点:

I tracked this down by trying to slurp up all of the messages in the queue using this:

MSG msg = { 0 };
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
    TRACE(_T(R"--(,"% *.*s",PEEK,0x%08x,"%s",0x%08x,0x%08x,0x%08x)--" "
"),
              0, 0, _T(""), msg.hwnd, "Window HAS msg",
              msg.message, msg.wParam, msg.lParam);
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

这将输出队列中的所有消息,并向我显示哪个窗口和什么消息(在本例中为 WM_PAINT)是违规者.

This would output all the messages in the queue, and showed me what window and what message (in this case, WM_PAINT) was the offender.

然后,我追踪了该窗口附加到的类对象,并查看了它的 OnPaint() 处理程序.

I then tracked down what class object that window that was attached to and looked at it's OnPaint() handler.

原来,以前的程序员在构造 CPaintDC 对象之前放置了一个 if x then return 条件.它的构造函数调用BeginPaint(),依次验证无效区域.在不验证无效区域的情况下,系统会继续生成 WM_PAINT 消息,直到无效区域为空.这将导致消息队列永远不会为空.

Turns out, a previous programmer put an if x then return condition before constructing a CPaintDC object. Its constructor calls BeginPaint(), which in turn validates the invalid region. Without validating the invalid region, the system continues to generate WM_PAINT messages, until the invalid region is empty. This will result in the message queue never being empty.

不确定这是否重要,但有问题的窗口和对话框之间的关系是它们在同一个线程中,不在根应用程序窗口之外.有两种显示模式,具有以下设置:

Not sure if this matters, but the relationship between the offending window and the dialogue box was that they were in the same thread, off of the root application window. There were two display modes which had the following setup:

-ROOT                            -ROOT
 +-CHILD                          +-MESSAGE BOX 
  +-MESSAGE BOX                   +-CHILD 
  +-CHILD                          +-CHILD 
   +-CHILD                          +-CHILD < Offender 
    +-CHILD < Offender               +-CHILD 
     +-CHILD                      

这篇关于为什么不显示消息框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆