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

    Frage

  • 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.

    Dienstag, 29. September 2009 09:16

Antworten

  • 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.
    • Als Antwort markiert ARHANGEL19 Dienstag, 13. Oktober 2009 13:18
    Dienstag, 13. Oktober 2009 12:55
    Moderator

Alle Antworten

  • 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.
    Dienstag, 29. September 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.
    Dienstag, 29. September 2009 12:10
    Moderator
  • The error happens always doing the same things, so it doesn't happen only after a while.
    Dienstag, 29. September 2009 12:54
  • Can you post the code where the error is happening so we can see the declaration and the code?
    Dienstag, 29. September 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
    Dienstag, 29. September 2009 13:12
  • Is the form1.show() where your error is occuring?

    Dienstag, 29. September 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
    Dienstag, 29. September 2009 13:20
  • What is mdiChild? is that a method you have written?
    Dienstag, 29. September 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;
    		}
    Dienstag, 29. September 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;
            }


    Dienstag, 29. September 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.
    Dienstag, 29. September 2009 13:50
  • You could try making a backup, then removing the extended panel and see if it still happens.
    Dienstag, 29. September 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.
    • Als Antwort vorgeschlagen Matt Wise Dienstag, 29. September 2009 15:10
    • Als Antwort markiert nobugzMVP, Moderator Sonntag, 4. Oktober 2009 16:08
    • Tag als Antwort aufgehoben ARHANGEL19 Montag, 5. Oktober 2009 05:32
    • Bearbeitet ARHANGEL19 Montag, 5. Oktober 2009 05:37 abusely marked as answer
    Dienstag, 29. September 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
    Dienstag, 13. Oktober 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.
    • Als Antwort markiert ARHANGEL19 Dienstag, 13. Oktober 2009 13:18
    Dienstag, 13. Oktober 2009 12:55
    Moderator