Jump to content

HotKeySet DoubleClick Detect


JohnBailey
 Share

Recommended Posts

How do I detect a key being pressed twice in succession like a doublePress action for a key? In the example I'm trying to detect F4. I thought maybe using the DLLCallBack.au3 but I thought that may be over kill for a timer and there may be a better method in general.

#include <Constants.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
HotKeySet('{F4}','detect')

Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode",1)
Opt("TrayMenuMode",1); Default tray menu items (Script Paused/Exit) will not be shown.

$ParentWin = GUICreate("HotKey DoubleClick Detect Ex.", 298, 321, 254, 210)
$LogED = GUICtrlCreateEdit("", 17, 27, 259, 276)
$Label1 = GUICtrlCreateLabel("Log", 18, 8, 36, 17)
GUICtrlSetColor(-1, 0xC0C0C0)

GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "_GuiEvents")

$TrayExititem = TrayCreateItem("Exit")

TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE,"TrayEvents")
TrayItemSetOnEvent($TrayExititem,"TrayEvents")

GUISetState(@SW_SHOW)
TraySetClick(16)

While 1
    Sleep(10)
WEnd

Func detect()
    GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & 'F4 SingleClick')
    _GUICtrlEditLineScroll ($LogED, 0, _GUICtrlEditGetLineCount ($LogED))
    TrayTip(@ScriptName, "F4 SingleClicked", 10, 0)
EndFunc

Func _GuiEvents()
    Select
        Case @GUI_CTRLID = $GUI_EVENT_CLOSE
           Exit
            
        Case @GUI_CTRLID = $GUI_EVENT_MINIMIZE
            WinSetState($ParentWin, "", @SW_HIDE)
            TrayTip(@ScriptName, "has been minimzed. Doubleclick here to restore", 10, 0)
  
    EndSelect
    
EndFunc

Func TrayEvents()
    Switch @TRAY_ID
        Case $TrayExititem
            Exit
        Case $TRAY_EVENT_PRIMARYDOUBLE
            WinSetState($ParentWin, "", @SW_SHOW)
            WinSetState($ParentWin, "", @SW_RESTORE)
            TrayTip(@ScriptName, "", 0)
    EndSwitch
EndFunc

Edit: confusing wording

Mods:

You are more than welcome to rename this thread's title to something like HotKeySet DoublePress Detect or Key DoublePress Detect

Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

This is what I mean by using the DllCallBack (thanks to Martin for showing me how to use this)

#include <Constants.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include <DllCallBack.au3>
#include <misc.au3>
HotKeySet('{F4}','detect')

$pTimerProc = _DllCallBack ("_TimerProc", "hwnd;uint;uint;dword")
$uiTimer = DllCall("user32.dll", "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 50, "ptr", $pTimerProc)
$uiTimer = $uiTimer[0]

Global $click=0

Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode",1)
Opt("TrayMenuMode",1)  ; Default tray menu items (Script Paused/Exit) will not be shown.

$ParentWin = GUICreate("HotKey DoubleClick Detect Ex.", 298, 321, 254, 210)
$LogED = GUICtrlCreateEdit("", 17, 27, 259, 276)
$Label1 = GUICtrlCreateLabel("Log", 18, 8, 36, 17)
GUICtrlSetColor(-1, 0xC0C0C0)

GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "_GuiEvents")

$TrayExititem = TrayCreateItem("Exit")

TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE,"TrayEvents")
TrayItemSetOnEvent($TrayExititem,"TrayEvents")

GUISetState(@SW_SHOW)
TraySetClick(16)

While 1
    Sleep(10)
    
WEnd

Func detect()
    If $click < 5 Then
        GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & 'F4 DoubleClick'& @CRLF & $click)
    Else
        GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & 'F4 SingleClick'& @CRLF & $click)
        _GUICtrlEditLineScroll ($LogED, 0, _GUICtrlEditGetLineCount ($LogED))
        TrayTip(@ScriptName, "F4 SingleClicked", 10, 0)
    EndIF
    $click=0
EndFunc

Func _GuiEvents()
    Select
        Case @GUI_CTRLID = $GUI_EVENT_CLOSE
            _DllCallBack_Free ($pTimerProc)
            DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "uint", $uiTimer)
           Exit
            
        Case @GUI_CTRLID = $GUI_EVENT_MINIMIZE
            WinSetState($ParentWin, "", @SW_HIDE)
            TrayTip(@ScriptName, "has been minimzed. Doubleclick here to restore", 10, 0)
  
    EndSelect
    
