Jump to content

Multiple keystroke handling


mike1950r
 Share

Recommended Posts

quote from https://www.autoitscript.com/forum/topic/208600-smartnote/

; ℹ️  While Right Windows Key IsPressed, tap 2 times the Right SHIFT key to start NewCapture,
;     is useful when Capture menu or contex.
; While start NewCapture point click anywhere to escape. (does not catch smaller than 9*9 px)
; While start NewCapture escape with ESC

Global $iShift

; loop until program exit
;************************************************
While Sleep(100)
    $iShift = 0
    While _IsPressed("5C", $hDLL) ; 5C = Right Windows key
        Sleep(100)
        If _IsPressed("A1", $hDLL) Then ; A1 = Right SHIFT key
            While _IsPressed("A1", $hDLL)
                Sleep(100)
            WEnd
            $iShift += 1
        EndIf

        If $iShift = 2 Then
            NewCapture()
            ExitLoop
        EndIf
    WEnd
WEnd
;************************************************

if that helps you

 

I know that I know nothing

Link to comment
Share on other sites

This is the concept for a single key. If you are looking to do it for multiple keys you might want to use a keyboard hook. There are plenty of examples on the forum about how to create a keyboard hook. There is even an example in help file for _WinAPI_SetWindowsHookEx() function.

#include <Misc.au3>

$hUser32 = DllOpen('user32.dll')

While True
    If _IsPressed('1B', $hUser32) Then ExitLoop     ; Exit if ESC key is pressed
    If _IsPressed('41', $hUser32) Then              ; Key A pressed
        ConsoleWrite('Key A is pressed down.' & @CRLF)
        Do
            Sleep(10)
        Until Not _IsPressed('41', $hUser32)
        ConsoleWrite('Key A is released.' & @CRLF)
    EndIf
    Sleep(10)
WEnd

DllClose($hUser32)

Here is a version using a keyboard hook:

#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>

Global $fExit = False

$hKeyboardProc = DllCallbackRegister('KeyboardProc', 'long', 'int;wparam;lparam')
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hKeyboardProc), _WinAPI_GetModuleHandle(0))

While Not $fExit
    Sleep(10)
WEnd

_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hKeyboardProc)

Func KeyboardProc($nCode, $wParam, $lParam)
    Local Static $LastKey = Null
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    Local $tKEYHOOKS = DllStructCreate('dword vkCode;dword scanCode;dword flags;dword time;ulong_ptr dwExtraInfo', $lParam)
    Switch $wParam
        Case $WM_KEYDOWN
            If $tKEYHOOKS.vkCode = 0x1B Then $fExit = True
            If $LastKey = Null Then
                $LastKey = $tKEYHOOKS.vkCode
                ConsoleWrite('Virtual key ' & $tKEYHOOKS.vkCode & ' is pressed.' & @CRLF)
            EndIf
        Case $WM_KEYUP
            If $LastKey = $tKEYHOOKS.vkCode Then
                $LastKey = Null
                ConsoleWrite('Virtual key ' & $tKEYHOOKS.vkCode & ' is released.' & @CRLF)
            EndIf
    EndSwitch
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc

 

Edited by Andreik
added keyboard hook example
Link to comment
Share on other sites

Hi Andreik ,

thanks for your examples.

In fact I need this for multiple keystrokes, also combinations with CTRL, SHIFT, ALTERNATE.

The idea is, that it should not matter how long the user clicks on the key, it should always only beeing treated once to avoid key-loops.

I will check your keyboard hook example, if this can help me.

Cheers mike

Link to comment
Share on other sites

You receive CTRL and SHIFT in $tKEYHOOKS.vkCode and you can also check if ALT key is pressed by processing $tKEYHOOKS.flags (if bit 5 is 1 then ALT key is pressed).

Here you have some documentation:

https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-kbdllhookstruct

Edited by Andreik
Link to comment
Share on other sites

5 hours ago, mike1950r said:

when the user holds the key longer

look at the code at https://www.autoitscript.com/forum/topic/211304-getasynckeystate-_ispressed-vs-the-bluetooth-headset-now-fight/#comment-1528571

Maybe that does what you need ?.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

On 12/31/2023 at 9:11 PM, argumentum said:

Hello again,

sorry for the delay: Happy new year to everybody. 😉

I think your idea in the other thread is just what i need.

React on _IsPressed but not on _IsHeld.

But sorry, I did not understand how to get this working.
This should be for any keystroke.

For example use in windows photoviewer:

Select all photos in a folder and preview in photoviewer.

