Jump to content

Recommended Posts

Posted

When I hold a key down I need it to fire a function which will run until I release the key.

I tried using _IsPressed which works, but it continues sending the actual key I'm holding down which is no good.

To prevent the key being sent I used HotKeySet. However, when I hold down the key set as a hotkey, it triggers the function continuously until I let go. So back to square one.

Is there a way to achieve what I want?

 

#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")

HotKeySet("{F8}", "Terminate")
HotKeySet("=", "test")

Func Terminate()
    DllClose($hDLL)
    Exit 0
EndFunc

Func test()
    If _IsPressed("BB", $hDLL) Then
        ConsoleWrite("_IsPressed - '=' Key was pressed." & @CRLF)
        While _IsPressed("BB", $hDLL)
            ConsoleWrite("  '=' Key remains pressed." & @CRLF)
            Sleep(250)
        WEnd
        ConsoleWrite("_IsPressed - '=' Key was released." & @CRLF)
    EndIf
    Sleep(250)
EndFunc

While 1
    Sleep(250)
WEnd

DllClose($hDLL)

 

Posted (edited)

What is it, that you are trying to achieve?

I changed to key 1 for testing.

 

#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")

HotKeySet("{F8}", "Terminate")

Func Terminate()
    DllClose($hDLL)
    Exit 0
EndFunc

Func test()
    If _IsPressed("31", $hDLL) Then
        ConsoleWrite("_IsPressed - '=' Key was pressed." & @CRLF)
        While _IsPressed("31", $hDLL)
            ConsoleWrite("  '=' Key remains pressed." & @CRLF)
            Sleep(250)
        WEnd
        ConsoleWrite("_IsPressed - '=' Key was released." & @CRLF)
    EndIf
EndFunc

While 1
    Sleep(250)
    test()
WEnd

DllClose($hDLL)

 

 

Edited by Xenobiologist

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Posted
16 minutes ago, Xenobiologist said:

What is it, that you are trying to achieve?

I changed to key 1 for testing.

 

#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")

HotKeySet("{F8}", "Terminate")

Func Terminate()
    DllClose($hDLL)
    Exit 0
EndFunc

Func test()
    If _IsPressed("31", $hDLL) Then
        ConsoleWrite("_IsPressed - '=' Key was pressed." & @CRLF)
        While _IsPressed("31", $hDLL)
            ConsoleWrite("  '=' Key remains pressed." & @CRLF)
            Sleep(250)
        WEnd
        ConsoleWrite("_IsPressed - '=' Key was released." & @CRLF)
    EndIf
EndFunc

While 1
    Sleep(250)
    test()
WEnd

DllClose($hDLL)

 

 

 

When you run the code, open up notepad, and press and hold 1, the cosole output is correct, but as you will see, AutoIt keeps sending 1 to the notepad. Which is no good, re my initial post:

25 minutes ago, Seminko said:

I tried using _IsPressed which works, but it continues sending the actual key I'm holding down which is no good.

 

Posted
#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")

HotKeySet("{F8}", "Terminate")
HotKeySet("=", "test")

Func Terminate()
    DllClose($hDLL)
    Exit 0
EndFunc

Func test()
    HotKeySet('=')
    ConsoleWrite("_IsPressed - '=' Key was pressed." & @CRLF)
    Do
        ConsoleWrite("  '=' Key remains pressed." & @CRLF)
        Sleep(250)
    Until Not _IsPressed('BB', $hDLL)
    ConsoleWrite("_IsPressed - '=' Key was released." & @CRLF)
    Sleep(250)
    HotKeySet("=", "test")
EndFunc

While 1
    Sleep(250)
WEnd

DllClose($hDLL)

 

Posted
18 minutes ago, Andreik said:
#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")

HotKeySet("{F8}", "Terminate")
HotKeySet("=", "test")

Func Terminate()
    DllClose($hDLL)
    Exit 0
EndFunc

Func test()
    HotKeySet('=')
    ConsoleWrite("_IsPressed - '=' Key was pressed." & @CRLF)
    Do
        ConsoleWrite("  '=' Key remains pressed." & @CRLF)
        Sleep(250)
    Until Not _IsPressed('BB', $hDLL)
    ConsoleWrite("_IsPressed - '=' Key was released." & @CRLF)
    Sleep(250)
    HotKeySet("=", "test")