EndFunc

Func TrayEvents()
    Switch @TRAY_ID
        Case $TrayExititem
            _DllCallBack_Free ($pTimerProc)
            DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "uint", $uiTimer)
            Exit
        Case $TRAY_EVENT_PRIMARYDOUBLE
            WinSetState($ParentWin, "", @SW_SHOW)
            WinSetState($ParentWin, "", @SW_RESTORE)
            TrayTip(@ScriptName, "", 0)
    EndSwitch
EndFunc


Func _TimerProc($hWnd, $uiMsg, $idEvent, $dwTime)
    $click+=1
    GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & $click)
    _GUICtrlEditLineScroll ($LogED, 0, _GUICtrlEditGetLineCount ($LogED))
EndFunc

For something so simple it seems to be overkill and a waste of that Dll. Any ideas anyone?

A decision is a powerful thing
Link to comment
Share on other sites

Check out IsPressed() and see if that helps you.

_IsPressed

--------------------------------------------------------------------------------

Check if key has been pressed

#Include <Misc.au3>
_IsPressed ( $s_hexKey [, $v_dll = 'user32.dll' ] )
You'll note the Remarks section under IsPressed() in the Help files also says this works with mouse clicks.

Remarks

01 Left mouse button

02 Right mouse button

04 Middle mouse button (three-button mouse)

Link to comment
Share on other sites

haha looks like we both posted the _IsPress at almost the same time. The only thing I don't like about doing this is it means I have to use the While loop or I have to use an AdlibEnable(), which I guess is what's should be done since no one else but you has suggested anything.

Thanks

Local $timer = 0
While 1
    Sleep(40)
    $timer +=1
    If _IsPressed("73", $dll) Then
        If $timer < 10  Then
            GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & '!!F4 DoubleClick!!'& @CRLF & $timer)
            _GUICtrlEditLineScroll ($LogED, 0, _GUICtrlEditGetLineCount ($LogED))
            TrayTip(@ScriptName, "!!F4 DoubleClicked!!", 10, 0)
        Else
            GUICtrlSetData($LogED, GUICtrlRead($LogED) & @CRLF & 'F4 SingleClick'& @CRLF & $timer)
            _GUICtrlEditLineScroll ($LogED, 0, _GUICtrlEditGetLineCount ($LogED))
            TrayTip(@ScriptName, "F4 SingleClicked", 10, 0)
        EndIF
        $timer=0
    EndIf
WEnd

BTW, I'm not sure what you meant by the mouse click... What were you meaning by that?

Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

LOL, yeah another photo finish :).

I'll admit I haven't read your code, I just searched to see if you used IsPressed(). But from what it looks like with your Gui...() commands, a While...WEnd wouldn't hurt your script. Most "GUIs" have one anyway waiting on the GUIGetMsg(), right? That's where the IsPressed() would go with some If...Then lock wrapped around it like you have in your example. BTW, you can simply use

If _IsPressed("73") Then

BTW, I'm not sure what you meant by the mouse click... What were you meaning by that?

The reason I mentioned "mouse click" is because you used the word "click." To me keys are pressed and things are "clicked" with a mouse. Granted this could be a language difference that we have, and since I'm not 100% clear on what you meant by "How do I detect a double click with a hotkey" I offered the mouse info in case you or others reading this thread thought IsPressed() is only for keys being pressed on the keyboard.

I've to run for now, but if you still need some help when I get back I'll pull your code into SciTE and see how I can help you out with this.

Link to comment
Share on other sites

How do I detect a double click with a hotkey? In the example I'm trying to detect F4. I thought maybe using the DLLCallBack.au3 but I thought that may be over kill for a timer and there may be a better method in general.

Ok John, I'm back and see that no one else has posted. I pulled and ran your script in SciTE4AutoIt3 and to be honest I'm not sure what you're trying to accomplish with the GUI and the running count. Also your TrayTip doesn't match up with your log window. Meaning the log window will correctly identify when a single or double click occurs but the TrayTip will always say Single Click.

Anyways, you can take a look at the following script and it will tell you if the F4 key has been double or single "clicked" with a MsgBox(). Hopefully this gives you enough of an idea that you can use the code. If I've totally missed what you're trying to accomplish, please clarify and I'll see what I can come up with.

Cheers!

#include<misc.au3>
HotKeySet("{F4}", "_Detected")

MsgBox(0, "HotKey Detection", "Test if the F4 key has been pressed 1 or 2 times.")
While 1
    Sleep(10)
