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

在.NET MDI应用程序中创建窗口句柄时出错,.net,tabs,window,mdi,.net,Tabs,Window,Mdi,我有一个带有选项卡控件的MDI应用程序。在某些机器上,打开新选项卡时出现“创建窗口句柄时出错”异常。这只发生在一些机器上,大多数是低速机器。 使用.NET Framework 4.0 最近几天我一直在调查这个问题,这让我发疯了!我在MSDN论坛上发现了以下内容 汉斯·帕桑在这个问题上的解决方案 根据答案,它与活动MDI子对象处于最大化状态有关。给定的解决方案是在显示新选项卡之前将活动子项设置为正常窗口状态,然后再恢复。这个解决方案是可行的,但我真的不喜欢这个解决方案引起的闪烁 堆栈跟踪如下所示:

我有一个带有选项卡控件的MDI应用程序。在某些机器上,打开新选项卡时出现“创建窗口句柄时出错”异常。这只发生在一些机器上,大多数是低速机器。 使用.NET Framework 4.0

最近几天我一直在调查这个问题,这让我发疯了!我在MSDN论坛上发现了以下内容 汉斯·帕桑在这个问题上的解决方案 根据答案,它与活动MDI子对象处于最大化状态有关。给定的解决方案是在显示新选项卡之前将活动子项设置为正常窗口状态,然后再恢复。这个解决方案是可行的,但我真的不喜欢这个解决方案引起的闪烁

堆栈跟踪如下所示:

创建窗口句柄时出错:

at System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp) at System.Windows.Forms.Control.CreateHandle() at System.Windows.Forms.Form.CreateHandle() at System.Windows.Forms.Control.get_Handle() at System.Windows.Forms.Form.SetVisibleCore(Boolean value) at System.Windows.Forms.Control.Show() at Client.UI.WinForms.Controls.TabManager.OpenNewTab(BaseTab2 tab) in WinForms\Forms\Tabs\TabManager.cs:line 82 at Client.UI.WinForms.Controls.TabManager.OpenTab(BaseTab2 tab) in WinForms\Forms\Tabs\TabManager.cs:line 183 at Client.UI.WinForms.MainForm.buttonLicenses_Click(Object sender, EventArgs e) in WinForms\Forms\MainForm.cs:line 4372 在System.Windows.Forms.NativeWindow.WindowClass.Callback(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()中 在WinForms\Forms\Tabs\TabManager.cs中的Client.UI.WinForms.Controls.TabManager.OpenNewTab(BaseTab2选项卡)中:第82行 在WinForms\Forms\Tabs\TabManager.cs中的Client.UI.WinForms.Controls.TabManager.OpenTab(BaseTab2 tab)中:第183行 在Client.UI.WinForms.MainForm.buttonLicenses\u单击WinForms\Forms\MainForm.cs中的(对象发送者,事件参数e):第4372行 代码:

private void OpenNewTab(BaseTab2选项卡)
{
tab.mdipparent=MainForm.Instance;
tab.WindowState=FormWindowState.Maximized;

tab.Show();Microsoft支持文章与您找到的MSDN论坛帖子的场景相同。它与您的文章不太匹配。请使用Taskmgr.exe、processs tab.View+Select Columns and tick Handles、USER objects和GDI objects对其进行诊断。请在使用过程中观察这些值

很可能的情况是,你会看到用户对象的价值毫无限制地上升。当它达到10000时,Windows会把地毯拉出来,这是一个进程创建的窗口太多了


这是由于在代码中从父控件中删除控件而未调用其Dispose()方法造成的。如果Taskmgr.exe无法帮助您找到它,请在代码中搜索“controls.Remove”或“controls.Clear”。可能您正在删除选项卡页。该控件您删除的对象暂时重新成为“停车窗口”的父对象。如果您不给它们另一个父对象或不调用它们的Dispose(),它们将永远卡在那里方法。这是一个漏洞。爆炸的代码不是导致问题的代码。

因此,基本上,您正在寻找替代Hans在MSDN线程中提出的解决方案的方法?一种避免闪烁的方法?您可以通过调用SuspendLayout/ResumeLayout来避免闪烁吗?当崩溃发生时,用户对象大约为170,GDI对象为around 170和Hadels大约为350。如果您认为问题是由于我们达到了.net或windows支持的最大限制而导致的,那么您能否解释一下为什么只有一些计算机会出现这种情况?它发生在内存/处理能力较低的计算机上。谢谢,请将其删除。您无法摆脱重新绘制。如果您不断地最大化MDI子项,那么MDI不是正确的窗口模型。请使用一个简单的表单来显示和处理多个用户控件中的一个。您在MSDN论坛上提出的解决方案/解决方案是有效的,因此我猜句柄不是问题。解决方案很好,除了“闪烁”之外。可能闪烁不是正确的词。发生的是MDI子项从最大化状态变为正常状态,然后又回到最大化状态-这个过程看起来一点也不好。这就是我所说的“闪烁”呃,为什么要返回最大化?如果您不想让新的子项最大化,那么只需从MSDN forums post中的解决方案代码中删除最后一条语句。MDI已经经历了还原+切换+最大化循环,即使您没有帮助它提前完成,这样错误就不会出现。是的,重新绘制的次数(3次)如果子窗体有很多控件,那么它就很明显了。唯一的解决方法是使用较少的控件。
    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);
        }
    }