2009-11-11 150 views
1

我正在调试一个在其消息循环中调用IsDialogMessage()的应用程序。偶尔,IsDialogMessage()永远不会返回(永远不会超过1小时的间隔)。根据Microsoft的符号服务器提供的user32.dll符号,它似乎卡在GetNextDlgGroupItem()(或同一个内部变体)中,迭代了一些窗口集。为什么IsDialogMessage()永远不会返回?

该应用程序是多线程的,并经常接收外部事件的通知,这些事件以DCOM调用的形式到达。我怀疑这样的调用是以错误的方式处理某种窗口状态的。如果我能够知道什么样的状态腐败可能导致IsDialogMessage()中的无限循环,我想我会更容易地识别腐败的来源。

回答

0

您是否可能禁用控件(使用::EnableWindow())而未首先检查该控件是否具有焦点?如果是,那么焦点会丢失,GetNextDlgGroupItem()会变得混乱。

+0

这是可能的;有很多控件在使用,有些可能会被禁用。 – 2009-11-12 00:48:49

0

这可能发生的另一个原因是如果你重新建立一个无模式的对话框。至少这可以发生在wxWidgets ...

3

我知道这是旧的,但回答后代,因为没有人在这里提到它。

更可能发生什么事是Windows管理器确定在哪里转发消息的麻烦。如果您有Windows的层次结构,那么您需要确保包含控件的非顶级窗口本身必须具有WS_EX_CONTROLPARENT样式集。如果它是一个对话框,则使用DS_CONTROL样式。这些标志的存在修改了IsDialogMessage的行为;他们将窗口标识为拥有自己的控件,这些控件可以接收焦点并处理标签顺序等,而不仅仅是控件本身。

举例来说,如果你有一个主框架窗口,它与WS_EX_CONTROLPARENT一个子窗口,其中有一个子窗口没有 WS_EX_CONTROLPARENT,其中有具有焦点的子窗口,和你打标签,就可能在你提到的同一个地方遇到无限循环。

将第二个孩子的扩展样式设置为包含WS_EX_CONTROLPARENT将解决该问题。

0

我做了一些调查,试图回答这个问题。但只有在情况下,当父窗口在本地MFC项目中,并且子项是托管的C#Windows窗体。如果您有这种情况,那么您可以尝试3种分辨率:

  1. 在Windows窗体端运行MFC对话框消息循环。以下是更多信息:Integrate Windows Forms Into Your MFC Applications Through C++ Interop
  2. 创建2个线程:一个用于Windows窗体对话框,一个用于本机对话框。在这里你可以在Windows窗体中创建对话框,然后用SetParent()将它设置为本地对话框的父对话框。但是,如果您将TabControl添加到Windows窗体中,则会比“IsDialogMessage()永不返回”挂起。
  3. 为本地项目中使用的Windows窗体对话框创建一个包装。对于恩,包装物可为WPF,在这里看到:Windows Form as child window of an unmanaged app

我已经采取了大多来自信息:http://msdn.microsoft.com/en-us/library/ms229600.aspx

而且治标可以改变焦点行为。例如,禁用它们,或仅将SetFocus()设置为父窗口或子窗口。但我强烈建议调查真正的原因,为什么IsDialogMessage()永远不会返回你的情况。

相关问题