|
-
Aug 9th, 2002, 01:17 AM
#1
Thread Starter
Addicted Member
Mouse Button Click
Does the API have a function to tell if the mouse button is clicked, Like GetCursorPos()?
-
Aug 9th, 2002, 05:28 AM
#2
Addicted Member
Not exactly -> when a mouse button is pressed, or released, or moved, Windows sends messages to the window under the cursor....
To detect ANY mouse button event in ANY window, you need to monitor those messages, which is possible with a global Hook procedure..
Dr Memory
Last edited by MathImagics; Aug 9th, 2002 at 05:31 AM.
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
-
Aug 9th, 2002, 08:07 PM
#3
Thread Starter
Addicted Member
-
Aug 10th, 2002, 06:34 AM
#4
Frenzied Member
don't you wish they made a GetAsyncMouseState? Is there
something that would work atleast vaguely like that?
-
Aug 10th, 2002, 03:56 PM
#5
Addicted Member
The way a global hook works is a bit like sub-classing - you call an API routine SetWindowsHookEx, passing it the address of your mouse event procedure. You can then monitor the system-wide mouse traffic, and detect events of interest, like WM_LBUTTONDOWN, WM_RBUTTONDOWN, etc..
It's possible to determine the position of the mouse when the event occurred, the window under the cursor at the time, and even what part of the window (like the title bar, control menu, window frame, etc).
Unfortunately, a VB program can only set local hooks - i.e. hooks for threads created by the prgram itself.
Only a DLL can set a system-wide mouse hook procedure. So you need a DLL to do the SetWindowsHookEx call for you. Such a DLL is provided by 3rd-party tools like DesaWare's SpyWorks.
It's not hard to make one of your own, but I don't have Visual C so I can't help....
Dr Memory
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
-
Aug 10th, 2002, 05:40 PM
#6
Thread Starter
Addicted Member
You saying I have to crate an some kind of event handler like in a C++ API app. and put it in a DLL.
-
Aug 10th, 2002, 05:58 PM
#7
Frenzied Member
No. You create a hook. Serge posted a mouse hook example, to trap right clicks. You'd want to change it to trap ANY click.
VB code here:
http://www.vbforums.com/showthread.p...tWindowsHookEx
-
Aug 10th, 2002, 06:41 PM
#8
Addicted Member
Here's an example of a hook procedure.
Module:
Code:
Option Explicit
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private MouseHookHandle As Long
Public Sub SetMouseHook()
Const WH_MOUSE = 7&
MouseHookHandle = SetWindowsHookEx(WH_MOUSE, AddressOf MyMouseHandler, App.hInstance, App.ThreadID)
End Sub
Public Sub ReleaseMouseHook()
If MouseHookHandle = 0 Then Exit Sub
UnhookWindowsHookEx MouseHookHandle
MouseHookHandle = 0
End Sub
Public Function MyMouseHandler(ByVal HookID As Long, ByVal MsgCode As Long, ByVal pMouseHookInfo As Long) As Long
Const WM_LBUTTONDOWN = &H201& ' MouseDown - Left button
Const WM_MBUTTONDOWN = &H207& ' Middle
Const WM_RBUTTONDOWN = &H204& ' Right
Const HC_ACTION = 0&
If HookID <> HC_ACTION Then GoTo PassItOn
Select Case MsgCode
Case WM_LBUTTONDOWN
Form1.List1.AddItem "Left Click "
Case WM_RBUTTONDOWN
Form1.List1.AddItem "Right Click "
End Select
PassItOn:
'
' allow mouse event to be passed on and processed normally
'
MyMouseHandler = CallNextHookEx(MouseHookHandle, HookID, MsgCode, pMouseHookInfo)
Exit Function
End Function
Create a form with 2 buttons and a list box - label the first button "Set" and the 2nd button "Release". Now paste in this code:
Code:
Private Sub Command1_Click()
SetMouseHook
Command1.Enabled = False
Command2.Enabled = True
End Sub
Private Sub Command2_Click()
ReleaseMouseHook
Command2.Enabled = False
Command1.Enabled = True
End Sub
Private Sub Form_Load()
Command1.Enabled = True
Command2.Enabled = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
ReleaseMouseHook
End Sub
When you run it, and press the "Set" button - any left or right click on the form itself will cause the hook procedure to register the event in the list box.
BUT, click on another window in another application and it won't register. The reason is that the call to SetWindowsHookEx says we only want mouse events in our own application passed through to our hook procedure. That's a LOCAL hook.
To set a GLOBAL hook, the last parameter must be 0, but if you look up the MSDN entry for SetWindowsHookEx, it tells you that the procedure making the call can only request a global hook if it's calling from a DLL.
Add-ins like SpyWorks give you such a DLL, and give you a control that you can use in your VB program which has a method to establish the hook, and Events that the DLL will trigger so you can get notification of the mouse events.
Dr Memory
Last edited by MathImagics; Aug 10th, 2002 at 06:46 PM.
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
-
Aug 10th, 2002, 07:20 PM
#9
The picture isn't missing
Originally posted by macai
don't you wish they made a GetAsyncMouseState? Is there
something that would work atleast vaguely like that?
GetAsyncKeyState doesn't just only get KeyBoard. by using these 3 constants:
Private Const VK_LBUTTON = &H1
Private Const VK_RBUTTON = &H2
Private Const VK_MBUTTON = &H4
you could check for the mouse buttons w/o hooking.
Last edited by BuggyProgrammer; Aug 10th, 2002 at 07:24 PM.
Remember, if someone's post was not helpful, you can always rate their post negatively  .
-
Aug 10th, 2002, 07:34 PM
#10
Addicted Member
Hmmm, doesn't that only work if your own app has the focus?
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
-
Aug 10th, 2002, 07:46 PM
#11
The picture isn't missing
wait let me rephrase that. it will work whenever and whereever. not only your own app focus.
Remember, if someone's post was not helpful, you can always rate their post negatively  .
-
Aug 10th, 2002, 07:52 PM
#12
Addicted Member
Well, you're absolutely right serves me right for believing MSDN!
Well spotted, BuggyProgrammer!
So our friend just needs to run a timer, like this:
Code:
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Const VK_LBUTTON = &H1
Private Const VK_RBUTTON = &H2
'
' following is only needed if you want to identify the window
' in which the mouse is being clicked
'
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Sub Timer1_Timer()
Static lastvalL%, lastvalR%
Dim thisvalL%, thisvalR%
Dim cpoint As POINTAPI
thisvalL = GetAsyncKeyState(VK_LBUTTON)
If thisvalL <> lastvalL Then
lastvalL = thisvalL
If thisvalL <> 0 Then
GetCursorPos cpoint
List1.AddItem "Left Click - " & Hex(WindowFromPoint(cpoint.X, cpoint.Y))
End If
End If
thisvalR = GetAsyncKeyState(VK_RBUTTON)
If thisvalR <> lastvalR Then
lastvalR = thisvalR
If thisvalR <> 0 Then
GetCursorPos cpoint
List1.AddItem "Right Click - " & Hex(WindowFromPoint(cpoint.X, cpoint.Y))
End If
End If
End Sub
Sorry to mislead! mea culpa, mea culpa, etc.....
Dr Memory
Last edited by MathImagics; Aug 10th, 2002 at 07:57 PM.
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
-
Aug 10th, 2002, 07:59 PM
#13
The picture isn't missing
but it won't work at the same precision as the hook. if you hold the button down it will keep adding the item.
Remember, if someone's post was not helpful, you can always rate their post negatively  .
-
Aug 10th, 2002, 08:34 PM
#14
Addicted Member
It's probably good enough for our "client"'s purposes, with any luck..
Also, the example I posted looks at the bit that tells you if there's been any change since the last call, so you don't get continuous repetition if you hold the button down....
Dr Memory
"He's got a B.A. (in be-bop), a Ph.D. (in swing), he's a Master of Rhythm, he's the Rock'n'Roll king"  ("The Rock'n'Roll Doctor", Lowell George)
"If you push something hard enough, it will fall over" (Fudd's Third Law of Opposition)
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
|