在.net MDI应用程序中创建窗口句柄出错



我有一个带有选项卡控件的MDI应用程序。在一些机器上,当打开一个新选项卡时,我得到"创建窗口句柄错误"异常。这只发生在某些机器上,主要是速度较慢的机器。. net Framework 4.0

过去几天我一直在调查这个问题,它快把我逼疯了!我在MSDN论坛上发现了以下内容Hans Passant在MSDN论坛上提出了解决方案根据答案,这与MDI子进程处于最大化状态有关。给出的解决方案是在显示新选项卡之前将活动子窗口设置为正常窗口状态,然后在显示新选项卡之后恢复它。这个解决方案是有效的,但是我真的不喜欢这个变通方法引起的闪烁。

堆栈跟踪如下:

创建窗口句柄错误:

<>之前在System.Windows.Forms.NativeWindow.WindowClass。回调IntPtr hWnd, Int32 msg,在System.Windows.Forms.NativeWindow。CreateHandle (CreateParams cp)在System.Windows.Forms.Control.CreateHandle ()在System.Windows.Forms.Form.CreateHandle ()在System.Windows.Forms.Control.get_Handle ()在System.Windows.Forms.Form。SetVisibleCore(布尔值)在System.Windows.Forms.Control.Show ()在Client.UI.WinForms.Controls.TabManager。OpenNewTab(BaseTab2选项卡)在WinFormsFormsTabsTabManager.cs:第82行在Client.UI.WinForms.Controls.TabManager。OpenTab(BaseTab2标签)在WinFormsFormsTabsTabManager.cs:第183行在Client.UI.WinForms.MainForm。buttonLicenses_Click(对象发送者,EventArgs e)在WinFormsFormsMainForm.cs:行4372之前代码:

    private void OpenNewTab(BaseTab2 tab)
    {
        tab.MdiParent = MainForm.Instance;
        tab.WindowState = FormWindowState.Maximized;
        tab.Show(); <----- [EXCEPTION THROWN HERE]
        if (tab.Path != String.Empty)
        {
            RecentManager.Add(tab.Path);
            RecentManager.SetOpen(tab.Path, true);
        }
    }

更新:在Microsoft支持中找到了这个
当以下两个条件都为真时,就会发生这种情况。

  1. MDI子窗体包含一个父控件。
  2. MDI子窗体上的父控件在Layout或Resize事件的事件处理程序中从其控件集合中删除子控件。

微软支持文章与您在MSDN论坛上找到的帖子是相同的场景。它和你的不太相配。用Taskmgr.exe的"进程"选项卡诊断。查看+选择列并勾选句柄、USER对象和GDI对象。当您使用您的进程时,请观察这些值。

可能的情况是,您将看到USER对象的值在没有绑定的情况下攀升。当达到10000个窗口时,Windows就会退出,这是一个进程创建的窗口太多了。

它是由在代码中从父控件中删除控件而不调用其Dispose()方法引起的。如果Taskmgr.exe没有帮助你找到它,那么在你的代码中搜索"控件"。"Remove"或"Controls.Clear"。也许你正在删除一个标签页。您删除的控件将暂时重新父级到"停车窗口"。如果你不给它们另一个父类或者不调用它们的Dispose()方法,它们就会永远卡在那里。这是一个漏洞。导致爆炸的代码并不是导致问题的代码。

最新更新