Sign in to follow this  
Followers 0
CodeMaster Rapture

Creating my own Keyboard Message Pump

7 posts in this topic

Greetings,

I'm trying to create my own keyboard message pump (for extended hotkeys) and I've come across a problem of speed. DLLCall seems a bit too slow for my needs, unless there is some trick to using DLLs that I'm un aware of. I'm using _IsPressed from the Misc.au3 (props to the author) to poll specific hotkeys:

While 1
    If (_IsPressed($HK_RapidClick)) Then
        MouseClick("Left")
    ElseIf (_IsPressed($HK_Pause)) Then
        TogglePause()
    ElseIf (_IsPressed($HK_ToolTip)) Then
        ToggleToolTip()
    Else
        UpdateToolTip()
    EndIf
    Sleep(10)
Wend

This works just fine, but it can take up to a full second for the hotkey to fire (depending on how much CPU power I have availible). Is there a faster way?

Thanx,

-CMR

Share this post


Link to post
Share on other sites



Greetings,

I'm trying to create my own keyboard message pump (for extended hotkeys) and I've come across a problem of speed. DLLCall seems a bit too slow for my needs, unless there is some trick to using DLLs that I'm un aware of. I'm using _IsPressed from the Misc.au3 (props to the author) to poll specific hotkeys:

While 1
    If (_IsPressed($HK_RapidClick)) Then
        MouseClick("Left")
    ElseIf (_IsPressed($HK_Pause)) Then
        TogglePause()
    ElseIf (_IsPressed($HK_ToolTip)) Then
        ToggleToolTip()
    Else
        UpdateToolTip()
    EndIf
    Sleep(10)
Wend

This works just fine, but it can take up to a full second for the hotkey to fire (depending on how much CPU power I have availible). Is there a faster way?

Thanx,

-CMR

HotKeySet is faster, if you are able to set the hotkeys (some programs prevent you from assigning hotkeys). You can always cancel and reset hotkeys if the circumstances call for it.

Example:

You want to set the {ESC} key as a hotkey, but you need to press the {ESC} key when the hotkey is pressed (not perform the function called, but send the actual {ESC} keypress).

HotKeySet("{ESC}", "ESCKeyPress")

Func ESCKeyPress ()

HotKeySet ("{ESC}")

Send ("{ESC}") ; or ControlSend

HotKeySet ("{ESC}", "ESCKeyPress")

EndFunc

This will cancel the hotkey to send the raw key, then re-enable the hotkey after it is sent.

Hope this helps,

Nomad


Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Well the snipplet you gave will do it instantly for me.. some issues you could have are, an extra long While loop that takes time to go through each section it has to that you've programmed, or the fact that it has to go through a function check for conditions, and it takes time to get back to check that _Ispressed() again, or if it is specifically your MouseClick(), you have no speed there, you can change the Opt('MouseClickDelay') settings or use MouseClick('left', MouseGetPos(0), MouseGetPos(1), 1, 1) maybe to speed things up.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

I cannot use HotkeySet for some of my Hotkeys (Mouse1-5 for instance), which is why I'm using _IsPressed. Also, my While loops is nice and compact (for the main app) and I'm ensuring I'm only polling what is absolutely neccesary. Now, the odd part is that if I poll ALL the possible keys (create an array of all the possible keys and loop thru it) it takes the same amount of time (roughly) as polling 3-4 hotkeys. For example:

Const $h_KeyList[95] = ["0x01","0x02","0x04","0x05","0x06","0x08","0x09","0x0D","0x10","0x11","0x12","0x13","0x14","0x1B",_
"0x20","0x21","0x22","0x23","0x24","0x25","0x26","0x27","0x28","0x2C","0x2D","0x2E","0x30","0x31",_
"0x32","0x33","0x34","0x35","0x36","0x37","0x38","0x39","0x41","0x42","0x43","0x44","0x45","0x46",_
"0x47","0x48","0x49","0x4A","0x4B","0x4C","0x4D","0x4E","0x4F","0x50","0x51","0x52","0x53","0x54",_
"0x55","0x56","0x57","0x58","0x59","0x5A","0x60","0x61","0x62","0x63","0x64","0x65","0x66","0x67",_
"0x68","0x69","0x6A","0x6B","0x6D","0x6E","0x6F","0x70","0x71","0x72","0x73","0x74","0x75","0x76",_
"0x77","0x78","0x79","0x7A","0x7B","0x90","0x91","0xA0","0xA1","0xA2","0xA3"]

Func _KBGetMsg()
    For $iter = 0 To (UBound($h_KeyList) - 1)
        If (_IsPressed($h_KeyList[$iter])) Then
            Return $h_KeyList[$iter]
        EndIf
    Next
    Return ""
EndFunc

While 1
    $KB_Msg = _KBGetMsg()

    Switch $KB_Msg
        Case $HK_Quit
            Exit
        Case $HK_TogglePause
            TogglePause()
        ;etc
    EndSwitch
    
    ;Debug
    If ($KB_Msg <> "") Then
        MsgBox(0,"Key pressed",$KB_Msg)
    EndIf
    ;End of Debug

    Sleep(10)
WEnd

One would think that the above could would be dramatically slower (95 calls to _IsPressed() per While Loop) than my previous code of 3 calls to _IsPressed().

Share this post


Link to post
Share on other sites

Maybe you set your conditions wrong with If/ElseIf/ElseIf... your example here isn't looking for "If/Else" it's simply "If".


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Use modified version of IsPressed() from latest beta version.

Inside first version is:

$aR = DllCall("user32", "int", "GetAsyncKeyState", "int", $hexKey)

so it for every key do DllOpen, DllCall,DllClose

In new version is:

Func _IsPressed($s_hexKey, $v_dll = 'user32.dll')
; $hexKey must be the value of one of the keys.
; _Is_Key_Pressed will return 0 if the key is not pressed, 1 if it is.
    Local $a_R = DllCall($v_dll, "int", "GetAsyncKeyState", "int", '0x' & $s_hexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
EndFunc  ;==>_IsPressed

At begining of your script put:

$dll = DllOpen("user32.dll")

and then call it like this:

_IsPressed($key, $dll)

Read Remarks for DllCall in helpfile.

Share this post


Link to post
Share on other sites

LOL I love it .... " Yo can I get some help? and give your input" then "sure here's something that may help try this" and the reply "no, no and um no, you're wrong"

:) funny stuff.


~Projects~1. iPod Ejector 1.0 - Tool Used To Eject iPod in Windows - Uses DevEject.exe :P2. SmartFTP Close Popup Tool - Closes reminders from freeware SmartFTP.~Helpful Links For New Users~1. LXP's Learning AutoIT PDF Guide - <<< Go here for a PDF Guide on learning AutoIT from the ground up!<<<2. AutoIt 1-2-3 <<<Want to learn more about AutoIT quickly? Go Here<<<3. How To Install The Beta And Production Versions Of AutoIT / SciteAutoIT

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0