VB .NET: using onMouseLeave on form

I'm creating a form that expands, and when the user moves the mouse off the expanded form, I want to trigger the resize to normal. It also seems that if the mouse enters a control on the form it triggers the form's onMouseleave event.

I am setting the size by: me.height = 100

But the onMouseleave event seems to fire when the mouse moves onto a control, or moves past the OLD size of the form.

How can I get the onMouseleave event not to fire if i move into a control it owns, and to use the form's new size when calculating if the user has moved the mouse out of it?

Is this a good approach: when the form's onMouseLeave event is triggered determine if the mouse is in the border of the form? How would I do that?

Thanks!
majnunAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
moduloConnect With a Mentor Commented:
PAQed with points refunded (500)

modulo
Community Support Moderator
0
 
andrewharrisCommented:
I would use the fors LostFocus Event instead.

Andrew
0
 
majnunAuthor Commented:
Yeah, but the expanded form might be covering up the other windows, so it's better to use a modified "mouseOut" functionality so that the user can actually click the other forms to change the focus.

I'm working on figuring out how to check the mouse position against the actual boundaries of the form.
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
toddhdCommented:
   Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        If (e.X > 0 And e.X < Me.Width) And (e.Y > 0 And e.Y < Me.Height) Then
            Me.Width = 400
            Me.Height = 400
        Else
            Me.Width = 300
            Me.Height = 300
        End If
    End Sub
0
 
toddhdCommented:
Sorry, change the form values to whatever you want - but you get the idea
0
 
majnunAuthor Commented:
toddhd:

on the right track, but the problem is that it only shrinks when i move the mouse out slowly to the left... if i move out quickly or exit the form rectangle in any other direction it stays at the bigger dimensions.

0
 
toddhdCommented:
I'll keep thinking - in the meantime, if it's not a high-perf app, you can add a loop or timer somewhere to call OnMouseMove on a given interval - say, every one second. That might help. Better yet, skip the event altogether and just track the mouse in a loop (I'm old an school game programmer - that's how I'd do it anyway).

Just FYI - I'm not having that problem on my machine - even fast, it's working.
0
 
majnunAuthor Commented:
Ok here's what i did and it works (add to the forms onMouseLeave event):

  Dim X, Y, Xoffset, Yoffset, Mx, My As Integer
        Dim off As Boolean = False
        Xoffset = 5 'border pixels
        Yoffset = 35 'titlebar & border pixels

        X = Me.Width - Xoffset
        Y = Me.Height - Yoffset
        Mx = Me.PointToClient(Me.MousePosition).X
        My = Me.PointToClient(Me.MousePosition).Y
     
        If Mx >= X Or Mx < 1 Then off = True
        If My >= Y Or My < 1 Then off = True

        If off then 'shrink window

Can someone help me refine this so that it automatically takes the title bar and form border into consideration, so that i can use the same function for different form types (with and without title bars, dialogs, etc. etc.) and at different screen resolutions (becase as it stands i think the offsets will need to change based on the screen resolution, no?)

If anyone has a better way of doing this please let me know.
0
 
majnunAuthor Commented:
I like toddhd solution of overriding the onMouseMove sub better than mine, seems more efficient... i wonder why i cant get it to work properly... any thoughts?
0
 
hagipmcCommented:
majnun ,
check out bounds property!
from msdn:
"
.NET Framework Class Library  

Control.Bounds Property
Gets or sets the size and location of the control including its nonclient elements.

[Visual Basic]
Public Property Bounds As Rectangle
[C#]
public Rectangle Bounds {get; set;}
[C++]
public: __property Rectangle get_Bounds();
public: __property void set_Bounds(Rectangle);
[JScript]
public function get Bounds() : Rectangle;
public function set Bounds(Rectangle);
Property Value
A Rectangle that represents the size and location of the control including its nonclient elements.

Remarks
The bounds of the control includes the nonclient elements such as scroll bars, borders, title bars, and menus. The SetBoundsCore method is called to set the Bounds property. The Bounds property is not always changed through its set method so you should override the SetBoundsCore method to ensure that your code is executed when the Bounds property is set.
"
0
 
toddhdCommented:
Majnun,

FYI again, I think I just "lucked out" last night - I tried it again this morning, and it's not working so well - I'm still working on it when I can... just wanted to let you know "it's not you" :)
0
 
toddhdCommented:
Ok, try this:

    Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
        Me.Width = 400
        Me.Height = 400
    End Sub

    Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
        Dim Flag As Boolean = False
        Dim c As Control
        For Each c In Me.Controls
            Dim p As Point
            p = Me.PointToClient(Me.MousePosition)
            If p.X >= c.Left And p.X <= c.Left + c.Width Then
                If p.Y >= c.Top And p.Y <= c.Top + c.Height Then
                    Flag = True
                End If
            End If
        Next

        If Not Flag Then
            Me.Width = 300
            Me.Height = 300
        End If

    End Sub
0
 
majnunAuthor Commented:
hagipmc:

Interesting, might be very helpful, but two problems I am having with it though:

1) It doesn't seem to do the trick because:

MsgBox(Me.Bounds.Height & " | " & Me.Height)

Me.Bounds.Height returns the same int as Me.Height

2) If I can get the Bounds to represent the form plus titlebar, borders, etc. when does the onMouseLeave fire? When the mouse moves out of the bounds or out of the area of the form inside the bounds?

0
 
