Jump to content

MouseOnEvent UDF!


MrCreatoR
 Share

Recommended Posts

The following code doesn't seam to work for me, i double-click the side buttons and nothing happens.

Yes, i still didn't implemented this event, the problem is the same as was with $MOUSE_PRIMARYDBLCLK_EVENT event.

As soon as i get mouse with extra buttons i will try to fix these problems.

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Though i dont fully understand mouse hooks but i was wondering is there any way for this UDF to block the key, yet not block it ?

So its set up to detect the key, but allows it to be send without going to any application "So it can detect when the button is being pressed or held".

Link to comment
Share on other sites

Though i dont fully understand mouse hooks but i was wondering is there any way for this UDF to block the key, yet not block it ?

So its set up to detect the key, but allows it to be send without going to any application "So it can detect when the button is being pressed or held".

You can catch the event without blocking, and then check in loop for _IsPressed.

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Aye _IsPressed was my first thought but blocking it means IsPressed doesn't work. (Plus i dont like using IsPressed as its a polling function which can miss presses or requires a high loop count (which can lead to high cpu) in order not to miss a press)

I did find if you block mouse up, but not down. Then IsPressed does work without sending the key but this means the computer non-stop is sending the key "cuz the up is blocked". This causes problems.

Took me hours to write this and i am sure compared to a pro works it is not very good but i thought i would share :). Its my own Brand of mouse hook using this UDF. It blocks the side-buttons from being sent, while it can detect which one is pressed. double pressed or held. It can also detect if the scroll-whell has been pressed left or right.

#include 'MouseOnEvent.au3'

local $MousePress
local $MouseLoop

_MouseSetOnEvent($MOUSE_XBUTTONDOWN_EVENT, "Dummy", "", 1)
_MouseSetOnEvent($MOUSE_XBUTTONUP_EVENT, "Dummy", "", 1)

$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr(DllCallbackRegister("MouseHook", "int", "int;ptr;ptr")), "hwnd", $hM_Module[0], "dword", 0)

While 1
    sleep(250)
WEnd

Func MouseHook($nCode, $wParam, $lParam)
$MouseHook = DllStructGetData(DllStructCreate("struct;long X;long Y;endstruct;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam), 3)
Select
   Case $MouseHook = 131072
      $MouseLoop += 1
         Select
            Case $MouseLoop = 1
               AdlibRegister("MouseForwardButton", 125)
            Case $MouseLoop > 1
               AdlibUnRegister("MouseForwardButton")
               If $MouseLoop = 2 Then
                  If $MousePress = 0 then
                     $MousePress = 1                  
                     AdlibRegister("MouseForwardDoubleClick", 200)
                  Else
                     $MousePress = 0                  
                     AdlibUnRegister("MouseForwardDoubleClick")
                     ConsoleWrite("Forward Double Click" & @CRLF)
                  EndIf
               EndIf
               $MouseLoop = 0
            EndSelect
      Return 1
   Case $MouseHook = 65536
      $MouseLoop += 1
         Select
            Case $MouseLoop = 1
               AdlibRegister("MouseBackButton", 125)
            Case $MouseLoop > 1
               AdlibUnRegister("MouseBackButton")
               If $MouseLoop = 2 then
                  If $MousePress = 0 then
                     $MousePress = 1                  
                     AdlibRegister("MouseBackDoubleClick", 200)
                  Else
                     $MousePress = 0                  
                     AdlibUnRegister("MouseBackDoubleClick")
                     ConsoleWrite("Back Double Click" & @CRLF)
                  EndIf
               EndIf               
               $MouseLoop = 0
            EndSelect
      Return 1
   Case Not($wParam = $WM_MOUSEWHEEL)
      If $MouseHook = 4287102976 then ConsoleWrite("Left Wheel Click" & @CRLF)
      If $MouseHook = 7864320 then ConsoleWrite("Right Wheel Click" & @CRLF)
EndSelect
EndFunc

Func MouseForwardButton()
If $MouseLoop = 1 then $MouseLoop = 3
ConsoleWrite("Foward Button Holding" & @CRLF)
EndFunc

Func MouseBackButton()
If $MouseLoop = 1 then $MouseLoop = 3
ConsoleWrite("Back Button Holding" & @CRLF)
EndFunc

Func MouseForwardDoubleClick()
   If $MousePress = 1 then ConsoleWrite("Forward Single Click" & @CRLF)
   AdlibUnRegister("MouseForwardDoubleClick")
   $MousePress = 0
EndFunc

Func MouseBackDoubleClick()
  If $MousePress = 1 then  ConsoleWrite("Back Single Click" & @CRLF)
   AdlibUnRegister("MouseForwardDoubleClick")
   $MousePress = 0
EndFunc

**Edit. If anyone reads and uses this code, please note though almost all of it is my own work and my ideas. The "Blocking" comes from this UDF and the Mousehook comes from So please give credit to the proper people :) For more details, anything with a ;;// is almost directly copied / pasted / gutted for reduced coding lines

Edited by IanN1990
Link to comment
Share on other sites

_IsPressed was my first thought but blocking it means IsPressed doesn't work.

You don't have to block, use firth parameter:

_MouseSetOnEvent($iEvent, $sFuncName, 0, 0)

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Ah, yea this would not block the key and allow IsPressed to detect it but this also means the key gets sent to the system. If i am watching KMPlayer or Youtube for example and i clicked up / down on my mouse. For kmp this would re-wind or fast-forward. For firefox it goes to the prev page or next page. Thats why i needed a way to block the key from being sent to any applications while still detecting if its being held or not.

but. i only wrote this because i wanted something here and now even if its worse quality :) I am sure when your able to get a new mouse u will most likely produce something alot better :)

Edited by IanN1990
Link to comment
Share on other sites

Hi MrCreator, very very nice UDF ;)

A fast question, how to make only one hotkey for start/stop? I have make two but i'd like to have only one:

#include <MouseOnEvent.au3> ;External UDF

HotKeySet("{ESC}", "_Exit")
HotKeySet("{F2}", "_Start")
HotKeySet("{F3}", "_Stop")

While 1
Sleep(100)
WEnd

Func _Start()
  _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_Dummy1", 0, 1)
  _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_Dummy2", 0, 1)
  _MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT, "_Dummy3", 0, 1)
EndFunc   ;==>_Start_Stop