WEnd

Func _Detected()
    If _IsPressed("73") Then
        $start = TimerInit()
        While _IsPressed("73")
            Sleep(50)
        WEnd
        $diff = TimerDiff($start)
        Sleep(10)
        If $diff >= 100 Then MsgBox(0, "F4 Detected", "Single Click: F4 pressed 1 time")
        If ($diff > 0) And ($diff < 100) Then MsgBox(0, "F4 Detected", "Double Click: F4 pressed 2 times")
    EndIf
EndFunc   ;==>_Detected
Link to comment
Share on other sites

Most "GUIs" have one anyway waiting on the GUIGetMsg(), right?

Normally, yeah they probably do. I don't use GUIGetMsg() at all, but I do indeed use the While loop

BTW, you can simply use

If _IsPressed("73") Then
haha I didn't even notice that. good point! :)

The reason I mentioned "mouse click" is because you used the word "click." To me keys are pressed and things are "clicked" with a mouse. Granted this could be a language difference that we have, and since I'm not 100% clear on what you meant by "How do I detect a double click with a hotkey" I offered the mouse info in case you or others reading this thread thought IsPressed() is only for keys being pressed on the keyboard.

I've to run for now, but if you still need some help when I get back I'll pull your code into SciTE and see how I can help you out with this.

Now I see what you mean, and my original wording is confusing. I thought of a mouse button being pressed/clicked as the same as a keyboard button being pressed/clicked. However, that is not how they are generally used; they are used like you said click for mouse and press for keyboard. My original wording was not good and I must admit I have moments like this where the simplest wording to a simple question evades me. Thank you for your patience. I was hoping the code would clarify any confusing wording. Also, it is good to point out that mouseclicks can be used with _IsPressed(), especially with my horribly confusing wording.
A decision is a powerful thing
Link to comment
Share on other sites

Ok John, I'm back and see that no one else has posted. I pulled and ran your script in SciTE4AutoIt3 and to be honest I'm not sure what you're trying to accomplish with the GUI and the running count. Also your TrayTip doesn't match up with your log window. Meaning the log window will correctly identify when a single or double click occurs but the TrayTip will always say Single Click.

Anyways, you can take a look at the following script and it will tell you if the F4 key has been double or single "clicked" with a MsgBox(). Hopefully this gives you enough of an idea that you can use the code. If I've totally missed what you're trying to accomplish, please clarify and I'll see what I can come up with.

Cheers!

#include<misc.au3>
HotKeySet("{F4}", "_Detected")

MsgBox(0, "HotKey Detection", "Test if the F4 key has been pressed 1 or 2 times.")
While 1
    Sleep(10)
WEnd

Func _Detected()
    If _IsPressed("73") Then
        $start = TimerInit()
        While _IsPressed("73")
            Sleep(50)
        WEnd
        $diff = TimerDiff($start)
        Sleep(10)
        If $diff >= 100 Then MsgBox(0, "F4 Detected", "Single Click: F4 pressed 1 time")
        If ($diff > 0) And ($diff < 100) Then MsgBox(0, "F4 Detected", "Double Click: F4 pressed 2 times")
    EndIf
EndFunc   ;==>_Detected
Great idea with the While _IsPressed() and the AND in the last if-statement !!

That's the basic idea. I just had a LOT of extra crud that was just being used for my personal testing, because I didn't know how to not use a timer that counted up using the While loop. What you did is perfect and a good example of what I was asking. It's clean and can be adjusted easily. thanks

A decision is a powerful thing
Link to comment
Share on other sites

... What you did is perfect and a good example of what I was asking. It's clean and can be adjusted easily. thanks

Thank you and your quite welcome, glad I could help and the code works for you. Isn't it great when we can learn from each other?? This is the way the forum should be, and not littered with .... oh nevermind :sigh:. Some things will never change.
Link to comment
Share on other sites

Thank you and your quite welcome, glad I could help and the code works for you. Isn't it great when we can learn from each other?? This is the way the forum should be, and not littered with .... oh nevermind :sigh:. Some things will never change.

haha indeed!

A decision is a powerful thing
Link to comment
Share on other sites

See my signature, I have a sample of doubleclick and right click in a list...

My wording was horribly misleading in the title of this thread and the original post of this thread. I should not have used the word click for starters. :"> my bad. ssubirias3 pointed that out.

As for double clicking involving a mouse (like most understand the word click to be associated with), here is a method I use. I prefer to use $NM_ vars.

