1
votes

I have an MDI application with tab controls. On some machines I get "Error creating window handle" exception when opening up a new tab. This is only occurs at some machines, mostly slow machines. .NET Framework 4.0 is used.

I have been investigating the issue for the last couple of days now and it has driven me nuts! I found the following on MSDN forums The solution by Hans Passant at this MSDN Forum And according to the answer it has something to do with the active MDI child being in maximized state. The given solution is to set the active child in normal window state before showing the new tab and then restore it afterwards. This solution works but I really dislike the flickering that the workaround causes.

The stack trace is as follows:

Error creating window handle:

   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

Code:

    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);
        }
    }

UPDATE: Found this at Microsoft support
This can occur when both the following conditions are true.

  1. The MDI child form contains a control which parents other controls.
  2. The parent control on the MDI child form removes a child control from its Controls collection in the event handler for the Layout or Resize events.
1
So basically, you're looking for an alternative to the solution Hans proposes in the MSDN thread? One that avoids the flicker?Cody Gray
Can you avoid the flicker by calling SuspendLayout/ResumeLayout?Roger Willcocks

1 Answers

3
votes

The Microsoft Support article is the same scenario as the MSDN forum post you found. It isn't a good match with yours. Diagnose this with Taskmgr.exe, Processes tab. View + Select Columns and tick Handles, USER objects and GDI objects. Observe these values for your process while you are using it.

The likely scenario is that you'll see the USER objects value climb without bound. Windows pulls the rug out when it reaches 10000, that's way too many windows to be created by one process.

It is caused by removing controls from their parent in your code without calling their Dispose() method. If the Taskmgr.exe doesn't help you find it then search your code for "Controls.Remove" or "Controls.Clear". Maybe you're removing a tab page. The control(s) you remove are temporarily re-parented to the 'parking window'. They'll get stuck there forever if you don't give them another parent or don't call their Dispose() method. That's a leak. The code that bombs is not the code that caused the problem.