none
Error creating window handle (InnerException: Object reference not set to an instance of an object.)

    Întrebare

  • I have a MDI application. In the main form I open two childs. I maximize them and when I try to open another child I get the error:

    Error creating window handle.

       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 Creon.DRAGON.MainForm.mIUserManagement_Click(Object sender, EventArgs e)
       at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
       at System.Windows.Forms.MenuItem.MenuItemData.Execute()
       at System.Windows.Forms.Command.Invoke()
       at System.Windows.Forms.Command.DispatchID(Int32 id)
       at System.Windows.Forms.Control.WmCommand(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at Creon.Common.BasicWinControls.CreonForm.WndProc(Message& m)
       at Creon.DRAGON.MainForm.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)

    InnerException
    Object reference not set to an instance of an object.

       at System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
       at System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
       at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)

    Do you know what could be the problem? Or how to determine the problem?

    This problem occurs only on some machines.

    29 septembrie 2009 09:16

Răspunsuri

  • Awesome bug.  It is a fatal combination of MDI, PerformLayout() and your Layout event handler.  With some hacks to make .NET work on Windows 98 to make it almost impossible to guess what is going on.  This ball starts rolling because MDI really dislikes a maximized child window.  It has to restore a child from the maximized state before it can bring another child to the front.  That triggers the form layout engine to re-layout the form.  And runs your Layout event handler.  What happens next is muddy to me but in effect there's nested code execution that creates the Form3 form window twice.  That's fatal, it bombs on a NullReference exception when it gets a message from the 2nd window and needs to match it up with the Form3 instance.  There's only one.

    This is a really low-level bug, fixing the Windows Forms code is not an option.  But there's a simple workaround: make sure that the current MDI child window is not maximized before you display a new one.  Put this code in the MDI parent form:

        public void DisplayChild(Form child) {
          bool max = false;
          if (this.ActiveMdiChild != null && this.ActiveMdiChild.WindowState == FormWindowState.Maximized) {
            this.ActiveMdiChild.WindowState = FormWindowState.Normal;
            max = true;
          }
          child.MdiParent = this;
          child.Show();
          if (max) child.WindowState = FormWindowState.Maximized;
        }

    And change your toolstrip button's Click event handler like this:

            private void toolStripButton2_Click(object sender, EventArgs e)
            {
              DisplayChild(new Form3());
            }


    Hans Passant.
    • Marcat ca răspuns de ARHANGEL19 13 octombrie 2009 13:18
    13 octombrie 2009 12:55

