I have read many tips about using MouseMove events to create an Explorer-like coolbar look. The problem is that if your button is located close to the main form’s border and you move the mouse too fast, the pointer jumps to the desktop or to another window without firing a Form_MouseMove event, and your button still has the “active” look.
The Command1_MouseMove event allows you to intercept the moment when the mouse pointer moves in or passes over the button, and you can easily assign an “active” picture to the button within this event. But you cannot intercept the moment when the pointer leaves the button using Form_MouseMove or any other Control_MouseMove or LostFocus event. To do this, you need to use two Windows APIs: SetCapture and ReleaseCapture. SetCapture directs all mouse events to the button, so you can trap the mouse at any point on the screen. ReleaseCapture releases mouse events, restoring standard behavior. The only thing you have to do with these APIs is check the pointer’s coordinates to determine when it leaves the button:
Declare Function ReleaseCapture Lib "user32" () _ As LongDeclare Function SetCapture Lib "user32" (ByVal _ hWnd As Long) As LongPrivate Sub SSCommand1_MouseMove(Button As _ Integer, Shift As Integer, X As Single, Y As _ Single) Dim ret As Long Static flagInside As Boolean If X < 0 Or X > SSCommand1.Width Or _ Y < 0 Or Y > SSCommand1.Height Then ' pointer is out flagInside = False ret = ReleaseCapture() SSCommand1.Picture = _ ImageList1.ListImages("gray").Picture SSCommand1.BevelWidth = 0 Else ' pointer is in If flagInside = False Then flagInside = True ret = SetCapture(SSCommand1.hWnd) SSCommand1.Picture = _ ImageList1.ListImages( _ "color").Picture SSCommand1.BevelWidth = 1 End If End IfEnd Sub
As you can see, you don’t need to use any other events except SSCommand1_MouseMove.
Use the flagInside variable to prevent the icon from blinking while the pointer passes over the button. While you drag the mouse over the button, the MouseMove event fires repeatedly. You don’t need to assign the “active” picture every time if it has already been assigned.