Jump to content

Recommended Posts

Posted

I'm using 

Here is the bare minimum example:

#Include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>

Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("_exit")

Global Const $HKM_GETHOTKEY = $WM_USER + 2

global $hGui = GUICreate("test", 220, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "onClose")

global $hInput = _WinAPI_CreateWindowEx (0, "msctls_hotkey32", "", BitOR($WS_CHILD, $WS_VISIBLE), 10, 10, 200, 24, $hGui)
GUISetState()

While 1
    Sleep(10)
WEnd

func onChange()
    ConsoleWrite("onChange " & SendMessage($hInput, $HKM_GETHOTKEY) & @CRLF)
EndFunc

func onClose()
    exit
EndFunc

Func _exit()
    _WinAPI_DestroyWindow($hInput)
EndFunc

Func SendMessage($hWnd, $Msg, $wParam = 0, $lParam = 0)
    Return DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hWnd, 'int', $Msg, 'int', $wParam, 'int', $lParam)[0]
EndFunc   ;==>SendMessage

How to fire onChange() function when the hotkey box changed value?

Posted

One of the method is to use WM_COMMAND:

#Include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>

Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("_exit")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")


Global Const $HKM_GETHOTKEY = $WM_USER + 2

global $hGui = GUICreate("test", 220, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "onClose")

global $hInput = _WinAPI_CreateWindowEx (0, "msctls_hotkey32", "", BitOR($WS_CHILD, $WS_VISIBLE), 10, 10, 200, 24, $hGui)
GUISetState()

While 1
    Sleep(10)
WEnd

func onChange()
    ConsoleWrite("onChange: " & SendMessage($hInput, $HKM_GETHOTKEY) & @CRLF)
EndFunc

func onClose()
    exit
EndFunc

Func _exit()
    _WinAPI_DestroyWindow($hInput)
EndFunc

Func SendMessage($hWnd, $Msg, $wParam = 0, $lParam = 0)
    Return DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hWnd, 'int', $Msg, 'int', $wParam, 'int', $lParam)[0]
EndFunc

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Switch $lParam
        Case $hInput
            onChange();
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

It works, but it fires onChange when a key pressed, not when value is "accepted". For example when you press and release SHIFT, it fires twice, because it doesn't "accept" just modifier keys.

So I'm trying fire onChange only when user released all keys and input field changed

Posted

What about following

Global Const $HKM_GETHOTKEY = $WM_USER + 2
Global Const $HOTKEYF_SHIFT=0x01;https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-sethotkey
....
func onChange()
    $key=SendMessage($hInput, $HKM_GETHOTKEY)
    ConsoleWrite("onChange: " & $key & @CRLF)
    $loword=_WinAPI_LoWord($key)
    $lobyte=_WinAPI_LoByte($loword)
    $hibyte=_WinAPI_HiByte($loword)
    ConsoleWrite("LOBYTE=" & $lobyte & @CRLF)
    ConsoleWrite("HIBYTE=" & $hibyte & @CRLF)
    If ($lobyte<>0 And $hibyte=$HOTKEYF_SHIFT) Then
        ConsoleWrite("hotkey changed" & @CRLF)
    EndIf
EndFunc

HKM_GETHOTKEY has valuable information about how to get what keys are pressed. If you need further help feel free to ask.

Posted

Thank you.

This sure will help, but since it's being fired while user still holding the keys pressed, it's hard to "sanitize" the value (aka for example reset the field to default on certain combinations)

Posted

It should be possible to look for specific key combinations (using BitAnd on HiByte and LoByte) in onChnage function and if you encounter them then reset the input. You will have to find a way to reset hot key control programatically.

Posted

I know how to sanitize and change the value, what I don't know is how to detect when all the keys were released

I don't want to reset the field while user is still holding keys down.

For example SHIFT+F is invalid combination, but CTRL+SHIFT+F is valid, so I don't want reset it while user is still holding SHIFT+F before they have a chance press CTRL.

Posted

What about this

Global Const $HKM_SETHOTKEY = $WM_USER + 1
Global Const $HKM_GETHOTKEY = $WM_USER + 2
Global Const $HOTKEYF_SHIFT=0x01, $HOTKEYF_CONTROL=0x02, $HOTKEYF_ALT=0x04;https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-sethotkey
Global $KeyPressed
...
func onChange()
    $key=SendMessage($hInput, $HKM_GETHOTKEY)
    ConsoleWrite("onChange: " & $key & @CRLF)
    $loword=_WinAPI_LoWord($key)
    $lobyte=_WinAPI_LoByte($loword);key
    $hibyte=_WinAPI_HiByte($loword);modifier key
    ConsoleWrite("LOBYTE=" & $lobyte & @CRLF)
    ConsoleWrite("HIBYTE=" & $hibyte & @CRLF)
    If ($lobyte<>0 And BitAND($hibyte,$HOTKEYF_SHIFT)=$HOTKEYF_SHIFT And BitAND($hibyte,$HOTKEYF_CONTROL)=$HOTKEYF_CONTROL ) Then
        ConsoleWrite("hotkey changed" & @CRLF)
    ElseIf ($KeyPressed<>0 And (BitAND($hibyte,$HOTKEYF_SHIFT)=$HOTKEYF_SHIFT Or BitAND($hibyte,$HOTKEYF_CONTROL)=$HOTKEYF_CONTROL)) Then ;any key with shift or control pressed
        ConsoleWrite("!Key with either shift or ctrl" & @CRLF)
        $KeyCombo=_WinAPI_MakeWord($KeyPressed,$hibyte);key, modifier key
        $KeyCombo2=_WinAPI_MakeLong($KeyCombo,0)
        SendMessage($hInput, $HKM_SETHOTKEY, $KeyCombo2, 0)
    ElseIf $lobyte<>0 Then
        ConsoleWrite("+LoByte<>0" & @CRLF)
        $KeyPressed=$lobyte
    EndIf
EndFunc

This is still not working, but the idea is to check if there is a key pressed alongside CTRL or SHIFT. If there is store it to $KeyPressed variable. Then if user presses one of the other keys, CTRL or SHIFT, add that key to the combo. I can not test any more as I am going to bed.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...