C# .NET 2.0 this.Close() and ToolStripDrropDown Menus

E

Eric Renken

OK, I have a form with a menu and a tool bar. In the Menu I have a File
menu that contains a "Exit" item. When I click this Exit item. I have an
event wired to:

mnuFile.DropDown.ItemClicked

In that event I check the:

event handler ...
if ( e.ClickedItem.Tag != null )
ProcessMenu( e.ClickedItem.Tag.ToString() )
System.Diagnostics.Debug.WriteLine( "Done" );

I do this because I have 1 function for all my menus on this screen. In
this function I have a switch statement:

switch ( tag )
{
....
case "Exit":
this.Close();
break;
....
}

This function returns up to the event handler successfully processes my
WriteLine statement, and then procedures to crash with:

{"Cannot access a disposed object.\r\nObject name:
'ToolStripDropDownMenu'."}

Why am I getting this error. There is no code after this and my code in my
Dispose processes correctly also. In stepping through the code the Dispose
happens before my this.Close() returns anyway, so I know all that is
functioning correctly. My thought on what is happening here is that at this
point after the event handler is done the ToolStrip is trying to hide the
drop down control, but since my form is already disposed of the ToolStrip is
causing an error internally. I think this because I can view the drop down
menu while stepping though my code. My thought is that after I clicked that
item the drop down should have disappeared on its own. Well anyway this
feels like a bug to me in the ToolStrip control, and I think I found a work
around. In my event I added this code to the beginning:

((ToolStripDropDown)sender).Hide();

By doing this I know longer crash when I close my application.

Eric Renken
 
E

Eric Renken

Sorry about some of the bad grammar up front. Was trying to get this out
way to fast.

Eric Renken
 
J

Jeffrey Tan[MSFT]

Hi Eric,

Thanks for your post.

Currently, for this issue, can you provide a little sample project to
demonstrate the problem? Then we can understand the problem context much
better. This is because the currently information you provided is not
enough for us to reproduce the problem.

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Eric,

Thanks for your feedback.

Yes, with your sample project, I can reproduce out this problem.

I think you are right. If we enable first chance exception in VS2005 after
setting up the symbol correctly. We will get the following call stack
because of the ObjectDisposedException:
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() Line
5581 + 0x2a bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.CreateHandle
() Line 1143 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.Handle.get() Line
2743 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.ReparentToDr
opDownOwnerWindow() Line 1657 + 0xb bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.SetVisibleCo
re(bool visible = false) Line 1913 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.OnItemClicke
d(System.Windows.Forms.ToolStripItemClickedEventArgs e =
{System.Windows.Forms.ToolStripItemClickedEventArgs}) Line 1358 + 0x19
bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.HandleItemClick(Syst
em.Windows.Forms.ToolStripItem dismissingItem = {Close}) Line 2582 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleClick(Syst
em.EventArgs e = {System.EventArgs}) Line 2769 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleMouseUp(Sy
stem.Windows.Forms.MouseEventArgs e = {X = 30 Y = 15 Button = Left}) Line
2920 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEventInterac
tive(System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met)
Line 2626 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEvent(System
.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) Line 2607 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.OnMouseUp(System.Win
dows.Forms.MouseEventArgs mea) Line 3531 + 0xd bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.OnMouseUp(Sy
stem.Windows.Forms.MouseEventArgs mea = {X = 30 Y = 17 Button = Left}) Line
1439 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref
System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button,
int clicks) Line 13032 + 0x5e bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref
System.Windows.Forms.Message m) Line 13762 C#

System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref
System.Windows.Forms.Message m) Line 1491 C#
System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.WndProc(ref
System.Windows.Forms.Message m = {msg=0x202 (WM_LBUTTONUP) hwnd=0x109c0
wparam=0x0 lparam=0x11001e result=0x0}) Line 4627 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.WndProc(ref
System.Windows.Forms.Message m) Line 2112 C#

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.On
Message(ref System.Windows.Forms.Message m) Line 14049 C#

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.Wn
dProc(ref System.Windows.Forms.Message m) Line 14104 C#

System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallbac
k(System.IntPtr hWnd, int msg = 514, System.IntPtr wparam, System.IntPtr
lparam) Line 777 + 0xa bytes C#
[Native to Managed Transition]
[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.S
ystem.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoo
p(int dwComponentID, int reason = -1, int pvLoopData = 0) Line 2106 + 0x8
bytes C#

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunM
essageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext
context = {System.Windows.Forms.ApplicationContext}) Line 3359 + 0x1b bytes
C#

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunM
essageLoop(int reason, System.Windows.Forms.ApplicationContext context)
Line 3243 + 0xa bytes C#

System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows
.Forms.Form mainForm) Line 1466 C#
MenuCrashSample.exe!MenuCrashSample.Program.Main() Line 17 + 0x1a bytes C#

With Reflector, we will find the following code in
System.Windows.Forms.Control.CreateHandle() method:

protected virtual void CreateHandle()
{
IntPtr ptr1 = IntPtr.Zero;
if (this.GetState(0x800))
{
throw new ObjectDisposedException(base.GetType().Name);
}
.....
}

Then by using Reflector to view Control.Dispose method, we will see the
following code in finally clause:
finally
{
this.ResumeLayout(false);
this.SetState(0x1000, false);
this.SetState(0x800, true);
}

So, Control.Dispose() method turn on 0x800 flag, which causes
ObjectDisposedException in System.Windows.Forms.Control.CreateHandle()
method.

Currently, I think your workaround of using mnuFile.DropDown.Hide() should
be a good one. Also, you may submit a bug request to our product team in
the link below:
http://lab.msdn.microsoft.com/productfeedback/default.aspx

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
E

Eric Renken

Jeffery,

Thanks for looking at this. I have submitted the bug to that URL you
listed. Along with the sample project.

Thanks again,

Eric Renken

"Jeffrey Tan[MSFT]" said:
Hi Eric,

Thanks for your feedback.

Yes, with your sample project, I can reproduce out this problem.

I think you are right. If we enable first chance exception in VS2005 after
setting up the symbol correctly. We will get the following call stack
because of the ObjectDisposedException:
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() Line
5581 + 0x2a bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.CreateHandle
() Line 1143 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.Handle.get() Line
2743 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.ReparentToDr
opDownOwnerWindow() Line 1657 + 0xb bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.SetVisibleCo
re(bool visible = false) Line 1913 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.OnItemClicke
d(System.Windows.Forms.ToolStripItemClickedEventArgs e =
{System.Windows.Forms.ToolStripItemClickedEventArgs}) Line 1358 + 0x19
bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.HandleItemClick(Syst
em.Windows.Forms.ToolStripItem dismissingItem = {Close}) Line 2582 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleClick(Syst
em.EventArgs e = {System.EventArgs}) Line 2769 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleMouseUp(Sy
stem.Windows.Forms.MouseEventArgs e = {X = 30 Y = 15 Button = Left}) Line
2920 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEventInterac
tive(System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met)
Line 2626 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEvent(System
EventArgs e, System.Windows.Forms.ToolStripItemEventType met) Line 2607 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.OnMouseUp(System.Win
dows.Forms.MouseEventArgs mea) Line 3531 + 0xd bytes C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.OnMouseUp(Sy
stem.Windows.Forms.MouseEventArgs mea = {X = 30 Y = 17 Button = Left})
Line
1439 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref
System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button,
int clicks) Line 13032 + 0x5e bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref
System.Windows.Forms.Message m) Line 13762 C#

System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref
System.Windows.Forms.Message m) Line 1491 C#
System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.WndProc(ref
System.Windows.Forms.Message m = {msg=0x202 (WM_LBUTTONUP) hwnd=0x109c0
wparam=0x0 lparam=0x11001e result=0x0}) Line 4627 C#

System.Windows.Forms.dll!System.Windows.Forms.ToolStripDropDown.WndProc(ref
System.Windows.Forms.Message m) Line 2112 C#

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.On
Message(ref System.Windows.Forms.Message m) Line 14049 C#

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.Wn
dProc(ref System.Windows.Forms.Message m) Line 14104 C#

System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallbac
k(System.IntPtr hWnd, int msg = 514, System.IntPtr wparam, System.IntPtr
lparam) Line 777 + 0xa bytes C#
[Native to Managed Transition]
[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.S
ystem.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoo
p(int dwComponentID, int reason = -1, int pvLoopData = 0) Line 2106 + 0x8
bytes C#

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunM
essageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext
context = {System.Windows.Forms.ApplicationContext}) Line 3359 + 0x1b
bytes
C#

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunM
essageLoop(int reason, System.Windows.Forms.ApplicationContext context)
Line 3243 + 0xa bytes C#

System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows
Forms.Form mainForm) Line 1466 C#
MenuCrashSample.exe!MenuCrashSample.Program.Main() Line 17 + 0x1a bytes
C#

With Reflector, we will find the following code in
System.Windows.Forms.Control.CreateHandle() method:

protected virtual void CreateHandle()
{
IntPtr ptr1 = IntPtr.Zero;
if (this.GetState(0x800))
{
throw new ObjectDisposedException(base.GetType().Name);
}
....
}

Then by using Reflector to view Control.Dispose method, we will see the
following code in finally clause:
finally
{
this.ResumeLayout(false);
this.SetState(0x1000, false);
this.SetState(0x800, true);
}

So, Control.Dispose() method turn on 0x800 flag, which causes
ObjectDisposedException in System.Windows.Forms.Control.CreateHandle()
method.

Currently, I think your workaround of using mnuFile.DropDown.Hide() should
be a good one. Also, you may submit a bug request to our product team in
the link below:
http://lab.msdn.microsoft.com/productfeedback/default.aspx

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Ok. If you need further help, please feel free to post. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top