Burgs Posted April 7, 2018 Posted April 7, 2018 (edited) 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. expandcollapse popupGlobal $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 April 7, 2018 by Burgs
Moderators Melba23 Posted April 7, 2018 Moderators Posted April 7, 2018 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 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Burgs Posted April 7, 2018 Author Posted April 7, 2018 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.
Moderators Melba23 Posted April 7, 2018 Moderators Posted April 7, 2018 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 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Moderators Melba23 Posted April 7, 2018 Moderators Posted April 7, 2018 Burgs, This code also detects whether the previous action was a double click: expandcollapse popup#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 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Burgs Posted April 8, 2018 Author Posted April 8, 2018 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
Burgs Posted April 8, 2018 Author Posted April 8, 2018 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?
Moderators Melba23 Posted April 8, 2018 Moderators Posted April 8, 2018 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 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now