工具条上的组合框出现异常“创建窗口句柄时出错”

时间:2011-09-06 04:50:14

标签: c# handle

我正在开发一个基于.Net 2.0 / C#的大型WinForm应用程序,在笔记本电脑上运行应用程序Dell E6520(Win7 Pro SP1,8G RAM)时,会出现一个稳定可重现的错误“创建窗口句柄时出错”,同时它适用于台式机,包括XP,Win7,2008)。

这是异常堆栈:

System.ComponentModel.Win32Exception: Error creating window handle.
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.ComboBox.CreateHandle()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.ControlCollection.Add(Control value)
   at System.Windows.Forms.WindowsFormsUtils.ReadOnlyControlCollection.AddInternal(Control value)
   at System.Windows.Forms.ToolStripControlHost.SyncControlParent()
   at System.Windows.Forms.ToolStripControlHost.OnParentChanged(ToolStrip oldParent, ToolStrip newParent)
   at System.Windows.Forms.ToolStripItem.set_ParentInternal(ToolStrip value)
   at System.Windows.Forms.ToolStripSplitStackLayout.LayoutHorizontal()
   at System.Windows.Forms.ToolStripSplitStackLayout.LayoutCore(IArrangedElement container, LayoutEventArgs layoutEventArgs)
   at System.Windows.Forms.Layout.LayoutEngine.Layout(Object container, LayoutEventArgs layoutEventArgs)
   at System.Windows.Forms.Control.OnLayout(LayoutEventArgs levent)
   at System.Windows.Forms.ScrollableControl.OnLayout(LayoutEventArgs levent)
   at System.Windows.Forms.ToolStrip.OnLayout(LayoutEventArgs e)
   at System.Windows.Forms.Control.PerformLayout(LayoutEventArgs args)
   at System.Windows.Forms.Control.System.Windows.Forms.Layout.IArrangedElement.PerformLayout(IArrangedElement affectedElement, String affectedProperty)
   at System.Windows.Forms.Layout.LayoutTransaction.DoLayout(IArrangedElement elementToLayout, IArrangedElement elementCausingLayout, String property)
   at System.Windows.Forms.Control.OnResize(EventArgs e)
   at System.Windows.Forms.Control.OnSizeChanged(EventArgs e)
   at System.Windows.Forms.Control.UpdateBounds(Int32 x, Int32 y, Int32 width, Int32 height, Int32 clientWidth, Int32 clientHeight)
   at System.Windows.Forms.Control.UpdateBounds()
   at System.Windows.Forms.Control.WmWindowPosChanged(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

当表单显示在里面时,会出现包含组合框和按钮的工具条。稍后通过调用以下方法,在构建表单后动态地将它们添加到工具条中,同时保持不可见:

private void Init()
{
  ...
  foreach (ToolBarItemConfig item in configuredToolbarItems)
  {
    ToolStripItem toolStripItem = createToolStripItem(item);
    toolStrip.Items.Add(toolStripItem);
    if (toolStripItem is ToolStripComboBox)
      populateComboBox(toolStripItem as ToolStripComboBox, item); // populate items of ToolStripComboBox
  }
  ...
}

注意在Init中,工具条是不可见的,并且不会创建新的ToolStripComboBox项的句柄(从日志中找到)。我可以理解句柄创建是由意图推迟的,因为它们实际上还没有显示。但是稍后,表格最终会显示出来并且会出现异常。

我从this article获得了很多灵感,可以通过在创建ToolStripComboBox项时立即访问Handle属性来强制创建句柄来解决此问题。

现在我的理解是ToolStrip尝试在显示表单时在其OnLayout中重新创建组合框的句柄,但那时仍然没有创建那些句柄,因此没有什么可以销毁 - > “创建窗口句柄时出错”。然而,这只是我的猜测,因为问题的根本原因对我来说仍然不清楚,特别是我 无法解释为什么这只发生在特定的笔记本电脑而不是桌面电脑中。

任何人都可以帮助我理解它的根本原因所以我可以确信类似的问题将来不会再受到伤害吗?

提前致谢。

2 个答案:

答案 0 :(得分:4)

有类似的问题,用户对象(句柄)的数量增加并爆炸,因为你传递了Windows不支持的限制。我们通过处理未使用的隐藏表单并进行一些重大清理来解决这个问题。

简而言之,不要让太多的控件或窗口/窗体打开,隐藏和不遮挡,因为这些对象仍然使用窗口句柄。

从“知道的人”中看到这篇有趣的文章; - )

Pushing the Limits of Windows: USER and GDI Objects – Part 1

答案 1 :(得分:0)

我使用任务管理器来查找问题。首先,我将一些列(用户对象,GDI)添加到流程选项卡(视图 - >选择列)。在我启动应用程序并在表单中导航之后。我看到用户对象的数量不断增长。一些关键数量的应用程序崩溃后。 这个链接对我有很大帮助http://blogs.msdn.com/b/jfoscoding/archive/2005/08/12/450835.aspx