Func _Dummy1()
; Test
EndFunc

Func _Dummy2()
;Test
EndFunc

Func _Dummy3()
; Test
EndFunc

Func _Stop()
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT)
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT)
_MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT)
EndFunc   ;==>Stop

Func _Exit()
Exit 0
EndFunc   ;==>_Exit

Thanks ;)

Link to comment
Share on other sites

A fast question, how to make only one hotkey for start/stop? I have make two but i'd like to have only one:

It's not related directly to the UDF:

#include <MouseOnEvent.au3> ;External UDF

Global $bPaused = False

HotKeySet("{ESC}", "_Exit")
HotKeySet("{F2}", "_StartStop")

While 1
    Sleep(100)
WEnd

Func _StartStop()
    If $bPaused Then
        _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "_Dummy", 0, 1)
        _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "_Dummy", 0, 1)
        _MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT, "_Dummy", 0, 1)
    Else
        _MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT)
        _MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT)
        _MouseSetOnEvent($MOUSE_WHEELDOWN_EVENT)
    EndIf
    
    $bPaused = Not $bPaused
EndFunc

Func _Dummy()
    ; Test
EndFunc

Func _Exit()
    Exit 0
EndFunc

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Strange, very strange.

I just tested on virtual machine with Win 7 Pro x64, all examples working fine, no crash.

I modified it and now work fine

$h__MSOE_PrmDblClk_Timer = _Timer_SetTimer(-1, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')

Link to comment
Share on other sites

I modified it and now work fine

$h__MSOE_PrmDblClk_Timer = _Timer_SetTimer(-1, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')

Please try this method, i think it should be better:

#Region Global Constants and Variables

...

Global $h__MSOE_AutHwnd                = WinGetHandle('[CLASS:AutoIt v3;TITLE:' & AutoItWinGetTitle() & ']')

...

#EndRegion Global Constants and Variables

...

_Timer_SetTimer($h__MSOE_AutHwnd, ...)

...

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

  • 3 weeks later...

I'd say call it with the last parameter set to 0 (makes your function non-blocking):

_MouseSetOnEvent($MOUSE_MOVE_EVENT, "MouseMove_Event","","",0,0)

Also, don't try to do too much in the function - you don't want to slow down mouse movements.

Oh, also, I don't know why MrCreator doesn't get the Mouse coordinates at the time the callback is made - that part makes no sense to me, because the mouse coordinates are passed and often necessary. Using MouseGetPos() is just overkill and may or may not give the right coords.

You can add this to the __MouseSetOnEvent_MainHandler() function in MrCreator's UDF to get the mouse position data ($aMOUSE_CUR_POS is a global array I set):

Local $stPos=DllStructCreate($tagPOINT,$lParam)
    $aMOUSE_CUR_POS[0]=DllStructGetData($stPos,1)
    $aMOUSE_CUR_POS[1]=DllStructGetData($stPos,2)

What else? I can't think of anything at the moment

So, this is a great UDF, thanks MrCreatoR.

I'm making a script that is constantly getting the position of the mouse. I was using MouseGetPos() for this, and it's working fine, but I tried what Ascend4nt suggested, and it works, but the positions keep counting past the (1366x768) screen resolution, giving unreliable numbers.

Obviously I've tested MouseGetPos() and it works fine, and I could go back to using that, but I'd like to keep it as light as possible... So I guess I'm asking is Ascend4nt's solution better than MouseGetPos(), and if so, is there a way to make it more reliable? As in, not counting up (or down into negatives) for the mouse position when it's obviously confined by the resolution.

Also, I'm just trying to pass some identifiers to a function called by $MOUSE_MOVE_EVENT, but I can't seem to figure that out... Here's my code:

#include-once
#include "MouseOnEvent.au3"

HotKeySet('{END}', '_End') ;End button to exit script

Local $mX = 0, $mY = 0, $lc = 0, $rc = 0 ;idk, just defining stuff

_MouseSetOnEvent($MOUSE_MOVE_EVENT, '_moveTracker') ;counting the pixels that the cursor has moved function
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, '_clickTracker', '', '', 1) ;count mouse clicks on left mouse button, with identifier 1
;I don't know if I'm passing the parameter right...
;I've tried also doing it in "" and using a variable, meh
_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, '_clickTracker', '', '', 2) ;count mouse click on right mouse button, with identifier 2
$mP = MouseGetPos() ;get initial mouse position

While 1 ;main loop
Sleep(20)
;~ ToolTip($a__MSOE_Pos[0], 0, 0) ;current value from MouseOnEvent.au3, as an added variable: "Global $a__MSOE_Pos[2]"
ToolTip('mX = ' & $mX & ' ... mY = ' & $mY & @CRLF & 'lc = ' & $lc & ' ... rc = ' & $rc, 0, 0) ;current x and y values that the cursor has traveled total
;and the total amount of left and right clicks
WEnd


Func _moveTracker() ;my function for getting the distance the cursor has traveled
;$mX is distance on X axis, $mY is Y axis, $mP is position of cursor
$mX += Abs(($mP[0] - $a__MSOE_Pos[0])) ;absolute value of old position - new, yields what I want
$mY += Abs(($mP[1] - $a__MSOE_Pos[1])) ; "" "" ""
$mP[0] = $a__MSOE_Pos[0] ;set the new cursor position
$mP[1] = $a__MSOE_Pos[1] ; "" "" ""
EndFunc ;==>_moveTracker

Func _clickTracker() ;record the amount of mouse clicks the user makes
;This is where I'm having a problem... I haven't used AutoIt in a while...
;so I put 1 and 2 in the primary and secondary events in the right parameters, I just don't know if I did it right
;or if I'm calling them correctly

;I want it to be, if it's a left click, send a 1 or something to this function, and then add one to $lc
;if it's a 2, add 1 to $rc...
If 1 Then $lc += 1
If 2 Then $rc += 1
EndFunc ;==>_clickTracker

Func _End() ;just used to close the script, cause I'm to lazy to click the tray icon
Exit
EndFunc ;==>_End

Right now, after adding the Global variable and Ascend4nts code to the UDF, when mousing over the edges of the screen, the numbers will keep going up, when they shouldn't, since the cursor is confined to the edge of the screen. There wasn't an issue with MouseGetPos()

