Jump to content

How to get onChange event for control created by _WinAPI_CreateWindowEx()?


VAN0
 Share

Recommended Posts

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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

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...