locked
Remove child forms icon from MDI menustrip RRS feed

  • Question

  •  

    Hello,

     

    I have MDI container form with a menustrip and when any children are displayed in it the child forms icon displays in the menu strip along with the min, max, and close buttons.

     

    What I want is the ability to not display the child forms icon in the menustrip, and it would be nice if I could control which of the other buttons are displayed as well.

     

    I have the child forms ShowIcon property set to False but the default windows icon is displayed in the menustrip now. :-(

     

    Any help in fixing this would be greatly appreciated.

     

    Thanks,

     

    Kris

    Tuesday, May 13, 2008 8:31 PM

Answers

  • Hi Kris,

     

    When an MDI child form is maximized, its system menu (corresponding to the icon of the MDI child form) and control box buttons(Minimize, Maximize, Close) are merged into its MDI parent form's  MainMenuStrip (if the MDI parent form has).

    The merged menu items are inserted into the top of the MainMenuStrip and the sequence is like blow:


    system menu item
    Close menu item
    Maximize/Resore menu item
    Minimize menu item

     

    All the value of the Alignment property of the above menu item are ToolStripItemAlignment.Right, except the system menu item, which has a value of ToolStripItemAlignment.Left. So system menu item is located at the far left of the MainMenuStrip.

     

    After above menu items are merged into the MainMenuStrip of the MDI parent form, we could remove the system menu item to accomplish what you want.

     

    However, there remains another question, i.e., when to remove the system menu item? The SizeChanged event of the MDI child form is not appropriate, because the menu items(system, Close, Maximize and etc) have not yet merged intot the MainMenuStrip of the MDI parent form when the SizeChanged event occurs.

     

    I use Spy++ to capture all the messages sent to an MDI child form when it is maximized, and found the message WM_GETTEXT, which is sent to a window to copy the text corresponding to the window into a butter provided by the
    caller. This message is sent to the MDI child form AFTER the menu items related to the MDI child form are merged into the MainMenuStrip of the MDI parent form. So we could catch this message and adjust the index of the system menu item.

     

    The following is a sample:

     

    Public Class ParentForm
       Private m_originalMenuItemCount As Integer
        Public ReadOnly Property OriginalMenuItemCount() As Integer
            Get
                Return Me.m_originalMenuItemCount
            End Get
        End Property

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.m_originalMenuItemCount = Me.MenuStrip1.Items.Count
        End Sub
    End Class

     

    Public Class ChildForm
        Private Sub AdjustMenuItem()
            If (Me.WindowState = FormWindowState.Maximized) Then
                If (Me.MdiParent.MainMenuStrip IsNot Nothing) Then
                    If (Me.MdiParent.MainMenuStrip.Items.Count > CType(Me.MdiParent, Form1).OriginalMenuItemCount) Then 
                       Me.MdiParent.MainMenuStrip.Items.RemoveAt(0)

                    End If
                End If
            End If
         End Sub

     

        Private WM_GETTEXT = &HD
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            If (m.Msg = WM_GETTEXT) Then
                Me.AdjustMenuItem()
            End If
            MyBase.WndProc(m)
        End Sub
    End Class

     

    Hope this helps.

    If you have any question, please feel free to let me know.

     

    Linda

    Friday, May 16, 2008 10:25 AM

All replies

  • These should only appear when the child form is in the Maximized state.  It has to work this way, because Windows does not have any other place to put these buttons.

     

    However, you could set the properties as follows on the child form.  This will give you a maximized child form without any of the buttons that you mention.

     

    Code Snippet

    Dim f As New Form2

    f.MdiParent = Me

    f.ControlBox = False

    f.MinimizeBox = False

    f.MaximizeBox = False

    f.WindowState = FormWindowState.Maximized

    f.Show()

     

    Tuesday, May 13, 2008 10:27 PM
  • When my child form doesn't have a form icon I don't see why it has to put the default windows icon on the menu strip. This is what I really want to try and figure out how to not show that icon on the menu strip. Is there some way to do that? Setting the child forms ShowIcon propertty to False didn't do the trick. :-(

     

    Thanks,

     

    Kris

    Wednesday, May 14, 2008 12:46 AM
  • Hi Kris,

     

    When an MDI child form is maximized, its system menu (corresponding to the icon of the MDI child form) and control box buttons(Minimize, Maximize, Close) are merged into its MDI parent form's  MainMenuStrip (if the MDI parent form has).

    The merged menu items are inserted into the top of the MainMenuStrip and the sequence is like blow:


    system menu item
    Close menu item
    Maximize/Resore menu item
    Minimize menu item

     

    All the value of the Alignment property of the above menu item are ToolStripItemAlignment.Right, except the system menu item, which has a value of ToolStripItemAlignment.Left. So system menu item is located at the far left of the MainMenuStrip.

     

    After above menu items are merged into the MainMenuStrip of the MDI parent form, we could remove the system menu item to accomplish what you want.

     

    However, there remains another question, i.e., when to remove the system menu item? The SizeChanged event of the MDI child form is not appropriate, because the menu items(system, Close, Maximize and etc) have not yet merged intot the MainMenuStrip of the MDI parent form when the SizeChanged event occurs.

     

    I use Spy++ to capture all the messages sent to an MDI child form when it is maximized, and found the message WM_GETTEXT, which is sent to a window to copy the text corresponding to the window into a butter provided by the
    caller. This message is sent to the MDI child form AFTER the menu items related to the MDI child form are merged into the MainMenuStrip of the MDI parent form. So we could catch this message and adjust the index of the system menu item.

     

    The following is a sample:

     

    Public Class ParentForm
       Private m_originalMenuItemCount As Integer
        Public ReadOnly Property OriginalMenuItemCount() As Integer
            Get
                Return Me.m_originalMenuItemCount
            End Get
        End Property

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.m_originalMenuItemCount = Me.MenuStrip1.Items.Count
        End Sub
    End Class

     

    Public Class ChildForm
        Private Sub AdjustMenuItem()
            If (Me.WindowState = FormWindowState.Maximized) Then
                If (Me.MdiParent.MainMenuStrip IsNot Nothing) Then
                    If (Me.MdiParent.MainMenuStrip.Items.Count > CType(Me.MdiParent, Form1).OriginalMenuItemCount) Then 
                       Me.MdiParent.MainMenuStrip.Items.RemoveAt(0)

                    End If
                End If
            End If
         End Sub

     

        Private WM_GETTEXT = &HD
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            If (m.Msg = WM_GETTEXT) Then
                Me.AdjustMenuItem()
            End If
            MyBase.WndProc(m)
        End Sub
    End Class

     

    Hope this helps.

    If you have any question, please feel free to let me know.

     

    Linda

    Friday, May 16, 2008 10:25 AM
  • Hello Linda,

     

    Thanks a lot. This did exactly what I wanted to do.

     

    Again Thanks.

     

    Kris

     

    Tuesday, May 20, 2008 6:25 PM
  • Lovely,

     

    But I would use MenuStrip ItemAdded event rather than overriding WndProc method.

    Because, first thing you should do is to consider how many times WndProc method called in an application. So in here you multipy process count with 2.

     

    Solution in ItemAdded event :

     

    if (e.item.Text == "" )

    {

    e.item.Visible = false;

    }

     

    • Proposed as answer by Murat YILDIZ Monday, July 13, 2009 1:50 PM
    Tuesday, July 29, 2008 9:06 AM
  • Is there really no better option for this problem?  I agree the above solution is the best so far, however I would think Microsoft would have atleast added an option to disable these.
    Thursday, July 31, 2008 9:24 PM
  •  Ryan_Whit wrote:
    Is there really no better option for this problem?  I agree the above solution is the best so far, however I would think Microsoft would have atleast added an option to disable these.

     

    i hope so, Ryan =)

    Friday, August 1, 2008 6:08 AM
  •  Emrah Yiğit wrote:

    Lovely,

     

    But I would use MenuStrip ItemAdded event rather than overriding WndProc method.

    Because, first thing you should do is to consider how many times WndProc method called in an application. So in here you multipy process count with 2.

     

    Solution in ItemAdded event :

     

    if (e.item.Text == "" )

    {

    e.item.Visible = false;

    }

     

     

    Thanks Emrah, this way very simple and effect.

    Monday, August 11, 2008 3:58 PM
  • Is there a way to just get rid of the icon when the child is maximized?

     

    The code mentioned above works great but I want to keep the other controls.

     

    TD

    Friday, September 26, 2008 3:16 AM
  • Hi Linda ,
    I am not able to get menu item count in my mdi parenf form..So i hard coded the value...
    The code was working fine till I noted that maiximize,minimize and close boxes/buttons are also remove.

    Would you please  suggest me some other way of doing the same.

    Thanks
    Gourav
    Monday, December 29, 2008 2:49 PM
  • Lovely,

     

    But I would use MenuStrip ItemAdded event rather than overriding WndProc method.

    Because, first thing you should do is to consider how many times WndProc method called in an application. So in here you multipy process count with 2.

     

    Solution in ItemAdded event :

     

    if (e.item.Text == "" )

    {

    e.item.Visible = false;

    }

     



       Thank you very much Emrah,
    I would like very much this kind of short and effective solutions on the way reaching to target :)


    Monday, July 13, 2009 1:53 PM
  • Hello,

    If I don't have access to program source code, is there a way to disable child forms icon, minimize, maximize, close items from showing up on MainMenuStrip? Hex editing, resource editing maybe? Any chances?
    Tuesday, November 10, 2009 5:20 AM
  • Hello,

    to hide only the mdi child icon on the left side, try this

    private void menuStrip1_ItemAdded(object sender, ToolStripItemEventArgs e)
          {
             string s = e.Item.GetType().ToString();
             if (s == "System.Windows.Forms.MdiControlStrip+SystemMenuItem")
             {
                e.Item.Visible = false;
             }
          }

    The 3 controlbox menu items are of type "System.Windows.Forms.MdiControlStrip+ControlBoxMenuItem".



    Hope it helps
    nafezz
    Thursday, November 12, 2009 6:09 PM
  •          string s = e.Item.GetType().ToString();
             if (s == "System.Windows.Forms.MdiControlStrip+SystemMenuItem")



    Hope it helps
    nafezz

    Will the ToString() output always be in English no matter what language the .NET Framework or CLR is?

    Thanks
    Tuesday, February 2, 2010 3:15 AM
  • private void menuStrip1_ItemAdded(object sender, ToolStripItemEventArgs e)
            {
                if (e.Item.Text == "")
                {
                    e.Item.Image = null;
     
    //to set an image
    //e.Item.Image =  Properties.Resources.Icon.ToBitmap();
                    //e.Item.ImageScaling = ToolStripItemImageScaling.SizeToFit;
                }
                
            }


    this, worked for me
    Monday, May 10, 2010 4:48 PM
  • Actually this reply give a good hint. Below is what I do using C++

     

    private: System::Void menuStrip1_ItemAdded(System::Object^  sender, System::Windows::Forms::ToolStripItemEventArgs^  e) {
    	 if( e->Item->Text == "" )
    	 {
    		e->Item->Visible = false;
    	 }
    }
    

    I believe this solution is the easiest one =)


    Code is wonderful.
    Thursday, November 3, 2011 10:16 AM
  • :-) THANK YOU

    This worked perfectly for me ...

    Regards

    Marky Mark

    Tuesday, December 3, 2013 1:45 AM
  • i know this post is old, but i ran across it with a simpler way to do what is needed (at least in my case).

    the controlbox property is ineffective when maximizing a mdi child form.

    i found that by "restoring" the form, the dynamic system menu bar "went away".

    my solution was to call these when i show my mdi child form:

    childForm.MaximizeBox = false;
    childForm.MinimizeBox = false;

    childForm.WindowState = FormWindowState.Maximized;
    childForm.WindowState = FormWindowState.Normal;

    calling "normal" at the end was not intuitive at first, but it seems to work great.

    *amendment*

    i neglected to notice that i was also using the dock property, which was hosing my testing. so...

    1. i did not set the window state on the form object in design view (left it "normal")
    2. my method to set child forms uses the following:

                    childForm.Dock = DockStyle.Fill;
                    childForm.FormBorderStyle = FormBorderStyle.None;
                    //childForm.ControlBox = false;
                    childForm.MaximizeBox = false;
                    childForm.MinimizeBox = false;
                    childForm.AutoScroll = true;
                    //childForm.WindowState = FormWindowState.Maximized;
                    //childForm.WindowState = FormWindowState.Normal;
                    childForm.Show();

    • Edited by JustinChoponis Saturday, January 4, 2014 4:21 AM mistake!
    • Proposed as answer by AustinGGGG Thursday, May 22, 2014 9:26 PM
    • Unproposed as answer by AustinGGGG Thursday, May 22, 2014 9:26 PM
    Saturday, January 4, 2014 4:12 AM
  • I just fixed this mess.  You need to set your MDIParent on your main form.

    For Example.  I don't want my maximized Form2 to show the control or an icon.  I want it to be a child of Form1.

    Private Sub Form1_Load...

    Me. WindowState = FormWindowState.Maximized

    Form2.MdiParent = me

    Form2.Show()

    End Sub

    Private Sub Form2_Load

    Me.ControlBox = False

    Me.MinimizeBox = False

    Me.MaximizeBox = False

    me.WindowState = FormWindowState.Maximized

    End Sub

    - Austin

    Thursday, May 22, 2014 9:31 PM
  • @nafezz: Intelligent work around. This is by far the most optimal solution.

    However I would like to know how do you classify particularly which one of the three ControlBoxMenuItems to work with. Suppose, I want to make only the 'Restore' button invisible. How is that attainable?

    Regards!

    Thursday, August 6, 2015 4:42 PM
  • Will the ToString() output always be in English no matter what language the .NET Framework or CLR is?

    @K.Kong: MdiControlStrip is the name of the MenuStrip class that contains those four controls. Also, the type of the Mdi child icon and its menus is SystemMenuItem; whereas the type of the 'Minimize', 'Restore' and 'Close' buttons is ControlBoxMenuItem. So I think it's very likely that the string of the return type will be the same across all languages.

    However, the significant question here is, how do you classify particularly which ControlBoxMenuItem to work with. Suppose, I want to make the 'Restore' button invisible. How do I go ahead with that? Any idea?

    Regards!

    Thursday, August 6, 2015 4:51 PM
  • Hello,

    to hide only the mdi child icon on the left side, try this

    private void menuStrip1_ItemAdded(object sender, ToolStripItemEventArgs e)
          {
             string s = e.Item.GetType().ToString();
             if (s == "System.Windows.Forms.MdiControlStrip+SystemMenuItem")
             {
                e.Item.Visible = false;
             }
          }

    The 3 controlbox menu items are of type "System.Windows.Forms.MdiControlStrip+ControlBoxMenuItem".



    Hope it helps
    nafezz

    That was my solution.

    private void menuStrip1_ItemAdded(object sender, ToolStripItemEventArgs e){
       string s = e.Item.GetType().ToString();
       if (s == "System.Windows.Forms.MdiControlStrip+SystemMenuItem")
       {
             menuStrip1.Items.RemoveAt(e.Item.MergeIndex);
       }
    }

    Thanks guys!


    Eduardo García.

    Monday, March 21, 2016 10:11 AM
  • Thanks. It is working perfectly..:)
    Thursday, September 22, 2016 6:04 AM