majnunAuthor Commented:
Ok this works almost perfectly (in the form's onMouseLeave):

    Dim X, Y, Xoffset, Yoffset, Mx, My As Integer
        Dim off As Boolean = False

        X = Me.ClientSize.Width
        Y = Me.ClientSize.Height

        Mx = Me.PointToClient(Me.MousePosition).X
        My = Me.PointToClient(Me.MousePosition).Y

        If Mx >= X Or Mx < 1 Then off = True
        If My >= Y Or My < 1 Then off = True

        If off Then popBack() 'resize


I say it works almost perfectly, because if I move the mouse out really fast it doesn't seem to trigger the onMouseLeave event... i'm assuming because the mouse position "jumps" over the boundary of the client area of the form and so never triggers the onMouseLeave event.
0
 
majnunAuthor Commented:
Woops, don't need the  Xoffset, Yoffset dimmed in the above.
0
 
majnunAuthor Commented:
ok, last thing to do i think is trigger the onMouseLeave event for the form on the onMouseEnter sub of the owning form... anyone know how I can trigger one form's events from another form?

Thanks!
0
 
majnunAuthor Commented:
ok, on second thought, incase i want to use this for non-owned forms, maybe i'll start a timer when the form is expanded and poll the mouse position every few seconds incase i moved off to fast, then destroy the timer when the form shrinks.
0
 
majnunAuthor Commented:
Ok, i've figured out a solution which works for me, and in case others find the particular execution useful here's the entirety:
In plain english:
The form (mediaPlayer) has a bunch of controls, one of the controls is a panel (pnlPlaylist) which is "hidden" below the forms border (i size the control so that the panel is not visible, but sits hidden "below" everything else). This panel is revealed when the form pops (expands and reveals the hidden panel). Based on the position of the form in relation to its parent form, it either pops up or pops down. If the form pops down the size increases and reveals the panel, if the form pops up the size increases, the panel jumps to the top of the form, and the other controls are repositioned to the bottom appropriately. I create an arraylist which holds control names which need to be repositioned to the bottom of the form when the form pops down (note i exclude the panel since it is positioned explicity). When the mouse moves out of the form its checks to make sure the mouse position is actually outside the form and then pops back to the smaller position. Just incase the user moves the mouse out to fast, a timer is created and started when the form pops bigger and poles the mouse position every two seconds and closes it if the mouse is off the form (the timer is also disposed whenever the form shrinks),

In code:
    Dim popHeight As Integer = 200
    Dim poppedDown As Boolean = False
    Dim poppedUp As Boolean = False
    Dim alControls As New ArrayList()
    Dim intPnlPlaylistTop As Integer
    Dim WithEvents tmrPop As System.Timers.Timer

    Sub tmrPop_Elapsed(ByVal sender As Object, _
                            ByVal e As System.Timers.ElapsedEventArgs) _
                            Handles tmrPop.Elapsed
        ' Respond to event
        popBack()
    End Sub

    Sub pop()
        If Me.Height < popHeight Then
            tmrPop = New System.Timers.Timer()
            tmrPop.Interval = 2000
            tmrPop.Start()
            If Me.Top < (Me.ParentForm.Size.Height / 2) Then
                popDown()
            Else
                popUp()
            End If
        End If
    End Sub

    Sub popDown()
        Me.Height = Me.Height + popHeight
        poppedDown = True
    End Sub

    Sub popUp()
        Dim ctr As Control
        Me.Height = Me.Height + popHeight
        For Each ctr In alControls
            ctr.Top = ctr.Top + popHeight
        Next
        intPnlPlaylistTop = pnlPlaylist.Top
        pnlPlaylist.Top = 10 'can't be at 0 because i need to pass over the form on the way out to trigger the onMouseLeave event
        Me.Top = Me.Top - popHeight
        poppedUp = True
    End Sub

    Sub popBack()
        Dim X, Y, Mx, My As Integer
        Dim off As Boolean = False

        X = Me.ClientSize.Width
        Y = Me.ClientSize.Height

        Mx = Me.PointToClient(Me.MousePosition).X
        My = Me.PointToClient(Me.MousePosition).Y

        If Mx >= X Or Mx < 1 Then off = True
        If My >= Y Or My < 1 Then off = True

        If off Then
            If poppedUp Or poppedDown Then
                tmrPop.Dispose()
            End If

            If poppedDown = True Then
                Me.Height = Me.Height - popHeight
                poppedDown = False
            End If

            If poppedUp = True Then
                Dim ctr As Control
                Me.Height = Me.Height - popHeight
                For Each ctr In alControls
                    ctr.Top = ctr.Top - popHeight
                Next
                pnlPlaylist.Top = intPnlPlaylistTop
                Me.Top = Me.Top + popHeight
                poppedUp = False
            End If

        End If
    End Sub

    Private Sub MediaPlayer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'add all the controls to the alControls arraylist
        'use a case to check for control names not to add to arraylist
        Dim ctr As Control
        For Each ctr In Me.Controls
            Select Case ctr.Name
                Case "pnlPlaylist" 'controlName, controlName, etc. for controls not to add to the alControls arraylist
                Case Else
                    alControls.Add(ctr)
            End Select
        Next

    End Sub

    Private Sub lblPlaylist_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles lblPlaylist.MouseHover
        pop()
    End Sub

    Public Sub MediaPlayer_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
        popBack()
    End Sub



I will leave this thread open for awhile to see if anyone has come up with a more elegant solution, or has suggestions regarding this implementation.

Thanks!
0
 
majnunAuthor Commented:
MODERATOR:

Is it possible to change the title of the question to:
"Expanding/Contracting forms: onMouseOut problem"

Since i've included the whole solution in case someone is wondering how to do it?
0
All Courses

From novice to tech pro — start learning today.