If you hold the right arrow key to long, it runs thru the selection photo after photo until the pipe is empty.
I want to avoid this.

Thanks for assistance.

Cheers mike

Link to comment
Share on other sites

54 minutes ago, mike1950r said:

React on _IsPressed but not on _IsHeld.

Is just what it does. On @extended, zero means pressed and one means held after. If you keep the key pressed longer, then the autorepeat kicks in on regular keys. For Alt, ctrl, etc. then those keys have their own behavior.

On 12/31/2023 at 9:44 AM, mike1950r said:

Hello, how can i handle keystrokes, when the user holds the key longer to get only ONE keystroke. Thanks for an idea.

The question is what key ?

Post a simple running code where the problem becomes evident for us, any/all of us, to help you better. Otherwise we can chat all day and not solve the problem you have.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

hello argumentum,

here is just an example:

Func PhotoViewerHotKeySet()
    HotKeyset("^{TAB}", "PhotoViewerHotKeyPressed")

    HotKeySet("^!{ESC}", "PhotoViewerHotKeyPressed")
    HotKeySet("!{ESC}", "PhotoViewerHotKeyPressed")

    etc ...
EndFunc   ;==>PhotoViewerHotKeySet

Func PhotoViewerHotKeyPressed()
    Switch @HotKeyPressed
        Case "^{TAB}"

        etc ...
    EndSwitch
EndFunc   ;==>PhotoViewerHotKeyPressed

Cheers mike

Link to comment
Share on other sites

52 minutes ago, mike1950r said:

here is just an example:

18 hours ago, argumentum said:

Post a simple running code

The reason for a running code and not just the important function is that I'd have to code the while loop and what not. I'd like to copy and paste, then just run it. Is easier for me at your expense. Otherwise is easier for you at my expense.

Switch @HotKeyPressed
        Case "^{TAB}"
;~          If _IsPressed("11") And _IsPressed("09") Then
                ; do your thing
                While _IsPressed("11") And _IsPressed("09")
                    Sleep(50) ; 11 CTRL key ; 09 TAB key
                WEnd
;~          EndIf

 

Edited by argumentum
added the code

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Hello again,

unfortunately this does not solve my problem.

Inserting this code for any CASE is too much effort.

I'm looking for a single principal methode to empty the keystroke pipe.

This should be in the beginning of the HotkeyPressed function prohibiting the useless repeats of keystrokes.
They do not appear when the user holds the key down, but when he releases the key afterwards holding down a while.

In fact the @HotKeyPressed variable should be empty, when the user releases the keys.

This was my idea.

Thanks anyway for your help.

Cheers mike

Link to comment
Share on other sites

take a look, i think it does what you want
205141-multiple-keyboards-hotkeyset-udf

#include "MKHKS-UDF.au3" ;https://www.autoitscript.com/forum/topic/205141-multiple-keyboards-hotkeyset-udf

Example()

;----------------------------------------------------------------------------------------
Func Example()
    _MKHKS_Initialize(False) ;With True Show list of keyboards

    _MKHKS_Register_HotKey("^{TAB}", PhotoViewerHotKeyPressed, 0) ;set hotkey to 1st keyboarb
    _MKHKS_Register_HotKey("^!{ESC}", PhotoViewerHotKeyPressed, 0) ;set hotkey to 1st keyboarb
    _MKHKS_Register_HotKey("!{ESC}", PhotoViewerHotKeyPressed, 0) ;set hotkey to 1st keyboarb

    While True
        _MKHKS_WaitForEvent()
        Sleep(50)
    WEnd

EndFunc   ;==>Example
;----------------------------------------------------------------------------------------
Func PhotoViewerHotKeyPressed()
    Switch @HotKeyPressed
        Case "^{TAB}"
            ConsoleWrite("^{TAB}" & @CRLF)
        Case "^!{ESC}"
            ConsoleWrite("^!{ESC}" & @CRLF)
        Case "!{ESC}"
            ConsoleWrite("!{ESC}" & @CRLF)
    EndSwitch
EndFunc   ;==>PhotoViewerHotKeyPressed
;----------------------------------------------------------------------------------------

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

Hi ioa747,

thanks for your post.
This looks very interesting.
I will check it out.

If I understand it right,
I would just change my hotkeyset function,
and the hotkeypressed function would be the same.

I will download the lib and install it.

Thanks so far.

Cheers mike

Link to comment
Share on other sites

Link to comment
Share on other sites

Same goes with my UDF.  But you did not answer my question, do you have multiple keyboards ?

It does not seem to work, I will need to investigate...

Edited by Nine
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...