Generating MouseLeave Events for a Window
Almost all of the more recent windows control support a feature known as "Hot-Tracking" - that is, when the control appears to highlight when the mouse moves over it, then returns to normal when the mouse leaves. Common examples include the flat toolbar buttons provided with the Windows Commmon controls.
This article demonstrates how to add this to your controls - properly.
Getting a VB control to highlight when the mouse moves over it is very simple - you just detect the MouseMove event. If you get one of these events, then the mouse is over the control. However, how do you detect when the mouse leaves the control? You can't use MouseMove, because it doesn't fire often when the mouse is leaving the control. And you can't (say) just detect mouse move events over the form the control is on, because the next MouseMove event may occur over another control even if the mouse passes over the form when it moves.
There are many possible solutions to this problem, from the simple (using a Timer, as suggested in the VB5 Owners Area on the Microsoft site - simple, but...) to installing a Windows Hook procedure to give your control a peek at all the Mouse Messages (surely overkill). However, there are some propert ways to do it, and some of them are even part of the OS.
Built-in Tracking Support... Sometimes
The most irritating thing about doing a MouseLeave event properly is the fact that MS have fully implemented this feature, but only in certain OS. NT4 implements this method, as does Win98 and the (possibly) forthcoming Win2000. In Windows 95 you can get at an emulation of the method which is coded in COMCTL32.DLL, but only if IE3.02 or higher is installed. So... if your application needs to support Win95 without a newer COMCTL32.DLL installed, or if you need to run on NT3.51, you can't get OS support to code this correctly.
Here is a summary of what you get:
To work around these problems, the code I provide here includes automatic detection of OS version and (if required) COMCTL32.DLL version to determine which method to use, and includes a method which will work regardless of OS version (provided the OS runs full Win32 or an emulation, at least!).
TrackMouseEvent, whether with an underscore or not
This method works by posting messages to your window when the mouse pointer leaves or hovers over the window for a specified period of time. You first call TrackMouseEvent supplying the window handle for Windows to start tracking mouse events. When Windows detects the Mouse Leaves the control, it posts a WM_MOUSELEAVE message to the window and then stops tracking the mouse. The TrackMouseEvent event call can then be made again.
This call can also be configured to post WM_MOUSEHOVER messsages too. Mouse Hover is defined as the mouse staying within a specified rectangle for more than a certain length of time. The rectangle and time to hover can be modified by a call to SystemParametersInfo. This works in exactly the same way as MouseLeave does - when it posts an event it then stops tracking.
How to Emulate TrackMouseEvent with SetCapture and ReleaseCapture
If you don't have TrackMouseEvent support, you can emulate its working. using the SetCapture method. This re-directs all mouse movement to a specified Window until it is either called again or ReleaseCapture is called. This means that if you call SetCapture on a window, and then move the mouse out of it, you will still receive a Mouse Move event when the cursor leaves the control, and therefore you can detect that the mouse has left. There are two things to note about this method:
To emulates the operation of TrackMouseEvent method the code subclasses for the following messages:
How to Use the cMouseTrack class
The cMouseTrack exposes the following methods and properties:
The following code outline demonstrates how this class is used:
' Declare an instance of the cMouseTrack object: Private WithEvents m_cPTM As cMouseTrack Private Sub Form_Load() ' Initialise the object to detect the mouse ' leaving picTrack: Set m_cPTM = New cMouseTrack m_cPTM.AttachMouseTracking picTrack End Sub Private Sub picTrack_MouseMove( _ Button As Integer, Shift As Integer, _ x As Single, y As Single) ' Tracking is initialised by entering the control: If Not (m_cPTM.Tracking) Then ' Mouse has entered the control; highlight it hot here. ' And start checking for mouse leave: m_cPTM.StartMouseTracking End If End Sub ' Respond to MouseHover and MouseLeave events Private Sub m_cPTM_MouseHover( _ Button As MouseButtonConstants, _ Shift As ShiftConstants, _ x As Single, y As Single) ' Respond to Hover as required: ' When the Hover event is fired, mouse tracking stops, so ' tell the class to start checking again: m_cPTM.StartMouseTracking End Sub Private Sub m_cPTM_MouseLeave() ' Mouse has left the control, remove the highlight: End Sub
The cMouseTrack class encapsulates all you need to easily add a MouseLeave event to a UserControl or standard VB control on your form. Its just up to you to use it to do something better than my pop-up Ren and Stimpy sample supplied with the download code...