EndFunc

While 1
    Sleep(250)
WEnd

DllClose($hDLL)

 

Thanks for the reply. I tried just that before posting the thread. It suffers from the same unwanted behavior as Xenobiologist's asnwer. Since you remove the hotkey in the function, '=' is being sent during the function execution.

  • Solution
Posted (edited)

Well, if you want to suppress the key just use a keyboard hook:

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

Global $bExit = False

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

Do
    Sleep(10)
Until $bExit

_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hKeyboardProc)

Func KeyboardProc($nCode, $wParam, $lParam)
    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 $bExit = True
            If $tKEYHOOKS.vkCode = 0xBB Then
                ConsoleWrite('= is pressed down' & @CRLF)
                Return 1
            EndIf
        Case $WM_KEYUP
            If $tKEYHOOKS.vkCode = 0xBB Then
                ConsoleWrite('= is released' & @CRLF)
                Return 1
            EndIf
    EndSwitch
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc

 

Edited by Andreik
Posted
1 hour ago, Andreik said:

Well, if you want to suppress the key just use a keyboard hook:

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

Global $bExit = False

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

Do
    Sleep(10)
Until $bExit

_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 $bExit = True
            If $tKEYHOOKS.vkCode = 0xBB Then
                ConsoleWrite('= is pressed down' & @CRLF)
                Return 1
            EndIf
        Case $WM_KEYUP
            If $tKEYHOOKS.vkCode = 0xBB Then
                ConsoleWrite('= is released' & @CRLF)
                Return 1
            EndIf
    EndSwitch
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc

 

Great stuff! Thank you very much.

I'm totally lost when it comes to DLL stuff, though. Would you be willing to comment the code a bit?

Posted (edited)
#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>

Global $KeyDown = False

; Register a hotkey to exit the program
HotKeySet('{ESC}', 'Quit')

; Set a low level keyboard hook
; KeyboardProc it's a callback function that it's called when keyboard events occurs
$hKeyboardProc = DllCallbackRegister('KeyboardProc', 'long', 'int;wparam;lparam')
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hKeyboardProc), _WinAPI_GetModuleHandle(0))

Do
    ; We process the messsage here because it's a good practice to return from 
    ; the callback function as soon as possible and without using any blocking functions
    If $KeyDown Then
        ConsoleWrite('= was pressed' & @CRLF)
        Do
            ConsoleWrite('= is still pressed' & @CRLF)
            Sleep(10)
        Until Not $KeyDown
        ConsoleWrite('= was released' & @CRLF)
    EndIf
    Sleep(10)
Until $bExit

; Unset the keyboard hook
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hKeyboardProc)

Func KeyboardProc($nCode, $wParam, $lParam)
    ; If nCode is less than zero just call the next hook procedure in the current hook chain
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    ; Create a structure that will contain info about the keyboard event
    ; (lParam it's the pointer to the KBDLLHOOKSTRUCT structure)
    Local $tKEYHOOKS = DllStructCreate('dword vkCode;dword scanCode;dword flags;dword time;ulong_ptr dwExtraInfo', $lParam)
    ; wParam contains the identifier of the keyboard message
    Switch $wParam
        Case $WM_KEYDOWN
            ; When = key it's pressed
            ; set $KeyDown to true, so you don't have to process anything else in the callback function
            If $tKEYHOOKS.vkCode = 0xBB Then
                $KeyDown = True
                ; Return nonzero value to prevent the system from passing the 
                ; message to the rest of the hook chain or the target window procedure
                Return 1
            EndIf
        Case $WM_KEYUP
            ; When = key it's released
            ; set $KeyDown to false, so you don't have to process anything else in the callback function
            If $tKEYHOOKS.vkCode = 0xBB Then
                $KeyDown = False
                ; Return nonzero value to prevent the system from passing the 
                ; message to the rest of the hook chain or the target window procedure
                Return 1
            EndIf
    EndSwitch
    ; Call the next hook procedure in the current hook chain
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc

Func Quit()
    $bExit = True
EndFunc

You can read all this stuff in more details here, here and here.

Edited by Andreik

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
×
×
  • Create New...