thanks garyfrost and eltorro

#include <GUIConstants.au3>
If Not IsDeclared('WM_NOTIFY') Then         Global Const $WM_NOTIFY     = 0x004E
If Not IsDeclared('NM_FIRST') Then          Global Const $NM_FIRST              = 0
If Not IsDeclared('NM_CLICK') Then          Global Const $NM_CLICK              = ($NM_FIRST - 2)
If Not IsDeclared('NM_DBLCLK') Then         Global Const $NM_DBLCLK             = ($NM_FIRST - 3)
    
Opt("GUIOnEventMode", 1)

#Region ### START Koda GUI section ### Form=I:\SAI\Auto-It files\GUI Designs\DoubleClick Listview Example.kxf
$ParentWin = GUICreate("DoubleClickListview Example", 440, 447, 193, 125)
$Label1 = GUICtrlCreateLabel("DoubleClick Listview", 92, 13, 263, 17, $SS_CENTER)
GUICtrlSetFont($Label1, 8, 800, 0, "MS Sans Serif")

$LV_Main = GUICtrlCreateListView("Name|Number", 20, 36, 395, 310)
GUICtrlSendMsg(-1, 0x101E, 0, 200)
GUICtrlSendMsg(-1, 0x101E, 1, 175)
$LV_Main_0 = GUICtrlCreateListViewItem("William Wells|084613", $LV_Main)
$LV_Main_1 = GUICtrlCreateListViewItem("Takumi Pärn|088943", $LV_Main)
$LV_Main_2 = GUICtrlCreateListViewItem("Ryan Jansen|135649", $LV_Main)
$LV_Main_3 = GUICtrlCreateListViewItem("Magnús Lancher|098674", $LV_Main)
$LV_Main_4 = GUICtrlCreateListViewItem("Afshan Kukk|135679", $LV_Main)

$StatusBar_LB = GUICtrlCreateLabel("", 0, 429, 439, 17, BitOR($SS_CENTER,$SS_SUNKEN))
GUICtrlSetColor($StatusBar_LB, 0x808080)

GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")

GUIRegisterMsg($WM_NOTIFY,  'WM_Notify_Events')
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    Sleep(100)
WEnd

Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam);Eltorro/GaFrost showed me this
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event, $from ;from only needed if EditInPlace is in the script
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then 
        $tagNMHDR =0
        Return
    EndIf
    $from = DllStructGetData($tagNMHDR, 1)
    $event = DllStructGetData($tagNMHDR, 3)
    Select
; The following is used specifically for EditInPlace 
        Case $wParam = $LV_Main
            Select
                Case $event = $NM_CLICK
                    GUICtrlSetData($StatusBar_LB,"Singleclicked: " & GUICtrlRead(GUICtrlRead($LV_Main)))
                Case $event = $NM_DBLCLK
                    GUICtrlSetData($StatusBar_LB,"Doubleclicked: " & GUICtrlRead(GUICtrlRead($LV_Main)))
                    
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    If $wParam <> $LV_Main Then
        Return $GUI_RUNDEFMSG
    EndIf
    
EndFunc ;==>WM_Notify_Events

Func _GUIEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            Exit
    EndSelect
EndFunc ;==>_GUIEvents

Edit: I'm an idiot - see below post.

Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

No Biggy, I was at work and skimmed in and saw the title.. I just didn't read the rest.. Sorry..I like the double hotkey pressed thingy. I added it o my collection of snippets for future projects..

I had to actually reword the original post, because unless the code itself was read then my English wording was just plain misleading. Yeah, ssubirias3 did a nice job.

A decision is a powerful thing
Link to comment
Share on other sites

Not me, I am just a squirel trying to get a nut in this world.. LOL I would leave it like it is. It is better described one one takes time to read into it. LOL

Where ya from John?

edit: added to post

Edited by gesller
Link to comment
Share on other sites

Not me, I am just a squirel trying to get a nut in this world.. LOL I would leave it like it is. It is better described one one takes time to read into it. LOL

Where ya from John?

edit: added to post

I'm actually from Dallas, TX, but "common sense English" can escape me often.

I admire those who speak multiple languages or who speak English as a second language (Proverb: "Learn a language; gain a [extra] soul"). I can struggle with my first language.

It's interesting though. This thread has pointed out to me how we use action words differently in relation to a mouse and a keyboard, when we basically are preforming the exact same actions. That is very interesting.

A decision is a powerful thing
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...