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

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

问题描述

我在一个具有非常奇怪的窗口模式设置的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.

推荐答案

这是由于'功能",如果消息队列中包含任何消息,则不会显示系统消息框. (请对该错误进行投票或评论.此行为非常意外.)

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)--" "\n"),
              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然后是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天全站免登陆