Jump to content

Detect mouse click in same location...?


Recommended Posts

Howdy,

  I am using attempting to do something that would seem to be rather simple...I want to 'left-click' within a GUI and determine if the location of that click equals the last known mouse position...preferably detecting a 'double-click'.  I am using the following 'schematic' code however am having difficulty.  Basically I call a function upon a 'mouse down' event and a 'mouse up' event.  Recording the positions upon each event should enable me to determine if the click is in the same location or if the user has moved the mouse and clicked elsewhere.  It almost seems that the functions interfere with each other, since a 'left-click' occurs very rapidly...is there a way to force one function to 'wait' until the other function has completed...?  Or perhaps there is an entirely different and better way than I am attempting...?  Thanks in advance for any ideas.  

Global $hDLL = DllOpen("user32.dll")
 Global $_CTRL_SELECT = -1, $_CTRL_GUI, $sControl, $_MOUSE_LOCATE, $_TAB_IN = -1, $_TAB_OUT = -1
 Global $_XMOUSE_SETS[4] = [-1, -1, -1, -1], $_YMOUSE_SETS[4] = [-1, -1, -1, -1]

Main()


Func Main()

    While 1

        ; Sleep because GUIOnEventMode is NOT a blocking function like GUIGetMsg
        Sleep(10)

     if _IsPressed("01", $hDLL) Then  

      ; Wait until key is released.
      if _IsPressed("01", $hDLL) Then
      $sControl = _IsPressed("01", $hDLL)
       if $_TAB_IN == -1 Then $_TAB_IN = ControlGetHandle($MainGUI, "", $_MAIN_MOUSE_ID)
      EndIf  ;_IsPressed is "01"...left mouse click...

       While _IsPressed($sControl, $hDLL)
       Sleep(250)
       WEnd

...

_Some_Stuff()

...


     EndIf  ;make sensitivity to 'LEFT' mouse clicks...

    WEnd
EndFunc

Func _Some_Stuff()

...

    GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
    GUIRegisterMsg($WM_LBUTTONUP, "_POSITION_TRAX")

...

EndFunc

