Sign in to follow this  
Followers 0
jonkri

Detect and act upon mouse clicks?

14 posts in this topic

Hello everyone!

My apologies if this is already covered in the API or in the forums, but I've been searching around for a couple of hours now without much success.

I want my application to act upon mouse clicks in certain windows. Ideally, I imagine something event-driven. I don't want to check if the mouse button is clicked in a loop since theoretically I could miss it if it's brief enough.

So in short: whenever the user clicks the mouse, I want to perform certain operations in my application. Furthermore, I want to know what window that has been clicked on.

Thanks in advance!

Share this post


Link to post
Share on other sites



Hello everyone!

My apologies if this is already covered in the API or in the forums, but I've been searching around for a couple of hours now without much success.

I want my application to act upon mouse clicks in certain windows. Ideally, I imagine something event-driven. I don't want to check if the mouse button is clicked in a loop since theoretically I could miss it if it's brief enough.

So in short: whenever the user clicks the mouse, I want to perform certain operations in my application. Furthermore, I want to know what window that has been clicked on.

Thanks in advance!

well, I can't give all the answers as I really haven't done a lot with mouse clicks, but this should get you started at least.

look at the WinAPI udfs in the help file, you can use some functions, such as _WinAPI_GetMousePos (),_WinAPI_GetWindowRect(), and _WinAPI_PtInRect() to help with getting the window that the mouse is in when clicked,

Maybe use _IsPressed() to detect clicks, not really sure on this one.


[u]You can download my projects at:[/u] Pulsar Software

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi guys

That mousehook is pretty slick but it runs the CPU at 15-20% whenever the mouse is moving. Still might be a good approach in some cases.

The register message only works when you click on the GUI window, not elsewhere, still might work.

The GUIGetCursorInfo($hov) is the solution I have used. With a 100 ms loop it gets most mouseclicks and runs the cpu at 0%. Change it to 50 ms and it gets every click but runs at 3-4% CPU.

Picea

Edited by picea892

Share this post


Link to post
Share on other sites

Thank you for your replies!

I do need an effective (3-4% CPU load is close to the acceptable limit, might even be a little bit too high) solution that registers 100% of all clicks and works with non-AutoIt GUI's (which I assume GUIGetCursorInfo($hov) doesn't.)

Further suggestions are very welcome.

Share this post


Link to post
Share on other sites

I just realized I wasn't really reading what you said... :D

I will try using GUIGetCursorInfo. Thanks!

Share this post


Link to post
Share on other sites

After I have checked the API I realized that GUIGetCursorInfo can't register the extra buttons or scroll events, all of which are necessary in order for my application to work. I'm sorry that I forgot to mention that.

Guess I need a more effective alternative of the low level mouse hook, then?

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

After I have checked the API I realized that GUIGetCursorInfo can't register the extra buttons or scroll events, all of which are necessary in order for my application to work. I'm sorry that I forgot to mention that.

Guess I need a more effective alternative of the low level mouse hook, then?

this is quick and dirty, and still has a high cpu percentage (15% avg), but with some refining you might be able to make it work better. It might not be exactly what you want either, but it works more or less.

#include <WinAPI.au3>
#include <Misc.au3>

$dll = DllOpen("user32.dll")

While 1
    $mouseclick1 = _IsPressed("01", $dll) ;left
    $mouseclick2 = _IsPressed("02", $dll) ;right
    $mouseclick3 = _IsPressed("04", $dll) ;middle
    $mouseclick4 = _IsPressed("05", $dll) ;x1
    $mouseclick5 = _IsPressed("06", $dll) ;x2
    If $mouseclick1 = TRUE OR $mouseclick2 = TRUE OR $mouseclick3 = TRUE OR $mouseclick4 = TRUE OR $mouseclick5 = TRUE Then
        Test()
    EndIf
    Sleep(10)
WEnd

DllClose($dll)

Func Test()
    $windows = _WinAPI_EnumWindowsTop ()
    $tPoint = _WinAPI_GetMousePos ()
    For $i = 1 To $windows[0][0]
        $tRect = _WinAPI_GetWindowRect ($windows[$i][0])
        If _WinAPI_PtInRect ($tRect, $tPoint) = True Then
            MsgBox(64, "", "Mouse Button was clicked in " & $windows[$i][0])
        EndIf
    Next
EndFunc
Edited by maqleod

[u]You can download my projects at:[/u] Pulsar Software

Share this post


Link to post
Share on other sites

