Hi
I subclassed a command button and im trying to capture the WM_MOUSELEAVE message.
But it doesnt seem to run by through the WndProc
Anyone know how to use this?
Thanks
Printable View
Hi
I subclassed a command button and im trying to capture the WM_MOUSELEAVE message.
But it doesnt seem to run by through the WndProc
Anyone know how to use this?
Thanks
No such event exists unfortunately. I take it you are trying
to respond to an 'Enter' and 'Leave' event... probably to make
the button look one way when the mouse is over it and another
when its somewhere else. Probably the simplest way to do this
is set up a low priority timer that calls WindowFromPoint ()
repeatedly. When the hWnd from the button is returned you
can set some flag/event indicating that you have entered the
button and when the hWnd from something else is returned you
can set some flag/event indicating that you have left the button.
-CC
Yup??Code:Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function GetCapture Lib "user32" () As Long
'MouseEnter And MouseExit Code
Private Sub Button_MouseMove(Button As Integer, Shift As Integer, X As Single, _
Y As Single)
If (X Or Y) < 0 Or (X > Button.Width) Or (Y > Button.Height) Then
'Your mouse has left the button
msgbox "mouse Exit"
ElseIf GetCapture() <> Button.hwnd Then
SetCapture Button.hwnd
'This is where your Mouse Enter and all your normal mouse move stuff happens 'eh
End If
End Sub
Been there. Done that. Unfortunately it is not 100% reliable.
Just an example:
* Launch your sample.
* Launch Notepad.
* Place both apps windows on top of each other.
* Bring your sample to the foreground.
* Put the mouse in the button.
* ALT-TAB to Notepad.
Notice that the exit event does not get triggered. There are other
ways to see this type of behavior even when your sample remains
the foreground window. One thing that I like to do is set a
system-wide message hook to trap all mouse motion events.
When the mouse position changes, you can check the handle
that it's over and respond accordingly. The downside is that a
system-wide hook requires the creation of a C-callable DLL. VB
can't make one of those, but VC, VC++ can. The timer approach
(although potentailly expensive in CPU time) tends to be fairly
easy to implement and does not suffer from the limitations of the
SetCapture () approach.
System wide hook???
I tend to disagree that a system wide hook would use up a lot of resources AND what's the point of getting EVERY SINGLE mouse message for windows, when reality says that this guys program is more than likely relativley small... Fair enough if it was office or something big and there was a great chance that anyone using the program is going to mostly deal with his interface while the program is running, but seriously...
I find the timer approach slows down windows also... (keep in mind that Vb can only have 4 timers running at any 1 time, other wise crash-crash.
Realisticly I find the previous message, the best solution. Sure.. it has a few minor drawbacks, but who's gonna open up notepad and do all that?? :S It's good enough 4 me.
It's just a personal ethic I guess. If the app is big or small, I
try to make the highest quality components as possible. Anyhow,
I never made any claims about the System-wide hook being
resource intensive. I did claim that the timer approach could be.
That's an interesting 4-timer-crash observation you made. I
never looked into it that far... but I have personally been so
dissappointed with the standard VB timer that I created one from
scratch (which load-tested at 20 instances just fine... no crashes
or anything).
Anyhow regarding the 'best' solution. Thats something
Geespot will have to decide for himself.
-CC
Using the EventVB.dll you can do this thus:
VB Code:
Option Explicit Dim WithEvents vbLink As EventVB.APIFunctions Dim WithEvents vbWnd As EventVB.ApiWindow Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Command1.Caption = "Mouse over" End Sub Private Sub Form_Load() Set vbLink = New APIFunctions Set vbWnd = New ApiWindow vbWnd.hWnd = Me.Command1.hWnd vbWnd.MouseLeaveTracking = True vbLink.SubclassedWindows.Add vbWnd End Sub Private Sub vbWnd_MouseLeave() Command1.Caption = "Mouse off" End Sub
The API involved is TrackMouseEvent...
Hope this helps,
Duncan
Quote:
Originally posted by Wak
Yup??Code:Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function GetCapture Lib "user32" () As Long
'MouseEnter And MouseExit Code
Private Sub Button_MouseMove(Button As Integer, Shift As Integer, X As Single, _
Y As Single)
If (X Or Y) < 0 Or (X > Button.Width) Or (Y > Button.Height) Then
'Your mouse has left the button
msgbox "mouse Exit"
ElseIf GetCapture() <> Button.hwnd Then
SetCapture Button.hwnd
'This is where your Mouse Enter and all your normal mouse move stuff happens 'eh
End If
End Sub
Thanks everyone, this will do perfect
im creating a email app and i just want small extras in the ui, and i wanted a mouseleave event so i could highlight certain controls when mouse was over