HotKeyInput UDF

44 posts in this topic

Posted (edited)

LAST VERSION - 1.3

28-Oct-11

The library allows to create HotKey Input control by using the low-level keyboard hook. This UDF is designed specially to support the >HotKey UDF library but it can be used separately. Please look at the example below to understand how it works. For more information, see detailed descriptions of all functions inside the library.

HotKeyInput.png

Available functions

_GUICtrlHKI_Create

_GUICtrlHKI_Destroy

_GUICtrlHKI_GetHotKey

_GUICtrlHKI_SetHotKey

_GUICtrlHKI_Release

_KeyLock

_KeyUnlock

_KeyLoadName

_KeyToStr

HotKeyInput UDF Library v1.3

Previous downloads: 2564

HotKeyInput.au3

Example

#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>

Global $Form, $HKI1, $HKI2, $Button, $Text

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HKI1 = _GUICtrlHKI_Create(0, 56, 55, 230, 20)
$HKI2 = _GUICtrlHKI_Create(0, 56, 89, 230, 20)

; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows
_KeyLock(0x062E)

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$Button = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            $Text = 'Hotkey1: 0x' & StringRight(Hex(_GUICtrlHKI_GetHotKey($HKI1)), 4) & ' (' & GUICtrlRead($HKI1) & ')' & @CR & @CR & _
                    'Hotkey2: 0x' & StringRight(Hex(_GUICtrlHKI_GetHotKey($HKI2)), 4) & ' (' & GUICtrlRead($HKI2) & ')'
            MsgBox(0, 'Code', $Text, 0, $Form)
    EndSwitch
WEnd
Edited by Yashied
2 people like this

Share this post


Link to post
Share on other sites



Posted (edited)

Very nice, but I noticed a little 'bug'.

If you run the example, and you press "CTRL + ALT + SHIFT" (CAS) and then "D" key, it writes "CAS - D". It works as it is supposed to.

But if you press CAS+D, release D and A, and again press D it writes "CAS - D", but you didn't pressed A. Same with S.

Cheers!

Edited by Izebize

Share this post


Link to post
Share on other sites

Posted

Very nice, but I noticed a little 'bug'.

If you run the example, and you press "CTRL + ALT + SHIFT" (CAS) and then "D" key, it writes "CAS - D". It works as it is supposed to.

But if you press CAS+D, release D and A, and again press D it writes "CAS - D", but you didn't pressed A. Same with S.

Cheers!

Thank you for your reply.

This is not a bug. HotKey combination fixed after pressing function key ("D"). To clear it is necessary to release all the keys have been pressed ("CAS"). I did it for safe use.

:P

Share this post


Link to post
Share on other sites

Posted

This library has been updated.

:D

Share this post


Link to post
Share on other sites

Posted

Great work Yashied I have learned allot from reading this script.

Thanks,

Share this post


Link to post
Share on other sites

Posted

Great work Yashied I have learned allot from reading this script.

Thanks,

Thanks.

^_^

Share this post


Link to post
Share on other sites

Posted (edited)

i cant figure out how to then set a hotkey after gathering the user input ? tried :-

$x=_GUICtrlReadHotKeyInput($HotkeyInput1)

HotKeySet($x,"test")

also

$x=Hex(_GUICtrlReadHotKeyInput($HotkeyInput1))

HotKeySet($x,"test")

also

$x='0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4)

HotKeySet($x,"test")

sorry for my lack of understanding of what _GUICtrlReadHotKeyInput($HotkeyInput1) returns and how to use it.

Edited by JackDinn

Share this post


Link to post
Share on other sites

Posted (edited)

i cant figure out how to then set a hotkey after gathering the user input ? tried :-

$x=_GUICtrlReadHotKeyInput($HotkeyInput1)

HotKeySet($x,"test")

also

$x=Hex(_GUICtrlReadHotKeyInput($HotkeyInput1))

HotKeySet($x,"test")

also

$x='0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4)

HotKeySet($x,"test")