Toate mesajele

  • based on the error i think you have not initialized the child form object..with out creating the object of the child you are trying to open it.. create a new object using new and then open.
    29 septembrie 2009 09:42
  • This kind of error is invariable caused by a window handle leak in your program.  That should only happen after using the program for a while.

    Hans Passant.
    29 septembrie 2009 12:10
  • The error happens always doing the same things, so it doesn't happen only after a while.
    29 septembrie 2009 12:54
  • Can you post the code where the error is happening so we can see the declaration and the code?
    29 septembrie 2009 13:07
  • if you mean the Creon.DRAGON.MainForm.mIUserManagement_Click(Object sender, EventArgs e)
    then this is something like this
    CursorUtils.WaitCursor();
    try
    {
    	Form form1= mdiChild(typeof(Form1));
    	if (form1== null)
    	{
    		mainToolbar.Enabled = false;
    		form1 = new Form1();
    		form1.Disposed += new EventHandler(OnMDIChildDisposed);
    		form1.MdiParent = this;
    		form1.Show();
    		mainToolbar.Enabled = true;
    	}
    	else
    	{
    		form1.Activate();
    		form1.WindowState = FormWindowState.Normal;
    	}
    	this.mainStatusBar.Panels[1].Text = form1.Text;
    }
    finally
    {
    	CursorUtils.DefaultCursor();
    }
    
    The form is not previously created so the if is true
    29 septembrie 2009 13:12
  • Is the form1.show() where your error is occuring?

    29 septembrie 2009 13:16
  • yes. But as you can see from the StackTrace the error is because a CallBack is made and the "targetwindow" from WindowClass is null
    29 septembrie 2009 13:20
  • What is mdiChild? is that a method you have written?
    29 septembrie 2009 13:28
  • private Form mdiChild(Type type)
    		{
    			for (int i = 0; i < this.MdiChildren.Length; ++i)
    				if (MdiChildren[i].GetType().Equals(type))
    					return MdiChildren[i];
    			return null;
    		}
    29 septembrie 2009 13:31
  • Testing the below code I have yet to get it to fail with the error you descibed. Am I missing something?

            private void ShowNewForm(object sender, EventArgs e)
            {
                Form form1 = mdiChild(typeof(Form1));
    
                if (form1 == null)
                {
                    form1 = new Form1();
                    form1.MdiParent = this;
                    form1.Show();
                }
                else
                {
                    form1.Activate();
                    form1.WindowState = FormWindowState.Normal;
                }
            }
    
            private Form mdiChild(Type type)
            {
                for (int i = 0; i < this.MdiChildren.Length; ++i)
                    if (MdiChildren[i].GetType().Equals(type))
                        return MdiChildren[i];
                return null;
            }


    29 septembrie 2009 13:42
  • Perhaps. I've manage to narrow when this exception appeared.

    On one of child forms I have contains a panel that is extended based on http://www.codeproject.com/KB/miscctrl/Extended_PictureBox.aspx (I adapted the code to a panel). Also I have adapted the code from Control.ScrollControlIntoView(Control ctrl).

    So it's complicated and I don't know how to narrow the code that is causing this error.
    29 septembrie 2009 13:50
  • You could try making a backup, then removing the extended panel and see if it still happens.
    29 septembrie 2009 13:56
  • Perhaps it wasn't to obviosly.

    The problem appeared when I changed the usercontrol with my extendedpanel.

    So if I use the code from before the extendedpanel the exception doesn't appear.
    • Propus ca răspuns de Matt Wise 29 septembrie 2009 15:10
    • Marcat ca răspuns de nobugzMVP, Moderator 4 octombrie 2009 16:08
    • Anulare marcare ca răspuns de ARHANGEL19 5 octombrie 2009 05:32
    • Editat de ARHANGEL19 5 octombrie 2009 05:37 abusely marked as answer
    29 septembrie 2009 14:04
  • New update. I have manage to restrict my problem.

    Here is the source code Download WindowsFormsApplication7.zip from FileFactory.com

    So how to reproduce.
    0. Run the mdi application
    1. Open the form with the problem using the button with the label "Problem form"
    2. Maximize the opened form
    3. Press the button on the opened form with the label "Set panel visible on normal state"
    4. Try to open any other form(the other button with the label "Any form")
    5. The error is thrown
    13 octombrie 2009 11:08
  • Awesome bug.  It is a fatal combination of MDI, PerformLayout() and your Layout event handler.  With some hacks to make .NET work on Windows 98 to make it almost impossible to guess what is going on.  This ball starts rolling because MDI really dislikes a maximized child window.  It has to restore a child from the maximized state before it can bring another child to the front.  That triggers the form layout engine to re-layout the form.  And runs your Layout event handler.  What happens next is muddy to me but in effect there's nested code execution that creates the Form3 form window twice.  That's fatal, it bombs on a NullReference exception when it gets a message from the 2nd window and needs to match it up with the Form3 instance.  There's only one.

    This is a really low-level bug, fixing the Windows Forms code is not an option.  But there's a simple workaround: make sure that the current MDI child window is not maximized before you display a new one.  Put this code in the MDI parent form:

        public void DisplayChild(Form child) {
          bool max = false;
          if (this.ActiveMdiChild != null && this.ActiveMdiChild.WindowState == FormWindowState.Maximized) {
            this.ActiveMdiChild.WindowState = FormWindowState.Normal;
            max = true;
          }
          child.MdiParent = this;
          child.Show();
          if (max) child.WindowState = FormWindowState.Maximized;
        }

    And change your toolstrip button's Click event handler like this:

            private void toolStripButton2_Click(object sender, EventArgs e)
            {
              DisplayChild(new Form3());
            }


    Hans Passant.
    • Marcat ca răspuns de ARHANGEL19 13 octombrie 2009 13:18
    13 octombrie 2009 12:55