good solution Magleod. It didn't run my CPU up. I slowed the sleep to 50 and still caught every click.

Share this post


Link to post
Share on other sites

Okay. Played with the mouse hooking method a bit more and tweaked a script from this post written by authenticity

http://www.autoitscript.com/forum/index.ph...=GUIRegisterMsg

I think this is another viable solution for you.

The message boxes were messing me up so I wrote a hard exit (processclose)..... Press escape to get out.

#include <WinAPI.au3>

Dim Const $WM_NCXBUTTONDOWN  = 0x00AB
Dim Const $WM_NCXBUTTONUP      = 0x00AC
Dim Const $WM_NCXBUTTONDBLCLK   = 0x00AD
Dim Const $WM_MOUSEWHEEL        = 0x020A
Dim Const $WM_XBUTTONDOWN     = 0x020B
Dim Const $WM_XBUTTONUP   = 0x020C
Dim Const $WM_XBUTTONDBLCLK  = 0x020D
Dim Const $WM_MOUSELAST   = 0x020A
Dim Const $WM_LBUTTONDOWN = 0x0201
Dim Const $WM_RBUTTONDOWN = 0x0204
Dim Const $WM_MBUTTONDOWN = 0x0207 
 

Dim Const $tagMSLLHOOKSTRUCT = $tagPOINT&';dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo'

HotKeySet('{ESC}', '_EXIT')

$hFunc = DllCallbackRegister("Mouse_LL", "long", "int;wparam;lparam")
$pFunc = DllCallbackGetPtr($hFunc)
$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, _WinAPI_GetModuleHandle(0))

While 1
    sleep(100)
WEnd

Func _EXIT()
     _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hFunc)
    ProcessClose("AutoIt3.exe")
EndFunc


Func Mouse_LL($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    
    If $iCode < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndIf
    
    If $iwParam = $WM_MOUSEWHEEL Then
        MsgBox(0,"","mousewheel")
    ElseIf $iwParam = $WM_LBUTTONDOWN Then
            MsgBox(0,"","left button")
        ElseIf $iwParam = $WM_RBUTTONDOWN Then
            MsgBox(0,"","Right button")
    EndIf
   
        
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc  ;==>_KeyProc

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Hi

I might be missing some thing but here is a simple solution. The above quick and dirty solution finds all windows that

cover the mouse cursor. But if you only want the active window on top , just use the below code.

#include <WinAPI.au3>
#include <Misc.au3>


$dll = DllOpen("user32.dll")
HotKeySet("{ESC}", "Quit")
While 1
$mouseclick1 = _IsPressed("01", $dll) ;left
$mouseclick2 = _IsPressed("02", $dll) ;right
$mouseclick3 = _IsPressed("04", $dll) ;middle
$mouseclick4 = _IsPressed("05", $dll) ;x1
$mouseclick5 = _IsPressed("06", $dll) ;x2
If $mouseclick1 = TRUE OR $mouseclick2 = TRUE OR $mouseclick3 = TRUE OR $mouseclick4 = TRUE OR $mouseclick5 = TRUE Then
Test()
EndIf
Sleep(100)
WEnd

DllClose($dll)

Func Test()
$whnd = WinGetHandle("")
$sTitle = WinGetTitle($whnd)
$msg = "Mouse Button was clicked in " & $whnd & " active window title " & $sTitle
ConsoleWrite($msg & @CRLF)

;MsgBox(64, "", "Mouse Button was clicked in " & $whnd & " active window title " & $sTitle)
EndFunc



Func Quit()


Exit
EndFunc
Edited by ozmike

Share this post


Link to post
Share on other sites

I think that the user after 4 years has solved his problem :D

Hi!


My UDF: NetInfo UDF Play with your network, check your download/upload speed and much more! YTAPI Easy to use YouTube API, now you can easy retrive all needed info from a video. NavInfo Check if a specific browser is installed and retrive other usefull information. YWeather Easy to use Yahoo Weather API, now you can easily retrive details about the weather in a specific region. No-IP UDF Easily update your no-ip hostname(s).

My Script: Wallpaper Changer Change you wallpaper dinamically, you can also download your wallpaper from your website and share it with all!   My Snippet: _ImageSaveToBMPConvert an image to bmp format. _SciteGOTO Open a file in SciTE at specific fileline. _FileToHex Show the hex code of a specified file

Share this post


Link to post
Share on other sites

The OP has been offline for 4 years! So you won't reach him.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

I realized it was a old post but I was searching had a similar problem - a came up with this solution -might help the next person..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0