sorry for my lack of understanding of what _GUICtrlReadHotKeyInput($HotkeyInput1) returns and how to use it.

Use HotKey.au3. Using this library can be set any hotkeys, including the F12, CTRL-ALT-DEL, etc.

$x=_GUICtrlReadHotKeyInput($HotkeyInput1)
_HotKeyAssign($x, "test", $HK_FLAG_NOREPEAT)

EDIT:

_GUICtrlReadHotKeyInput() returns the combined 16-bit hotkey code, which consists of upper and lower bytes.

Hotkey code bits:

0-7 - Specifies the virtual-key (VK) code of the key. Codes for the mouse buttons (0x01 - 0x06) are not supported. For more information see this.

8 - SHIFT key

9 - CONTROL key

10 - ALT key

11 - WIN key

12-15 - Don`t used

Edited by Yashied

Share this post


Link to post
Share on other sites

Posted (edited)

ahh, there's more :)

btw you really know your stuff nice func's

thx,

Edited by JackDinn

Share this post


Link to post
Share on other sites

Posted (edited)

If you want to use HotKeySet(), it is not difficult to write a function to convert the hot keys. It will look like this:

Func _HotKeyConvert($iKey)

    Local $sKey = ""

    If BitAND($iKey, 0x0100) Then $sKey &= "+"
    If BitAND($iKey, 0x0200) Then $sKey &= "^"
    If BitAND($iKey, 0x0400) Then $sRet &= "!"
    If BitAND($iKey, 0x0800) Then $sRet &= "#"
    Switch BitAND($iKey, 0x00FF)
        Case 0x08
            $sKey &= "{BACKSPACE}"
        Case 0x09
            $sKey &= "{TAB}"
            
        ...
            
    EndSwitch
    Return $sKey
EndFunc   ;==>_HotKeyConvert
Edited by Yashied

Share this post


Link to post
Share on other sites

Posted

aye i had started picking apart the return from _KeyToStr() and doing much what your doing there (but not as clean) but i was sure there was an easer way to do it.

much thx for your work.

Share this post


Link to post
Share on other sites

Posted

awesome work, yashied!

I'm still way too green to understand much of any of it, but it works pretty great.

but I noticed that 'backspace' and '-' don't register for me within the control. Another thing I was curious about was the approach to numlock. It looks like windows is still storing the state of numlock when it's pressed in the control. The light is correct on the keyboard itself, and it seems windows knows the state because if you hit numlock again it's on the correct mode, but it looks like it accidentally popped into the wrong mode.

anyway, thought I'd ask :D

Share this post


Link to post
Share on other sites

Posted

awesome work, yashied!

I'm still way too green to understand much of any of it, but it works pretty great.

Thanks.

but I noticed that 'backspace' and '-' don't register for me within the control.

Single "Backspace" You can not assign a hot key, it is used to clear the input fields (like the "Esc"). "-" - this is an error in the _KeyToStr() function. Fixed.

Another thing I was curious about was the approach to numlock. It looks like windows is still storing the state of numlock when it's pressed in the control. The light is correct on the keyboard itself, and it seems windows knows the state because if you hit numlock again it's on the correct mode, but it looks like it accidentally popped into the wrong mode.

Indeed, a strange effect. It looks like in Windows you can not completely lock the "Num Lock". The only thing I can suggest at this point - use _KeyLock() to add "Num Lock" in the prohibited list of hot keys.

_KeyLock(0x0090)

Share this post


Link to post
Share on other sites

Posted

Hi,

Can I get the hotkey code on change?

I use the code below, and it gets the hotkey text correctly, but the key code seems to be previous one.

#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>

Global Const $EN_CHANGE = 0x300
Global $Form, $ButtonOk, $HotkeyInput1, $HotkeyInput2, $GUIMsg
Global $t

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HotkeyInput1 = _GUICtrlCreateHotKeyInput(0, 56, 55, 230, 20, -1, -1, ' - ')
$HotkeyInput2 = _GUICtrlCreateHotKeyInput(0, 56, 89, 230, 20)

$InputHotkeyKey = $HotkeyInput1

_KeyLock(0x062E) ; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$ButtonOk = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()

While 1
    $GUIMsg = GUIGetMsg()

    Select
        Case $GUIMsg = $GUI_EVENT_CLOSE
            Exit
        Case $GUIMsg = $ButtonOk
            $t = '   Hotkey1:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4) & '  (' & GUICtrlRead($HotkeyInput1) & ')   ' & @CR & @CR & _
                 '   Hotkey2:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput2)), 4) & '  (' & GUICtrlRead($HotkeyInput2) & ')   '
            MsgBox(0, 'Code', $t, 0, $Form)
    EndSelect
WEnd

Func InputHotkeyChange($iInput)
    tooltip(GUICtrlRead($InputHotkeyKey)&@LF&_GUICtrlReadHotKeyInput($InputHotkeyKey))
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iCode = _WinAPI_HiWord($wParam)
    Local $iID = _WinAPI_LoWord($wParam)
    Local $hCtrl = $lParam
    if $iCode = $EN_CHANGE then
        Switch $iID
            Case $InputHotkeyKey
                InputHotkeyChange($iID)
        EndSwitch
    endif
    return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Posted

Hi,

Can I get the hotkey code on change?

I use the code below, and it gets the hotkey text correctly, but the key code seems to be previous one.

#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>

Global Const $EN_CHANGE = 0x300
Global $Form, $ButtonOk, $HotkeyInput1, $HotkeyInput2, $GUIMsg
Global $t

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HotkeyInput1 = _GUICtrlCreateHotKeyInput(0, 56, 55, 230, 20, -1, -1, ' - ')
$HotkeyInput2 = _GUICtrlCreateHotKeyInput(0, 56, 89, 230, 20)

$InputHotkeyKey = $HotkeyInput1

_KeyLock(0x062E) ; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$ButtonOk = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()

While 1
    $GUIMsg = GUIGetMsg()

    Select
        Case $GUIMsg = $GUI_EVENT_CLOSE
            Exit
        Case $GUIMsg = $ButtonOk
            $t = '   Hotkey1:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4) & '  (' & GUICtrlRead($HotkeyInput1) & ')   ' & @CR & @CR & _
                 '   Hotkey2:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput2)), 4) & '  (' & GUICtrlRead($HotkeyInput2) & ')   '
            MsgBox(0, 'Code', $t, 0, $Form)
    EndSelect
WEnd

Func InputHotkeyChange($iInput)
    tooltip(GUICtrlRead($InputHotkeyKey)&@LF&_GUICtrlReadHotKeyInput($InputHotkeyKey))
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iCode = _WinAPI_HiWord($wParam)
    Local $iID = _WinAPI_LoWord($wParam)
    Local $hCtrl = $lParam
    if $iCode = $EN_CHANGE then
        Switch $iID
            Case $InputHotkeyKey
                InputHotkeyChange($iID)
        EndSwitch
    endif
    return $GUI_RUNDEFMSG
EndFunc

#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>

Global Const $EN_CHANGE = 0x300
Global $Form, $ButtonOk, $Dummy, $HotkeyInput1, $HotkeyInput2, $GUIMsg
Global $t

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HotkeyInput1 = _GUICtrlCreateHotKeyInput(0, 56, 55, 230, 20, -1, -1, ' - ')
$HotkeyInput2 = _GUICtrlCreateHotKeyInput(0, 56, 89, 230, 20)

$InputHotkeyKey = $HotkeyInput1

_KeyLock(0x062E) ; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$ButtonOk = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
$Dummy = GUICtrlCreateDummy()
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()

While 1
    $GUIMsg = GUIGetMsg()

    Select
        Case $GUIMsg = $GUI_EVENT_CLOSE
            Exit
        Case $GUIMsg = $ButtonOk
            $t = '   Hotkey1:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4) & '  (' & GUICtrlRead($HotkeyInput1) & ')   ' & @CR & @CR & _
                    '   Hotkey2:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput2)), 4) & '  (' & GUICtrlRead($HotkeyInput2) & ')   '
            MsgBox(0, 'Code', $t, 0, $Form)
        Case $Dummy
            InputHotkeyChange(GUICtrlRead($Dummy))
    EndSelect
WEnd

Func InputHotkeyChange($iInput)
    ToolTip(GUICtrlRead($InputHotkeyKey) & @LF & _GUICtrlReadHotKeyInput($InputHotkeyKey))
EndFunc   ;==>InputHotkeyChange

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iCode = _WinAPI_HiWord($wParam)
    Local $iID = _WinAPI_LoWord($wParam)
    Local $hCtrl = $lParam
    If $iCode = $EN_CHANGE Then
        Switch $iID
            Case $InputHotkeyKey
                GUICtrlSendToDummy($Dummy, $iID)
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Share this post


Link to post
Share on other sites

Posted

Thanks, it works!

But when I use OnEvent mode it does not work.

Sorry I should ask for OnEvent mode at the first time.

Thanks again!

#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>
Opt("GUIOnEventMode", 1)

Global Const $EN_CHANGE = 0x300
Global $Form, $ButtonOk, $Dummy, $HotkeyInput1, $HotkeyInput2, $GUIMsg
Global $t

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HotkeyInput1 = _GUICtrlCreateHotKeyInput(0, 56, 55, 230, 20, -1, -1, ' - ')
$HotkeyInput2 = _GUICtrlCreateHotKeyInput(0, 56, 89, 230, 20)

$InputHotkeyKey = $HotkeyInput1

_KeyLock(0x062E) ; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$ButtonOk = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
$Dummy = GUICtrlCreateDummy()
GUICtrlSetOnEvent($Dummy, "DummyEvent")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()

While 1
    Sleep(10)
WEnd

Func DummyEvent()
    InputHotkeyChange(GUICtrlRead($Dummy))
EndFunc

Func InputHotkeyChange($iInput)
    ToolTip(GUICtrlRead($InputHotkeyKey) & @LF & _GUICtrlReadHotKeyInput($InputHotkeyKey))
EndFunc   ;==>InputHotkeyChange

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iCode = _WinAPI_HiWord($wParam)
    Local $iID = _WinAPI_LoWord($wParam)
    Local $hCtrl = $lParam
    If $iCode = $EN_CHANGE Then
        Switch $iID
            Case $InputHotkeyKey
                GUICtrlSendToDummy($Dummy, $iID)
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Share this post


Link to post
Share on other sites

Posted

OK!

Replace the following part of code in the HotKeyInput.au3

If $VK[$vkCode] > '' Then
    $Key = BitOR(BitShift($hkId[0][3], -8), $vkCode)
    If Not _HotKeyInput_Lock($Key) Then
        GUICtrlSetData($hkId[$Index][0], _KeyToStr($Key, $hkId[$Index][3]))
        $hkId[$Index][2] = $Key
        $hkId[0][7] = 1
        $hkId[0][8] = 1
    Else
        $Return = 0
    EndIf
EndIf

to

If $VK[$vkCode] > '' Then
    $Key = BitOR(BitShift($hkId[0][3], -8), $vkCode)
    If Not _HotKeyInput_Lock($Key) Then
        $hkId[$Index][2] = $Key
        GUICtrlSetData($hkId[$Index][0], _KeyToStr($Key, $hkId[$Index][3]))
        $hkId[0][7] = 1
        $hkId[0][8] = 1
    Else
        $Return = 0
    EndIf
EndIf

Share this post


Link to post
Share on other sites

Posted

OK!

Replace the following part of code in the HotKeyInput.au3

Great!

I don't even need the dummy control.

Thanks.:D

Share this post


Link to post
Share on other sites

Posted

The UDF doesn't work on my AutoIt version :( Can you update it?

Share this post


Link to post
Share on other sites

Posted

And what is the reason?

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

  • Recently Browsing   0 members

    No registered users viewing this page.