Results 1 to 16 of 16

Thread: [RESOLVED] Close all Forms except main Form

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Resolved [RESOLVED] Close all Forms except main Form

    Hello vbforums
    I need to close any opened form except the main form
    I'm using this function
    Public Sub EndForms()
    For Each currentForm As Form In Application.OpenForms
    If currentForm.Name <> "MainForm" Then
    currentForm.Close()
    End If
    Next
    End Sub
    In toolstrip click, I use:

    Code:
    Private Sub ToolS1_Click(sender As Object, e As EventArgs) Handles ToolS1.Click
            EndForms()
            frm2.Show(Me)
        End Sub
    Code:
    Private Sub ToolS2_Click(sender As Object, e As EventArgs) Handles ToolS2.Click
            EndForms()
            frm3.Show(Me)
        End Sub
    The problem is that I have to click twice so as the code is executed.
    How can I make the code execute by clicking just once?
    thank you
    Last edited by Adebiyi24; Aug 6th, 2022 at 02:12 PM.

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Close all Forms except main Form

    Is the empty Handles clause in that last snippet just a copy paste error, or is it actually missing?

    What do you see when you step through the code? What is the state of frm2 at the time that you call .Show on it?
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    Is the empty Handles clause in that last snippet just a copy paste error, or is it actually missing?
    thank you for your interest
    just a copy paste error
    What do you see when you step through the code?
    I get this error
    An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
    But when adding Try and catch , I need two clicks to execute the code.
    What is the state of frm2 at the time that you call .Show on it?
    It is in a state of closing
    thanks

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Close all Forms except main Form

    That exception is probably because you're enumerating a list and modifying it within the loop. Closing a form is going to modify the OpenForms list.

    I assume that this code is in the main form itself. If so then Me is a reference to the main form, so you can close each open form other than Me. To do that while not modifying the list you're enumerating, create an array first. Here are two options:
    vb.net Code:
    1. For Each frm In Application.OpenForms.Cast(Of Form)().ToArray()
    2.     If frm IsNot Me Then
    3.         frm.Close()
    4.     End If
    5. Next
    vb.net Code:
    1. For Each frm In Application.OpenForms.Cast(Of Form)().Except({Me}).ToArray()
    2.     frm.Close()
    3. Next

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    jmcilhinney thanks a lot
    In fact I figured out that the problem is in the toolstrip click event.
    I have used your codes but instead of using Toolstrip_Click, I have used Button_Click and everything goes fine.
    However under Toolstrip_Click, I need to click twice to get the code executed.
    I wonder if there is a solution to this issue.
    thanks again

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Close all Forms except main Form

    You don't actually need to click the ToolStripButton twice. It's a focus issue. The click on the ToolStripButton will not be registered unless the form containing it has focus. Notice that, if you click the form to give it focus first and then click the ToolStripButton, it works as expected. I'm not sure whether there's a way around that or not.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    Quote Originally Posted by jmcilhinney View Post
    You don't actually need to click the ToolStripButton twice. It's a focus issue. The click on the ToolStripButton will not be registered unless the form containing it has focus. Notice that, if you click the form to give it focus first and then click the ToolStripButton, it works as expected. I'm not sure whether there's a way around that or not.
    YOU are right sir
    It is question of focus
    I added
    Code:
    Me.Focus()
    at the end of EndForms() function but didn't solve the issue
    Code:
    For Each frm In Application.OpenForms.Cast(Of Form)().Except({Me}).ToArray()
                    frm.Close()
                Next
                Me.Focus()

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Close all Forms except main Form

    Read the documentation for that Focus method and you'll see what you should be doing instead. ALWAYS read the documentation. That's not really a solution though, because you're back in the same boat as soon as the user clicks the second form.

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Close all Forms except main Form

    There seems to be a genuine solution here:

    https://stackoverflow.com/questions/...-a-mouse-click

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    Quote Originally Posted by jmcilhinney View Post
    There seems to be a genuine solution here:

    https://stackoverflow.com/questions/...-a-mouse-click
    I can't figure out how to use that class

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Close all Forms except main Form

    It looks like there's a bit of translation, and the blog link in that post appears to have expired. The code will look roughly like this:

    Code:
     Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)
            MyBase.WndProc(m)
            If m.Msg = WM_MOUSEACTIVATE AndAlso m.Result = MA_ACTIVATEANDEAT  Then
                m.Result = MA_ACTIVATE
            End If
    
        End Sub
    However, you will need to get the values for those constants. WM_MOUSEACTIVATE is relatively easy. I didn't find a quick reference for the other two, though. I also left out the casting to and from an IntPtr.
    My usual boring signature: Nothing

  12. #12
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,479

    Re: Close all Forms except main Form

    Code:
    Const WM_MOUSEACTIVATE As Integer = &H15
    Const MA_ACTIVATEANDEAT As Integer = &H2
    Const MA_ACTIVATE As Integer = &H1

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    I found a trick to overcome the issue
    In ToolStrip1_MouseEnter, I put :
    Code:
    ToolStrip1.Focus()
    and in ToolStripButton_click, I call Endforms()
    Then it worked

  14. #14
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Close all Forms except main Form

    Quote Originally Posted by Adebiyi24 View Post
    I found a trick to overcome the issue
    In ToolStrip1_MouseEnter, I put :
    Code:
    ToolStrip1.Focus()
    and in ToolStripButton_click, I call Endforms()
    Then it worked
    That's a bad solution again. The fact that the user's mouse passes over a part of a form doesn't mean that they want to focus that form. You've got a proper solution that does what you actually want to do, i.e. focuses the form immediately when you click a ToolStripButton so that the button registers the Click. Maybe use that.

    One of the answers to the SO question I linked to has a full VB code solution. All you have to do is add that class to your project, use that ToolStripExtended class instead of the regular ToolStrip and then set the ClickThrough property to True. Voila, it works exactly as you want.

    If you don't want to delete the ToolStrip you already have and create another, simply open the designer code file and change the type of ToolStrip1 from ToolStrip to ToolStripExtended. To get to that designer code file, you'll need to click the Show All Files button in the Solution Explorer and then expand the node for your form. I suggest creating a backup of the solution folder first, because doing something wrong in that designer code file will prevent the form being displayed in the designer.

  15. #15
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,479

    Re: Close all Forms except main Form

    Quote Originally Posted by Shaggy Hiker View Post
    It looks like there's a bit of translation, and the blog link in that post appears to have expired. The code will look roughly like this:

    Code:
     Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)
            MyBase.WndProc(m)
            If m.Msg = WM_MOUSEACTIVATE AndAlso m.Result = MA_ACTIVATEANDEAT  Then
                m.Result = MA_ACTIVATE
            End If
    
        End Sub
    However, you will need to get the values for those constants. WM_MOUSEACTIVATE is relatively easy. I didn't find a quick reference for the other two, though. I also left out the casting to and from an IntPtr.
    Wouldn't MyBase.WndProc(m) be better placed at the end of the sub?

    Code:
     Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)        
        If m.Msg = WM_MOUSEACTIVATE AndAlso m.Result = MA_ACTIVATEANDEAT  Then
            m.Result = MA_ACTIVATE
        End If
        MyBase.WndProc(m)
    End Sub

  16. #16

    Thread Starter
    Lively Member
    Join Date
    Mar 2021
    Posts
    108

    Re: Close all Forms except main Form

    jmcilhinney
    thanks a lot
    it worked

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width