为啥不显示消息框?

Posted

技术标签:

【中文标题】为啥不显示消息框?【英文标题】:Why would a message box be not displaying?为什么不显示消息框? 【发布时间】:2016-12-12 17:34:59 【问题描述】:

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

在按下 ALT 键之前,消息框是不可见的。

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

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

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

【问题讨论】:

这可能是绘画/重绘问题。 @1201ProgramAlarm,因为这是一个普通的windows MessageBox,不知道会怎么样。 您是否使用多显示器设置?消息框可以在您已断开连接的显示器上吗? 你是如何显示消息框的?您是否将对话框窗口句柄传递给它? Win32 MessageBox doesn't appear 表现出相同的故障模式。在该问答中,owner 窗口的 WM_PAINT-handler 缺少 BeginPaint/EndPaint 调用。有了手头的信息,我建议查看(或注释掉)所有者窗口的PreTranslateMessage 实现。按 [Alt] 进入模式循环,即系统提供的消息循环,绕过应用程序提供的消息循环(这可能是错误的)。 【参考方案1】:

这是由MFC CDialog DoModal can't show window if parent window message queue is 'busy'“功能”引起的,如果消息队列包含任何消息,它将不会显示系统消息框。 (请对该错误进行投票或评论。这种行为非常出乎意料。)

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

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)是违规者。

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

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

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

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

【讨论】:

如果您简短地描述有问题的窗口和不会显示的对话框之间的关系,这可能对未来的访问者有用。

以上是关于为啥不显示消息框?的主要内容,如果未能解决你的问题,请参考以下文章

为啥列表框不使用 Visual C++ 6 显示元素?

为啥这个组合框不显示项目?

为啥dataTable不显示空数据消息?

WinForm,消息框怎样显示在窗体正中?

消息框不显示

为啥不显示我的 Jest 自定义匹配器的“消息”?