And, to avoid having two functions (one for counting left clicks, and one for right clicks), I'm trying to have it identify which is which, and do it in one function... Although I'm sure that just having two functions is better/faster. Still, I would like to know how to correctly pass and parse parameters.

I'm not sure if this is all making sense, so let me know if I can clarify anything.

Thanks

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

  • 2 weeks later...

Great UDF! However, it doesn't catch primary single clicks when the user presses buttons. It seems clicking buttons is interpreted by the OS as some kind of "button event" ... of higher precedence and no $MOUSE_PRIMARYDOWN_EVENT is generated. Is there any workaround to catch such clicks on buttons? Perhaps the callback registered by MouseOnEvent is not the first in the WIN API handler chain. Thanks!

Link to comment
Share on other sites

HI

Secondtly is there any way for $MOUSE_XBUTTONDOWN_EVENT to tell the differenec between which side mouse button has been pressed?

05 Windows 2000/XP: X1 mouse button

06 Windows 2000/XP: X2 mouse button

for those searching for x buttons look no further! I've got X buttons working

X buttons added!

Unofficial version 1.11

'x'tra buttons 4 & 5 on side of mouse. See my this post further down

If you still have problems with this UDF then try mouse trap UDF

Edited by ozmike
Link to comment
Share on other sites

  • 5 weeks later...

hi ozmike

in beta 3.3.9.4 au3check returns "error: $stMSLLHOOKSTRUCT previously declared as a 'Const'"

the 2 lines of code referenced are 296 and 354...

Local Const $stMSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

i thought "local const" was allowed in the beta, but apparently not, so what's the best way of solving this?

of course i can just remove "Const" and it runs fine, but i don't know that's the right way to solve the problem

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
Share on other sites

  • 4 weeks later...

@MrCreatoR

@ozmike

