|
-
Jan 3rd, 2002, 03:48 PM
#1
Thread Starter
Lively Member
mouse over control
The following code is a way to use API to tell when a control no longer has the mouse over it. Any ideas how to find when a control gets the mouse over it using API?
Code:
Public Const TME_CANCEL = &H80000000
Public Const TME_HOVER = &H1&
Public Const TME_LEAVE = &H2&
Public Const TME_NONCLIENT = &H10&
Public Const TME_QUERY = &H40000000
Public Const WM_MOUSELEAVE = &H2A3&
Public Type TRACKMOUSEEVENTTYPE
cbSize As Long
dwFlags As Long
hwndTrack As Long
dwHoverTime As Long
End Type
Public Declare Function TrackMouseEvent Lib "user32" (lpEventTrack As TRACKMOUSEEVENTTYPE) As Long
Public Declare Function SetCursorPos Lib "user32.dll" (ByVal x As Long, ByVal y As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public PrevProc As Long
Public Sub HookForm(F As Control)
PrevProc = SetWindowLong(F.hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnHookForm(F As Control)
SetWindowLong F.hWnd, GWL_WNDPROC, PrevProc
End Sub
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_MOUSELEAVE Then
'if we receive a WM_MOUSELEAVE message, show it
Form1.Print "The mouse left the button!"
End If
WindowProc = CallWindowProc(PrevProc, hWnd, uMsg, wParam, lParam)
End Function
--------------------------------------------------------------------------------
into a form
visual basic code:--------------------------------------------------------------------------------Private Sub command1_Click()
Dim ET As TRACKMOUSEEVENTTYPE
'initialize structure
ET.cbSize = Len(ET)
ET.hwndTrack = Command1.hWnd
ET.dwFlags = TME_LEAVE
'start the tracking
TrackMouseEvent ET
'show a message to the user
Me.Print "Move the mouse cursor outside the button" + vbCrLf + "to generate a WM_MOUSELEAVE event"
End Sub
Private Sub Form_Load()
MsgBox "WARNING: This sample uses subclassing." + vbCrLf + "To end this program, always use the X button of the form." + vbCrLf + "Do not use VB's Stop button and do not use the 'End' keyword in your VB code." + vbCrLf + vbCrLf + "For more information about subclassing, check out" + vbCrLf + "our subclassing tutorial at http://www.allapi.net/", vbExclamation
'set the graphics mode to persistent
Me.AutoRedraw = True
Me.Print "Click the button to begin"
'start subclassing this form
HookForm Command1
End Sub
Private Sub Form_Unload(Cancel As Integer)
'stop subclassing this control
UnHookForm Command1
End Sub
Everytime
"I'm not normally a religious man, but if you're up there, save me, Superman!" Homer Simpson
Visit my site
-
Jan 3rd, 2002, 04:08 PM
#2
Add the following code to a Form with a Timer. Set it's Interval to 1.
VB Code:
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Sub Timer1_Timer()
Dim PT As POINTAPI
Dim RC As RECT
GetWindowRect hwnd_of_window, RC
GetCursorPos PT
If (PT.x > RC.Left And PT.x < RC.Right) And (PT.y > RC.Top And PT.y < RC.Bottom) Then
'Mouse is over it
End If
End Sub
-
Jan 3rd, 2002, 04:39 PM
#3
Thread Starter
Lively Member
thanks
is there a bad overhead on cpu usage (or whatever) with having such a timer?
Everytime
"I'm not normally a religious man, but if you're up there, save me, Superman!" Homer Simpson
Visit my site
-
Jan 3rd, 2002, 05:39 PM
#4
It's not the best method, but with today's computers, you probably won't notice the different. If you want though, you could set the Interval to a higher number so that the code doesn't execute as much.
Do you need this to work for all windows? Or just windows that are in your project?
-
Jan 4th, 2002, 04:35 AM
#5
Thread Starter
Lively Member
it's just for windows in the project so it shouldn't be too stressful. Thanks for the idea
Everytime
"I'm not normally a religious man, but if you're up there, save me, Superman!" Homer Simpson
Visit my site
-
Jan 4th, 2002, 07:20 AM
#6
Here are a couple of examples for detecting when a mouse is over a control, when it has left the control, and doing certain things to the control depending on where the mouse is, without using a timer.
VB 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
'From VB2TheMax.Com
'MouseEnter And MouseExit Code
'NOTE: To use this code to change the background color of a command
'button, the command button style MUST be set to graphical
Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If (X < 0) Or (Y < 0) Or (X > Command1.Width) Or (Y > Command1.Height) Then ' the MOUSELEAVE pseudo-event
ReleaseCapture ' in this example revert the caption to normal
Command1.Font.Bold = False
ElseIf GetCapture() <> Command1.hwnd Then ' the MOUSEENTER pseudo-event
SetCapture Command1.hwnd ' in this example, make the caption bold
Command1.Font.Bold = True
End If
End Sub
'You can apply this tip to all controls that have the hWnd property, such as PictureBox,
'ListBox, etc, for example to easily implement hot-tracking effects. Here is another example
'that selects the text of a textbox (Text1) when the cursor is over.
Private Sub Text1_MouseMove(Button As Integer, Shift As Integer, X As Single, _
Y As Single)
If (X Or Y) < 0 Or (X > Text1.Width) Or (Y > Text1.Height) Then
ReleaseCapture
Text1.SelLength = 0
ElseIf GetCapture() <> Text1.hWnd Then
SetCapture Text1.hWnd
Text1.SelStart = 0
Text1.SelLength = Len(Text1)
Text1.SetFocus
End If
End Sub
'To change the backcolor of a command button
Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If (X < 0) Or (Y < 0) Or (X > cmdClose.Width) Or (Y > cmdClose.Height) Then ' the MOUSELEAVE pseudo-event
ReleaseCapture ' the mouse is no longer over the button, change backcolor to gray
cmdClose.BackColor = &HC0C0C0
ElseIf GetCapture() <> cmdClose.hwnd Then ' the MOUSEENTER pseudo-event
SetCapture cmdClose.hwnd ' the mouse is over the button, change backcolor to cyan
cmdClose.BackColor = vbCyan
End If
End Sub
-
Jan 4th, 2002, 10:44 AM
#7
That's for MouseEnter, and MouseLeave, not MouseOver.
Everytime: Personally, I don't see anything wrong with using a Timer. In order to check a "MouseOver" event, you'll inevitably need to use some type of loop, so might as well use VB's Timer.
-
Mar 22nd, 2002, 07:21 PM
#8
Fanatic Member
is there any point in using an API timer?
/: Tim :\____________________
\: VB, HTML, ASP, VBScript, QBASIC, JavaScript :/
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|