Func _POSITION_TRAX($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam

 ;calculate the mouse position (client coordinates) upon 'MOUSE UP' event...

           $_MOUSE_LOCATE = GUIGetCursorInfo($_CTRL_GUI)  ;Gets the mouse cursor position relative to GUI window (client coordinates)
           
            if IsArray($_MOUSE_LOCATE) == 1 Then

                 ;****ENSURE THE 'MOUSE_SETS' ARE RECORDED AT CURRENT LOCATION
                 ;    OF THE MOUSE RELEASE...
                 $_XMOUSE_SETS[$_CTRL_SELECT] = $_MOUSE_LOCATE[0]
                 $_YMOUSE_SETS[$_CTRL_SELECT] = $_MOUSE_LOCATE[1]
                 ;****

            EndIf  ;IsArray($_MOUSE_LOCATE) is 1 ($_MOUSE_LOCATE IS an array...)

EndFunc

Func WM_LBUTTONDOWN($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam

 ;calculate the mouse position (client coordinates) upon 'MOUSE DOWN' event...

    $iMouseX = BitAND($lParam, 0x0000FFFF)
    $iMouseY = BitShift($lParam, 16)

    if (Int($iMouseX) == Int($_XMOUSE_SETS[$_CTRL_SELECT])) AND (Int($iMouseY) == Int($_YMOUSE_SETS[$_CTRL_SELECT])) Then
ConsoleWrite("SAME LOCATION CLICKED...!!!" & @CRLF)
    MsgBox(64, "DOUBLE CLICKS:", "SAME LOCATION CLICKED...!!!")
    EndIf  ;same location...

     ;****ENSURE THE 'MOUSE_SETS' ARE RECORDED AT CURRENT LOCATION
     ;    OF THE MOUSE RELEASE...
     $_XMOUSE_SETS[$_CTRL_SELECT] = $iMouseX
     $_YMOUSE_SETS[$_CTRL_SELECT] = $iMouseY
     ;****

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONDOWN

 

Edited by Burgs
Link to comment
Share on other sites

  • Moderators

Burgs,

Why so complicated? This seems to work quite well:

#include <GUIConstantsEx.au3>

Global $aLastClick[2] = [9999, 9999]

$hGUI = GUICreate("Test", 500, 500)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_PRIMARYUP
            $aMPos = MouseGetPos()
            If $aMPos[0] = $aLastClick[0] And $aMPos[1] = $aLastClick[1] Then
                ConsoleWrite("Mouse has NOT moved" & @CRLF)
            Else
                ConsoleWrite("Mouse has moved" & @CRLF)
                $aLastClick = $aMPos
            EndIf

    EndSwitch

WEnd

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hello,

  Thank you for the reply.  I believe I cannot use the routine you posted since my 'GUIOnEventMode' option is set to 1....I do not believe the 'GUIGetMsg' will work, unless I am mistaken.  Is there a similar workaround?

  Using the 'schematic' code I posted do you think there would be any problem with the delay from when the click is pressed and the calling of the 'mouse event' functions...?  I wonder if the 250ms delay is causing a problem with the execution of the 'mouse down'/'mouse up' functions ('WM_LBUTTONDOWN' and '_POSITION_TRAX' respectively)...?  Thank you again for your time.

 

Link to comment
Share on other sites

  • Moderators

Burgs,

Why do OnEvent users never seem to be able to cope with converting MessageLoop code? It is not at all difficult:

#include <GUIConstantsEx.au3>

Global $aLastClick[2] = [9999, 9999]

Opt("GUIOnEventMode", 1)

$hGUI = GUICreate("Test", 500, 500)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_Click")

GUISetState()

While 1
    Sleep(10)
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _Click()
    $aMPos = MouseGetPos()
    If $aMPos[0] = $aLastClick[0] And $aMPos[1] = $aLastClick[1] Then
        ConsoleWrite("Mouse has NOT moved" & @CRLF)
    Else
        ConsoleWrite("Mouse has moved" & @CRLF)
        $aLastClick = $aMPos
    EndIf
EndFunc   ;==>_Click

I have no idea what you are talking about in the second part. As I said, why make it so complicated if you can do it simply with the native event handlers?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Burgs,

This code also detects whether the previous action was a double click:

#include <GUIConstantsEx.au3>
#include <Misc.au3>

Global $aLastClick[2] = [9999, 9999]

Opt("GUIOnEventMode", 1)

Global $bDoubleTap = False, $bPrevDoubleTap = False
Global $iPeriod = 250 ; Set limit for double tap interval
Global $iTimer = TimerInit()


Global $hDLL = DllOpen("user32.dll")

$hGUI = GUICreate("Test", 500, 500)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_Click")

GUISetState()

While 1
    Sleep(10)
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _Click()
    ; Was previous click within the "doubleclick" delay
    If TimerDiff($iTimer) > $iPeriod Then
        ; No so clear flags and restart timer
        $bDoubleTap = False
        $iTimer = TimerInit()
    Else
        ; Yes so set flags
        $bDoubleTap = True
        $bPrevDoubleTap = True
    EndIf
    ; Create message
    $sMsg = ""
    ; Determine if mouse has moved
    $aMPos = MouseGetPos()
    If $aMPos[0] = $aLastClick[0] And $aMPos[1] = $aLastClick[1] Then
        $sMsg = "Mouse has NOT moved"
    Else
        $sMsg = "Mouse has moved"
        $aLastClick = $aMPos
    EndIf
    ; If a doubleclick detected
    If $bDoubleTap Then
        $sMsg &= " - doubleclick detected"
    EndIf
    ; If it was not a double click but the previous action was
    If (Not $bDoubleTap) And $bPrevDoubleTap Then
        $sMsg &= " - previous action was doubleclick"
        $bPrevDoubleTap = False
    EndIf
    ; Announce result
    ConsoleWrite($sMsg & @CRLF)
EndFunc   ;==>_Click

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thank you for your assistance M23,

  I have not yet had a chance to play around with your script examples, however I am sure it will be of great help to me.  I appreciate it a great deal. 

  And to answer your question here "Why do OnEvent users never seem to be able to cope with converting MessageLoop code?"

   ...well I of course cannot speak for anybody else...only myself...the reason is because I am not very intelligent...   hehehehe   :) 

Burgs

Link to comment
Share on other sites

Hi again,

  I do have one quick comment/question about your code.  For a 'double-click', which is 2 quick successive clicks...the 'second' click must necessarily ALWAYS be in the same position as the 'first' click...correct? 

  Since that is the case I guess I must modify the code to compare the previously clicked position (''$aLastClick[0]' and '$aLastClick[1]') locations with the 'first' click and ignore the 'second' click...that logic would seem to be what is needed...correct?   

Link to comment
Share on other sites

  • Moderators

Burgs,

Quote

For a 'double-click', which is 2 quick successive clicks...the 'second' click must necessarily ALWAYS be in the same position as the 'first' click...correct? 

No, the code makes no check for that - however if you want the 2 clicks to be in reasonably close proximity it should not be to difficult to add a few lines.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...