I played with this just a bit (ozmike's version) and modified it so au3check doesn't squak with parms

-d -w 3 -w 4 -w 5
, however i still have problems with it.

I'm working on an alternative to Send and _SendEx to overcome the "stuck" modifier key problem (and yes, it can happen with _SendEx as well), but wheni add the mouse hooking, things go downhill. For instance, this bit of code seems to work fine without the hook in place:

$aVKeys = StringSplit($sVKeys, ",")

    For $i = 1 To UBound($aVKeys) -1
        DllCall($hUser32dll, "int", "keybd_event", "int", $aVKeys[$i], "int", 0, "long", 0, "long", 0)
    Next

But when i tested with

_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_Func")
, the for/next loop would never run. This seemed very strange, but the script would run the StringSplit and it would work (the array was created), but it would not enter the For loop.

Anyway, maybe one of you guys can take a look to see that my mods are ok and, if so, please update the version since i don't feel qualified :)

#include-once
#region Header

#cs

    Title:        MouseOnEvent UDF
    Filename:      MouseOnEvent.au3
    Description:    Set an events handler (a hook) for Mouse device.
    Author:      G.Sandler a.k.a (Mr)CreatoR (CreatoR's Lab - http://creator-lab.ucoz.ru, http://autoit-script.ru)
    Version:        1.9
    Requirements:   AutoIt v3.3.6.1 +, Developed/Tested on Windows XP (rus) Service Pack 2/3, Win 7, with standard 3-buttons mouse device
    Uses:          WindowsConstants.au3, WinAPI.au3, Timers.au3
    Forum Link:  http://www.autoitscript.com/forum/index.php?showtopic=64738
    Notes:
    1) The original events-messages (such as $WM_MOUSEMOVE) can be used as well.
    2) Blocking $sFuncName function with commands such as "Msgbox()" can lead to unexpected behavior,
    the return to the system should be as fast as possible!
    3) When $MOUSE_PRIMARYDOWN_EVENT and $MOUSE_SECONDARYDOWN_EVENT are set,
    the $MOUSE_PRIMARYDBLCLK_EVENT and $MOUSE_SECONDARYDBLCLK_EVENT events are also set by force,
    to unset these events use _MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT or $MOUSE_SECONDARYDBLCLK_EVENT).
    4) When using obfuscator, make sure to add event functions to ignore list (#Obfuscator_Ignore_Funcs).
    5) When Overiding (blocking) UP events make sure to also block DOWN event otherwise others windows lock up.

    ChangLog:
    v1.10  beta
    * Added handling for X buttons UP , DOWN , DOUBLE CLICK
    * Note, a 1 or 2 is appended to the $funcName that is passed.
    * eg. If X button 2 pressed and funcName = "hello" the function called will be "hello2".
    * Affect events :
    * $MOUSE_XBUTTONDOWN_EVENT
    * $MOUSE_XBUTTONUP_EVENT
    * $MOUSE_XBUTTONDBLCLK_EVENT
    * Note, clicking both X buttons dosen't set a double click event
    * Examples Updated.

    v1.9 [22.07.2012]
    * Script breaking version!
    * Dropped AutoIt 3.3.0.0 support.
    * Instead of $sParam1 and $sParam2, now $vParam used as last parameter.
    * Event function ($sFuncName) now called with $iEvent as first parameter, and $vParam as second (both optional).
    * Now $iBlockDefProc is set to -1 by default (event function can define whether to block event process or not, simply by returning 1 or 0).
    * Fixed not working $MOUSE_PRIMARYDBLCLK_EVENT and $MOUSE_SECONDARYDBLCLK_EVENT,
    now handled manually because windows does not always receive these events (depending on CS_DBLCLKS style).
    (not tested properly, so these events will have "experimental" label for now).
    * Fixed error related to "Subscript used with non-Array variable", caused when window with handle of $hTargetWnd parameter is not found (window closed).
    * Examples updated.

    v1.8 [02.06.2010]
    * Fixed an issue with wrong handling when $MOUSE_XBUTTONUP/DOWN_EVENT and few other events are set.
    * Fixed an issue when user attempts to set other function for the event that already have been set.
    Now the function and other parameters are replaced for the current event.
    * UDF file renamed (removed "Set" in the middle and "_UDF" at the end of the name).
    * Cosmetic changes in the UDF code.
    * Docs updated.

    v1.7 [14.10.2009]
    * Stability fixes. Thanks again to wraithdu.

    v1.6 [13.10.2009]
    * Fixed an issue with releasing the resources of mouse hook. Thanks to wraithdu.

    v1.5 [09.10.2009]
    + Added wheel button up/down *scrolling* event recognition.
    Thanks to JRowe (http://www.autoitscript.com/forum/index.php?showtopic=103362).
    * Fixed an issue with returning value from __MouseSetOnEvent_MainHandler - should call _WinAPI_CallNextHookEx before return.
    * Constants starting with MOUSE_EXTRABUTTON* renamed to MOUSE_XBUTTON*, as it should be in the first place.
    * Few examples updated.

    v1.4 [30.09.2009]
    + Added UDF header to the function.
    + Now the original events-messages (such as $WM_MOUSEMOVE) can be used as well.
    + Added missing events (althought i am not sure if they are still supported)
    $MOUSE_PRIMARYDBLCLK_EVENT - Primary mouse button double click.
    $MOUSE_SECONDARYDBLCLK_EVENT - Secondary mouse button double click.
    $MOUSE_WHEELDBLCLK_EVENT - Wheel mouse button double click.
    $MOUSE_EXTRABUTTONDBLCLK_EVENT - Side mouse button double click.

    * Changed global vars and internal functions names to be more unique.
    * Fixed variables declaration and misspelling.

    v1.3 [27.10.2008]
    * Added optional parameter $iBlockDefProc - Define wether the Mouse events handler will block the default processing or not (Default is 1, block).
    If this is -1, then user can Return from the event function to set processing operation (see the attached example «AutoDrag window.au3»).

    v1.2 [05.04.2008]
    * Added: [Optional] parameter $hTargetWnd, if set, the OnEvent function will be called only on $hTargetWnd window, otherwise will be standard Event processing.
    Note: Can be a little(?) buggy when you mix different events.

    v1.1 [22.03.2008]
    * Fixed: Incorrect ReDim when remove event from the array, it was causing UDF to crash script with error.
    * Spell/Grammar corrections
    * Added: An example of _BlockMouseClicksInput().

    v1.0 [21.02.2008]
    * First public release.
#CE

;#include <WindowsConstants.au3>
Global Const $GA_ROOT = 2

#include <WinAPI.au3>
#include <Timers.au3>

OnAutoItExitRegister('__MouseSetOnEvent_OnExitFunc')

#endregion Header

#region Global Constants and Variables

Global $a__MSOE_Events[1][1]
Global $h__MSOE_MouseProc = -1
Global $h__MSOE_MouseHook = -1
Global $i__MSOE_EventReturn = 1
Global $h__MSOE_Hook_Timer = 0
Global $h__MSOE_PrmDblClk_Timer = 0
Global $h__MSOE_ScnDblClk_Timer = 0
Global $h__MSOE_XDblClk_Timer = 0 ; Xbutton
;Global $h__MSOE_WDblClk_Timer        = 0 ; Wheel Button
Global $i__MSOE_PrmDblClk_Timer = 0
Global $i__MSOE_ScnDblClk_Timer = 0
Global $i__MSOE_XDblClk_Timer = 0 ; Xbutton
Global $i__MSOE_XDblClk_Button = 0 ; Xbutton  Which Button Double Clicked

;Global $i__MSOE_WDblClk_Timer        = 0 ; Wheel Button
Global $a__MSOE_PrmDblClk_LastMPos[2]
Global $a__MSOE_ScnDblClk_LastMPos[2]
Global $a__MSOE_XDblClk_LastMPos[2] ; Xbutton
;Global $a__MSOE_WDblClk_LastMPos[2] ; Wheel Button
Global $a__MSOE_DblClk_Data = __MouseSetOnEvent_GetDoubleClickData()

#endregion Global Constants and Variables

#region Public Constants

Global Const $MOUSE_MOVE_EVENT = 0x200 ;512 (WM_MOUSEMOVE)         ; ==> Mouse moving.
Global Const $MOUSE_PRIMARYDOWN_EVENT = 0x201 ;513 (WM_LBUTTONDOWN)         ; ==> Primary mouse button down.
Global Const $MOUSE_PRIMARYUP_EVENT = 0x202 ;514 (WM_LBUTTONUP)         ; ==> Primary mouse button up.
Global Const $MOUSE_PRIMARYDBLCLK_EVENT = 0x203 ;515 (WM_LBUTTONDBLCLK)     ; ==> Primary mouse button double click.
Global Const $MOUSE_SECONDARYDOWN_EVENT = 0x204 ;516 (WM_RBUTTONDOWN)         ; ==> Secondary mouse button down.
Global Const $MOUSE_SECONDARYUP_EVENT = 0x205 ;517 (WM_RBUTTONUP)         ; ==> Secondary mouse button up.
Global Const $MOUSE_SECONDARYDBLCLK_EVENT = 0x206 ;518 (WM_RBUTTONDBLCLK)     ; ==> Secondary mouse button double click.
Global Const $MOUSE_WHEELDOWN_EVENT = 0x207 ;519 (WM_MBUTTONDOWN)         ; ==> Wheel mouse button pressed down.
Global Const $MOUSE_WHEELUP_EVENT = 0x208 ;520 (WM_MBUTTONUP)         ; ==> Wheel mouse button up.
Global Const $MOUSE_WHEELDBLCLK_EVENT = 0x209 ;521 (WM_MBUTTONDBLCLK)     ; ==> Wheel mouse button double click.
Global Const $MOUSE_WHEELSCROLL_EVENT = 0x20A ;522 (WM_MOUSEWHEEL)         ; ==> Wheel mouse scroll.
Global Const $MOUSE_WHEELSCROLLDOWN_EVENT = 0x20A + 8 ;530 (WM_MOUSEWHEEL + 8)     ; ==> Wheel mouse scroll Down.
Global Const $MOUSE_WHEELSCROLLUP_EVENT = 0x20A + 16 ;538 (WM_MOUSEWHEEL + 16)     ; ==> Wheel mouse scroll Up.
Global Const $MOUSE_XBUTTONDOWN_EVENT = 0x20B ;523 (WM_XBUTTONDOWN)         ; ==> Side mouse button down (usually navigating next/back buttons).
Global Const $MOUSE_XBUTTONUP_EVENT = 0x20C ;524 (WM_XBUTTONUP)         ; ==> Side mouse button up.
Global Const $MOUSE_XBUTTONDBLCLK_EVENT = 0x20D ;525 (WM_XBUTTONDBLCLK)     ; ==> Side mouse button double click.

#endregion Public Constants

#region Public Functions

; #FUNCTION# ====================================================================================================
; Name...........:    _MouseSetOnEvent
; Description....:    Set an events handler (a hook) for Mouse device.
; Syntax.........:    _MouseSetOnEvent($iEvent, $sFuncName = "", $hTargetWnd = 0, $iBlockDefProc = -1, $vParam = "")
; Parameters.....:    $iEvent         - The event to set, here is the list of supported events:
;                                        $MOUSE_MOVE_EVENT - Mouse moving.
;                                        $MOUSE_PRIMARYDOWN_EVENT - Primary mouse button down.
;                                        $MOUSE_PRIMARYUP_EVENT - Primary mouse button up.
;                                        $MOUSE_PRIMARYDBLCLK_EVENT - Primary mouse button double click.
;                                        $MOUSE_SECONDARYDOWN_EVENT - Secondary mouse button down.
;                                        $MOUSE_SECONDARYUP_EVENT - Secondary mouse button up.
;                                        $MOUSE_SECONDARYDBLCLK_EVENT - Secondary mouse button double click.
;                                        $MOUSE_WHEELDOWN_EVENT - Wheel mouse button pressed down.
;                                        $MOUSE_WHEELUP_EVENT - Wheel mouse button up.
;                                        $MOUSE_WHEELDBLCLK_EVENT - Wheel mouse button double click.
;                                        $MOUSE_WHEELSCROLL_EVENT - Wheel mouse scroll.
;                                        $MOUSE_WHEELSCROLLDOWN_EVENT - Wheel mouse scroll *Down*.
;                                        $MOUSE_WHEELSCROLLUP_EVENT - Wheel mouse scroll *Up*.
;                                        $MOUSE_XBUTTONDOWN_EVENT - Side mouse button down (usualy navigating next/back buttons).
;                                        $MOUSE_XBUTTONUP_EVENT - Side mouse button up.
;                                        $MOUSE_XBUTTONDBLCLK_EVENT - Side mouse button double click.
;
;                    $sFuncName         - [Optional] Function name to call when the event is triggered.
;                                        If this parameter is empty string ("") or omited, the function will *unset* the $iEvent.
;                    $hTargetWnd     - [Optional] Window handle to set the event for, e.g the event is set only for this window.
;                    $iBlockDefProc     - [Optional] Defines if the event should be blocked (actualy block the mouse action).
;                                        If this parameter = -1 (default), then event function can define whether to block event process or not, simply by returning 1 or 0.
;                    $vParam         - [Optional] Parameter to pass to the event function ($sFuncName).
;
; Return values..:    Success         - If the event is set in the first time, or when the event is unset properly, the return is 1,
;                                        if it's set on existing event, the return is 2.
;                    Failure         - Returns 0 on UnSet event mode when there is no set events yet.
; Author.........:    G.Sandler ((Mr)CreatoR, CreatoR's Lab - http://creator-lab.ucoz.ru, http://autoit-script.ru)
; Modified.......:
; Remarks........:    1) The original events-messages (such as $WM_MOUSEMOVE) can be used as well.
;                    2) Blocking of $sFuncName function by window messages with commands
;                    such as "Msgbox()" can lead to unexpected behavior, the return to the system should be as fast as possible!
; Related........:
; Link...........:    http://www.autoitscript.com/forum/index.php?showtopic=64738
; Example........:    Yes.
; ===============================================================================================================
Func _MouseSetOnEvent($iEvent, $sFuncName = "", $hTargetWnd = 0, $iBlockDefProc = -1, $vParam = "")

    If $sFuncName = "" Then ;Unset Event
        If $a__MSOE_Events[0][0] < 1 Then
            Return 0
        EndIf

        Local $aTmp_Mouse_Events[1][1] = [[0]]

        For $i = 1 To $a__MSOE_Events[0][0]
            If $a__MSOE_Events[$i][0] <> $iEvent Then
                $aTmp_Mouse_Events[0][0] += 1
                ReDim $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0] + 1][5]

                $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][0] = $a__MSOE_Events[$i][0]
                $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][1] = $a__MSOE_Events[$i][1]
                $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][2] = $a__MSOE_Events[$i][2]
                $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][3] = $a__MSOE_Events[$i][3]
                $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][4] = $a__MSOE_Events[$i][4]
            EndIf
        Next

        $a__MSOE_Events = $aTmp_Mouse_Events

        If $a__MSOE_Events[0][0] < 1 Then
            If $i__MSOE_EventReturn = 1 Then
                __MouseSetOnEvent_OnExitFunc()
            ElseIf $i__MSOE_EventReturn = 0 Then
                $h__MSOE_Hook_Timer = _Timer_SetTimer(0, 10, "__MouseSetOnEvent_WaitHookReturn")
            EndIf
        EndIf

        Return 1
    EndIf

    ;First event
    If $a__MSOE_Events[0][0] < 1 Then
        $h__MSOE_MouseProc = DllCallbackRegister("__MouseSetOnEvent_MainHandler", "int", "int;ptr;ptr")
        $h__MSOE_MouseHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($h__MSOE_MouseProc), _WinAPI_GetModuleHandle(0), 0)
    EndIf

    ;Search thru events, and if the event already set, we just (re)set the new function and other parameters
    For $i = 1 To $a__MSOE_Events[0][0]
        If $a__MSOE_Events[$i][0] = $iEvent Then
            $a__MSOE_Events[$i][0] = $iEvent
            $a__MSOE_Events[$i][1] = $sFuncName
            $a__MSOE_Events[$i][2] = $hTargetWnd
            $a__MSOE_Events[$i][3] = $iBlockDefProc
            $a__MSOE_Events[$i][4] = $vParam

            Return 2
        EndIf
    Next

    $a__MSOE_Events[0][0] += 1
    ReDim $a__MSOE_Events[$a__MSOE_Events[0][0] + 1][5]

    $a__MSOE_Events[$a__MSOE_Events[0][0]][0] = $iEvent
    $a__MSOE_Events[$a__MSOE_Events[0][0]][1] = $sFuncName
    $a__MSOE_Events[$a__MSOE_Events[0][0]][2] = $hTargetWnd
    $a__MSOE_Events[$a__MSOE_Events[0][0]][3] = $iBlockDefProc
    $a__MSOE_Events[$a__MSOE_Events[0][0]][4] = $vParam

    ;Add primary/secondary double click event, if needed can be disabled later
    If $iEvent = $MOUSE_PRIMARYDOWN_EVENT Then
        _MouseSetOnEvent($MOUSE_PRIMARYDBLCLK_EVENT, $sFuncName, $hTargetWnd, $iBlockDefProc, $vParam)
    EndIf

    If $iEvent = $MOUSE_SECONDARYDOWN_EVENT Then
        _MouseSetOnEvent($MOUSE_SECONDARYDBLCLK_EVENT, $sFuncName, $hTargetWnd, $iBlockDefProc, $vParam)
    EndIf

    If $iEvent = $MOUSE_XBUTTONDOWN_EVENT Then
        _MouseSetOnEvent($MOUSE_XBUTTONDBLCLK_EVENT, $sFuncName, $hTargetWnd, $iBlockDefProc, $vParam)
    EndIf

    Return 1

EndFunc   ;==>_MouseSetOnEvent

#endregion Public Functions

#region Internal Functions

Func __MouseSetOnEvent_MainHandler($nCode, $wParam, $lParam)

    Local $iEvent, $iRet, $iBlockDefProc_Ret, $iWScrollDirection, $iXButtonNumber, $stMSLLHOOKSTRUCT, $tXButton_Struct, $aCurrentMPos, $iDC_Width, $iDC_Height, $tWheel_Struct, $sFuncName

    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($h__MSOE_MouseHook, $nCode, $wParam, $lParam) ;Continue processing

    $iEvent = _WinAPI_LoWord($wParam)
    $iWScrollDirection = 0

    $iXButtonNumber = 0 ; Xbutton

    If $a__MSOE_Events[0][0] < 1 Then Return 0

    Switch $iEvent

        Case $MOUSE_XBUTTONDOWN_EVENT, $MOUSE_XBUTTONUP_EVENT

            $stMSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"
            $tXButton_Struct = DllStructCreate($stMSLLHOOKSTRUCT, $lParam)

            $iXButtonNumber = _WinAPI_HiWord(DllStructGetData($tXButton_Struct, 3))

            If $iEvent = $MOUSE_XBUTTONDOWN_EVENT Then ; Xbutton double click

                If $i__MSOE_XDblClk_Timer = 0 Then
                    $i__MSOE_XDblClk_Timer = TimerInit()
                    $a__MSOE_XDblClk_LastMPos = MouseGetPos()
                    $i__MSOE_XDblClk_Button = $iXButtonNumber
                    $h__MSOE_XDblClk_Timer = _Timer_SetTimer(0, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')
                ElseIf $i__MSOE_XDblClk_Timer > 0 And $i__MSOE_XDblClk_Button = $iXButtonNumber Then ; check which button
                    If TimerDiff($i__MSOE_XDblClk_Timer) <= $a__MSOE_DblClk_Data[0] Then
                        $aCurrentMPos = MouseGetPos()

                        $iDC_Width = $aCurrentMPos[0] - $a__MSOE_XDblClk_LastMPos[0]
                        If $a__MSOE_XDblClk_LastMPos[0] > $aCurrentMPos[0] Then $iDC_Width = $a__MSOE_XDblClk_LastMPos[0] - $aCurrentMPos[0]

                        $iDC_Height = $aCurrentMPos[1] - $a__MSOE_XDblClk_LastMPos[1]
                        If $a__MSOE_XDblClk_LastMPos[1] > $aCurrentMPos[1] Then $iDC_Height = $a__MSOE_XDblClk_LastMPos[1] - $aCurrentMPos[1]

                        If $iDC_Width <= $a__MSOE_DblClk_Data[1] And $iDC_Height <= $a__MSOE_DblClk_Data[2] Then
                            $iEvent = $MOUSE_XBUTTONDBLCLK_EVENT
                        EndIf
                    EndIf
                    $i__MSOE_XDblClk_Button = 0 ;reset
                    $i__MSOE_XDblClk_Timer = 0
                EndIf
            EndIf

        Case $MOUSE_WHEELDOWN_EVENT

            ;ConsoleWrite("Wheel dbl click" & @CRLF );
            ;If $i__MSOE_WDblClk_Timer = 0 Then
            ;    $i__MSOE_WDblClk_Timer = TimerInit()
            ;    $a__MSOE_WDblClk_LastMPos = MouseGetPos()
            ;    $h__MSOE_WDblClk_Timer = _Timer_SetTimer(0, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')
            ;ElseIf $i__MSOE_WDblClk_Timer > 0 Then
            ;    If TimerDiff($i__MSOE_WDblClk_Timer) <= $a__MSOE_DblClk_Data[0] Then
            ;        Local $aCurrentMPos = MouseGetPos()
            ;
            ;        Local $iDC_Width = $aCurrentMPos[0] - $a__MSOE_WDblClk_LastMPos[0]
            ;        If $a__MSOE_WDblClk_LastMPos[0] > $aCurrentMPos[0] Then $iDC_Width = $a__MSOE_WDblClk_LastMPos[0] - $aCurrentMPos[0]

            ;        Local $iDC_Height = $aCurrentMPos[1] - $a__MSOE_WDblClk_LastMPos[1]
            ;        If $a__MSOE_WDblClk_LastMPos[1] > $aCurrentMPos[1] Then $iDC_Height = $a__MSOE_WDblClk_LastMPos[1] - $aCurrentMPos[1]

            ;        If $iDC_Width <= $a__MSOE_WClk_Data[1] And $iDC_Height <= $a__MSOE_DblClk_Data[2] Then
            ;            $iEvent = $MOUSE_WHEELDBLCLK_EVENT
            ;        EndIf
            ;    EndIf

            ;    $i__MSOE_WDblClk_Timer = 0
            ;EndIf

        Case $MOUSE_WHEELSCROLL_EVENT

            $stMSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"
            $tWheel_Struct = DllStructCreate($stMSLLHOOKSTRUCT, $lParam)

            $iWScrollDirection = _WinAPI_HiWord(DllStructGetData($tWheel_Struct, 3))
        Case $MOUSE_PRIMARYDOWN_EVENT

            If $i__MSOE_PrmDblClk_Timer = 0 Then
                $i__MSOE_PrmDblClk_Timer = TimerInit()
                $a__MSOE_PrmDblClk_LastMPos = MouseGetPos()
                $h__MSOE_PrmDblClk_Timer = _Timer_SetTimer(0, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')
            ElseIf $i__MSOE_PrmDblClk_Timer > 0 Then
                If TimerDiff($i__MSOE_PrmDblClk_Timer) <= $a__MSOE_DblClk_Data[0] Then
                    $aCurrentMPos = MouseGetPos()

                    $iDC_Width = $aCurrentMPos[0] - $a__MSOE_PrmDblClk_LastMPos[0]
                    If $a__MSOE_PrmDblClk_LastMPos[0] > $aCurrentMPos[0] Then $iDC_Width = $a__MSOE_PrmDblClk_LastMPos[0] - $aCurrentMPos[0]

                    $iDC_Height = $aCurrentMPos[1] - $a__MSOE_PrmDblClk_LastMPos[1]
                    If $a__MSOE_PrmDblClk_LastMPos[1] > $aCurrentMPos[1] Then $iDC_Height = $a__MSOE_PrmDblClk_LastMPos[1] - $aCurrentMPos[1]

                    If $iDC_Width <= $a__MSOE_DblClk_Data[1] And $iDC_Height <= $a__MSOE_DblClk_Data[2] Then
                        $iEvent = $MOUSE_PRIMARYDBLCLK_EVENT
                    EndIf
                EndIf

                $i__MSOE_PrmDblClk_Timer = 0
            EndIf

        Case $MOUSE_SECONDARYDOWN_EVENT

            If $i__MSOE_ScnDblClk_Timer = 0 Then
                $i__MSOE_ScnDblClk_Timer = TimerInit()
                $a__MSOE_ScnDblClk_LastMPos = MouseGetPos()
                $h__MSOE_ScnDblClk_Timer = _Timer_SetTimer(0, $a__MSOE_DblClk_Data[0] + 50, '__MouseSetOnEvent_DoubleClickExpire')
            ElseIf $i__MSOE_ScnDblClk_Timer > 0 Then
                If TimerDiff($i__MSOE_ScnDblClk_Timer) <= $a__MSOE_DblClk_Data[0] Then
                    $aCurrentMPos = MouseGetPos()

                    $iDC_Width = $aCurrentMPos[0] - $a__MSOE_ScnDblClk_LastMPos[0]
                    If $a__MSOE_ScnDblClk_LastMPos[0] > $aCurrentMPos[0] Then $iDC_Width = $a__MSOE_ScnDblClk_LastMPos[0] - $aCurrentMPos[0]

                    $iDC_Height = $aCurrentMPos[1] - $a__MSOE_ScnDblClk_LastMPos[1]
                    If $a__MSOE_ScnDblClk_LastMPos[1] > $aCurrentMPos[1] Then $iDC_Height = $a__MSOE_ScnDblClk_LastMPos[1] - $aCurrentMPos[1]

                    If $iDC_Width <= $a__MSOE_DblClk_Data[1] And $iDC_Height <= $a__MSOE_DblClk_Data[2] Then
                        $iEvent = $MOUSE_SECONDARYDBLCLK_EVENT
                    EndIf
                EndIf

                $i__MSOE_ScnDblClk_Timer = 0
            EndIf

    EndSwitch

    For $i = 1 To $a__MSOE_Events[0][0]
        If $a__MSOE_Events[$i][0] = $iEvent Or $iWScrollDirection <> 0 Then
            ;Handle wheel scroll up/down
            If $iEvent = $MOUSE_WHEELSCROLL_EVENT And ($a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLL_EVENT Or $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLUP_EVENT Or $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLDOWN_EVENT) Then
                If $iWScrollDirection > 0 And $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLUP_EVENT Then
                    $iEvent = $MOUSE_WHEELSCROLLUP_EVENT
                ElseIf $iWScrollDirection < 0 And $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLDOWN_EVENT Then
                    $iEvent = $MOUSE_WHEELSCROLLDOWN_EVENT
                ElseIf $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLUP_EVENT Or $a__MSOE_Events[$i][0] = $MOUSE_WHEELSCROLLDOWN_EVENT Then
                    ContinueLoop
                EndIf
            ElseIf $iWScrollDirection <> 0 Then
                ContinueLoop
            EndIf

            If $a__MSOE_Events[$i][2] <> 0 And Not __MouseSetOnEvent_IsHoveredWnd($a__MSOE_Events[$i][2]) Then
                Return 0 ;Allow default processing
            EndIf

            $i__MSOE_EventReturn = 0


            $iBlockDefProc_Ret = $a__MSOE_Events[$i][3]
            ; Start Xbutton
            $sFuncName = $a__MSOE_Events[$i][1]
            If $iXButtonNumber <> 0 Then
                $sFuncName = $sFuncName & $iXButtonNumber
            EndIf


            $iRet = Call($sFuncName, $iEvent, $a__MSOE_Events[$i][4])

            If @error Then
                $iRet = Call($sFuncName, $iEvent)

                If @error Then
                    $iRet = Call($sFuncName)
                EndIf
            EndIf

            ; End Xbutton

            $i__MSOE_EventReturn = 1

            If $iBlockDefProc_Ret = -1 Then
                $iBlockDefProc_Ret = $iRet
            EndIf

            Return $iBlockDefProc_Ret ;Block default processing (or not :))
        EndIf
    Next

    Return _WinAPI_CallNextHookEx($h__MSOE_MouseHook, $nCode, $wParam, $lParam) ;Continue processing

EndFunc   ;==>__MouseSetOnEvent_MainHandler

Func __MouseSetOnEvent_WaitHookReturn($hWnd, $iMsg, $iIDTimer, $dwTime)

    #forceref $hWnd, $iMsg, $iIDTimer, $dwTime

    If $i__MSOE_EventReturn = 1 Then
        _Timer_KillTimer(0, $h__MSOE_Hook_Timer)
        __MouseSetOnEvent_OnExitFunc()
    EndIf

EndFunc   ;==>__MouseSetOnEvent_WaitHookReturn

Func __MouseSetOnEvent_IsHoveredWnd($hWnd)
;~     Local $iRet = False
;~
;~     Local $aWin_Pos = WinGetPos($hWnd)
;~     Local $aMouse_Pos = MouseGetPos()
;~
;~     If Not IsArray($aWin_Pos) Then
;~         Return SetError(1, 0, False)
;~     EndIf
;~
;~     If $aMouse_Pos[0] >= $aWin_Pos[0] And $aMouse_Pos[0] <= ($aWin_Pos[0] + $aWin_Pos[2]) And _
;~         $aMouse_Pos[1] >= $aWin_Pos[1] And $aMouse_Pos[1] <= ($aWin_Pos[1] + $aWin_Pos[3]) Then
;~         $iRet = True
;~     EndIf
;~
;~     Local $aRet = DllCall("User32.dll", "hwnd", "WindowFromPoint", "long", $aMouse_Pos[0], "long", $aMouse_Pos[1])
;~
;~     If HWnd($aRet[0]) <> $hWnd And Not $iRet Then
;~         $iRet = False
;~     EndIf

    Local $tPoint = _WinAPI_GetMousePos()

    Return _WinAPI_GetAncestor(_WinAPI_WindowFromPoint($tPoint), $GA_ROOT) = $hWnd

EndFunc   ;==>__MouseSetOnEvent_IsHoveredWnd

Func __MouseSetOnEvent_DoubleClickExpire($hWnd, $iMsg, $iIDTimer, $dwTime)

    #forceref $hWnd, $iMsg, $iIDTimer, $dwTime

    If TimerDiff($i__MSOE_PrmDblClk_Timer) > $a__MSOE_DblClk_Data[0] Then
        _Timer_KillTimer(0, $h__MSOE_PrmDblClk_Timer)
        $h__MSOE_PrmDblClk_Timer = 0
        $i__MSOE_PrmDblClk_Timer = 0
    EndIf

    If TimerDiff($i__MSOE_ScnDblClk_Timer) > $a__MSOE_DblClk_Data[0] Then
        _Timer_KillTimer(0, $h__MSOE_ScnDblClk_Timer)
        $h__MSOE_ScnDblClk_Timer = 0
        $i__MSOE_ScnDblClk_Timer = 0
    EndIf

    If TimerDiff($i__MSOE_XDblClk_Timer) > $a__MSOE_DblClk_Data[0] Then
        _Timer_KillTimer(0, $h__MSOE_XDblClk_Timer)
        $h__MSOE_XDblClk_Timer = 0
        $i__MSOE_XDblClk_Timer = 0
    EndIf

    ;If TimerDiff($i__MSOE_WDblClk_Timer) > $a__MSOE_DblClk_Data[0] Then
    ;    _Timer_KillTimer(0, $h__MSOE_WDblClk_Timer)
    ;    $h__MSOE_WDblClk_Timer = 0
    ;    $i__MSOE_WDblClk_Timer = 0
    ;EndIf

EndFunc   ;==>__MouseSetOnEvent_DoubleClickExpire

Func __MouseSetOnEvent_GetDoubleClickData()

    Local $aRet[3] = _
            [ _
            RegRead('HKEY_CURRENT_USER\Control Panel\Mouse', 'DoubleClickSpeed'), _
            RegRead('HKEY_CURRENT_USER\Control Panel\Mouse', 'DoubleClickWidth'), _
            RegRead('HKEY_CURRENT_USER\Control Panel\Mouse', 'DoubleClickHeight') _
            ]

    Local $aGDCT = DllCall('User32.dll', 'uint', 'GetDoubleClickTime')

    If Not @error And $aGDCT[0] > 0 Then
        $aRet[0] = $aGDCT[0]
    EndIf

    Return $aRet

EndFunc   ;==>__MouseSetOnEvent_GetDoubleClickData

Func __MouseSetOnEvent_OnExitFunc()

    If $h__MSOE_MouseHook <> -1 Then
        _WinAPI_UnhookWindowsHookEx($h__MSOE_MouseHook)
        $h__MSOE_MouseHook = -1
    EndIf

    If $h__MSOE_MouseProc <> -1 Then
        DllCallbackFree($h__MSOE_MouseProc)
        $h__MSOE_MouseProc = -1
    EndIf

EndFunc   ;==>__MouseSetOnEvent_OnExitFunc

#endregion Internal Functions

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
Share on other sites

MrCreatorR,

There is a hard crash with AutoIt V3.3.8.1 on Windows 7 x64 when using the AutoDrag Window and Restrict clicks in Clock area examples.

Edit: Actually it appears all the examples create a hard crash.

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 1 month later...

Here's my version with single click detection added. Sometimes a person needs this separate from mousedown/up detection.

For some reason I haven't figured out, wheel click detection isn't working for me (Windows 8).

I"m not sure how to add it as an attachment to this post.

v1.10 [12.01.2013] (drewkeller)

+ Add a new test script/GUI that displays all supported mouse events in real time on the GUI.

+ Add double click detection for wheel button and xbutton (wheel click doesn't work for me... Logitech MX-LASER on Win8, but if I remote desktop from my wife's laptop, it works with her mouse).

+ Add single click detection for primary, secondary, wheel (doesn't work for me) and xbutton. This uses the same time and hit-rectangle as the double click detection, as suggested by http://msdn.microsoft.com/en-us/library/ms171543(v=vs.80).aspx (mainly by adding the event processing when the double click timer expires).

* Refactoring to allow easier addition of double- and single click detection for more buttons.

* Uses lParam to determine the mouse position so it is the exact position reported by the OS (as suggested by Ascend4nt).

! Fix SCROLLUP/DOWN triggering (was always being overridden by SCROLL, so never being reported).

% NOTE: Perhaps the scroll triggers would not have to be mutually exclusive, if a means of queuing them was added. The second UP event is also overridden by the DblClk trigger, so it could also benefit from being queued.... if it's really an issue.

Edit: Ok, I figured out how to do the attachment. Also needed to fix some bugs that I found after I implemented the new test GUI.

MouseOnEvent.zip

Edited by drewkeller
Link to comment
Share on other sites

  • 2 weeks later...

Nice Work DrewKeller - nice code restructure..thanks!

The only thing with Xbuttons is that you need to be able to detect which xbutton is pressed

I've modified the above , to detect which X button is pressed..

* Note, a 1 or 2 is appended to the $funcName that is passed.

* eg. If X button 2 pressed and funcName = "hello" the function called will be "hello2"

Tested on win 7 - both 64 bit and 32 bit compiled exes work

Unofficial Version 1.11 - with X buttons

MouseOnEvent.zip

If you still have problems with this UDF then try mouse trap UDF

Edited by ozmike
Link to comment
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
 Share

×
×
  • Create New...