Jump to content

Recommended Posts

Posted (edited)

image.png.067e8d40443028ce06e29203f959e03f.png

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <SendMessage.au3>
#include <WinAPIsys.au3>
#include <WindowsClassConstants.au3>

Global Const $HKM_GETHOTKEY = 0x0402

Exit _example()
Func _example()

    Local $hGUI = GUICreate("Hotkey control example", 380, 180, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))
    GUICtrlCreateLabel("Type your shortcut (e.g., Ctrl+W, Ctrl+Shift+Alt+K):", 20, 20, 340, 25)
    Local $hWndHotkey = _WinAPI_CreateWindowEx(0, $WC_HOTKEY, "", BitOR($WS_CHILD, $WS_VISIBLE), 20, 55, 200, 22, $hGUI)
    Local $idBtnApply = GUICtrlCreateButton("Apply Hotkey", 245, 54, 110, 24)
    Local $idChkPowerUser = GUICtrlCreateCheckbox("Power User Mode (Disable Warning Dialogs)", 20, 95, 340, 20)
    GUICtrlCreateLabel("---------------------------------------------------------------------------------", 20, 125, 340, 15)
    Local $idLblStatus = GUICtrlCreateLabel("Active Hotkey Hook: None", 20, 145, 340, 20)
    GUICtrlSetFont($idLblStatus, 10, 800)
    GUISetState(@SW_SHOW, $hGUI)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete()
                ExitLoop

            Case $idBtnApply
                Local $bPowerModeActive = (GUICtrlRead($idChkPowerUser) = $GUI_CHECKED)
                _SetNewHotkey($hWndHotkey, $idLblStatus, $bPowerModeActive, $hGUI)

        EndSwitch
    WEnd
EndFunc   ;==>_example

Func _SetNewHotkey($hWndCtrl, $idStatusLabel, $bPowerMode, $hGUI)
    Local Static $sCurrentHotkey = ""
    Local $iHotkeyData = _SendMessage($hWndCtrl, $HKM_GETHOTKEY, 0, 0)
    Local $iKey = BitAND($iHotkeyData, 0xFF)
    Local $iModifiers = BitShift($iHotkeyData, 8)
    ConsoleWrite('-        $iKey = "0x' & Hex($iKey, 2) & '" (' & $iKey & ')' & @CRLF)
    ConsoleWrite('-  $iModifiers = "' & $iModifiers & '"' & @CRLF)

    If $iKey = 0 Then
        If $sCurrentHotkey <> "" Then
            HotKeySet($sCurrentHotkey)
            $sCurrentHotkey = ""
        EndIf
        GUICtrlSetData($idStatusLabel, "Active Hotkey Hook: None")
        MsgBox($MB_ICONINFORMATION, "Cleared", "Hotkey removed successfully.", 120, $hGUI)
        Return
    EndIf

    Local $iWin32Mod = 0
    If BitAND($iModifiers, 1) Then $iWin32Mod += 1 ; Shift
    If BitAND($iModifiers, 2) Then $iWin32Mod += 2 ; Ctrl
    If BitAND($iModifiers, 4) Then $iWin32Mod += 4 ; Alt

    Local $bOsCheck = _WinAPI_RegisterHotKey(0, 999, $iWin32Mod, $iKey)
    If $bOsCheck Then
        _WinAPI_UnregisterHotKey(0, 999)
    Else
        MsgBox($MB_ICONERROR, "OS Hardware Blocked!", _
                "The Windows OS kernel has permanently locked this specific key combination." & _
                " It is fundamentally impossible to register.", 120, $hGUI)
        Return
    EndIf

    If Not $bPowerMode Then
        Local $bIsRisky = False
        Local $sReason = ""

        If ($iModifiers = 2) Then ; just Control Combo
            Switch $iKey
                Case 0x43 ; C
                    $bIsRisky = True
                    $sReason = "Global Copy Clipboard Command"
                Case 0x56 ; V
                    $bIsRisky = True
                    $sReason = "Global Paste Clipboard Command"
                Case 0x58 ; X
                    $bIsRisky = True
                    $sReason = "Global Cut Clipboard Command"
                Case 0x57 ; W
                    $bIsRisky = True
                    $sReason = "Standard Browser Window/Tab Close Utility"
            EndSwitch
        EndIf

        ; Catch single keys that have no modifiers (like standalone F1-F12 keys)
        If Not $iModifiers Then
            $bIsRisky = True
            If $iKey >= 112 And $iKey <= 123 Then
                $sReason = "Standalone Functional F" & ($iKey - 111) & " Key"
            Else
                $sReason = "Just a key without modifiers"
            EndIf
        EndIf

        If $bIsRisky Then
            Local $iChoice = MsgBox(BitOR($MB_YESNO, $MB_ICONWARNING, $MB_DEFBUTTON2, $MB_TOPMOST), "Warning: Overriding System Shortcut", _
                    "The shortcut you entered is typically mapped to: [" & $sReason & "]." & @CRLF & @CRLF & _
                    "Activating it globally will break its usage in other programs!" & @CRLF & @CRLF & _
                    "Do you want to override this safety constraint?", 120, $hGUI)

            If $iChoice <> $IDYES Then Return
        EndIf
    EndIf

    Local $sAutoItKeyString = ""
    If BitAND($iModifiers, 1) Then $sAutoItKeyString &= "+"
    If BitAND($iModifiers, 2) Then $sAutoItKeyString &= "^"
    If BitAND($iModifiers, 4) Then $sAutoItKeyString &= "!"

    Switch $iKey
        Case 112 To 123 ; F1 to F12
            $sAutoItKeyString &= "{F" & ($iKey - 111) & "}"
        Case 8 ; Backspace
            $sAutoItKeyString &= "{BACKSPACE}"
        Case 9 ; Tab
            $sAutoItKeyString &= "{TAB}"
        Case 13 ; Enter
            $sAutoItKeyString &= "{ENTER}"
        Case 19 ; Pause
            $sAutoItKeyString &= "{PAUSE}"
        Case 20 ; Caps Lock
            $sAutoItKeyString &= "{CAPSLOCK}"
        Case 27 ; Escape
            $sAutoItKeyString &= "{ESC}"
        Case 32 ; Spacebar
            $sAutoItKeyString &= "{SPACE}"
        Case 33 To 40 ; Navigation block (PGUP, PGDN, END, HOME, LEFT, UP, RIGHT, DOWN)
            Local $aNav = ["PGUP", "PGDN", "END", "HOME", "LEFT", "UP", "RIGHT", "DOWN"]
            $sAutoItKeyString &= "{" & $aNav[$iKey - 33] & "}"
        Case 45 ; Insert
            $sAutoItKeyString &= "{INSERT}"
        Case 46 ; Delete
            $sAutoItKeyString &= "{DEL}"
        Case 96 To 105 ; Numpad 0 to 9
            $sAutoItKeyString &= "{NUMPAD" & ($iKey - 96) & "}"
        Case 106 To 111 ; Numpad Operators (*, +, Separator, -, ., /)
            Local $aOps = ["NUMPADMULT", "NUMPADADD", "", "NUMPADSUB", "NUMPADDOT", "NUMPADDIV"]
            $sAutoItKeyString &= "{" & $aOps[$iKey - 106] & "}"
        Case 144 ; Num Lock
            $sAutoItKeyString &= "{NUMLOCK}"
        Case 145 ; Scroll Lock
            $sAutoItKeyString &= "{SCROLLLOCK}"

        ; ⚠️ OEM Symbol Mappings for standard hardware layouts ⚠️
        Case 0xBA ; Semicolon / Plus key (; :)
            $sAutoItKeyString &= ";"
        Case 0xBB ; Plus key (= +)
            $sAutoItKeyString &= "="
        Case 0xBC ; Comma key (, <)
            $sAutoItKeyString &= ","
        Case 0xBD ; Minus key (- _)
            $sAutoItKeyString &= "-"
        Case 0xBE ; Period key (. >)
            $sAutoItKeyString &= "."
        Case 0xBF ; Slash key (/ ?)
            $sAutoItKeyString &= "/"
        Case 0xC0 ; Tilde key (` ~)
            $sAutoItKeyString &= "`"
        Case 0xDB ; Open Bracket key ([ {)
            $sAutoItKeyString &= "["
        Case 0xDC ; Backslash key (\ |)
            $sAutoItKeyString &= "\"
        Case 0xDD ; Close Bracket key (] })
            $sAutoItKeyString &= "]"
        Case 0xDE ; Quote key (' ")
            $sAutoItKeyString &= "'"

        Case Else
            $sAutoItKeyString &= StringLower(Chr($iKey))
    EndSwitch

    ConsoleWrite('- "' & $sAutoItKeyString & '"' & @CRLF)

    If $sCurrentHotkey <> "" Then HotKeySet($sCurrentHotkey)

    If HotKeySet($sAutoItKeyString, "_MyCustomAction") Then
        $sCurrentHotkey = $sAutoItKeyString
        GUICtrlSetData($idStatusLabel, "Active Hotkey Hook: " & $sAutoItKeyString)
        MsgBox(BitOR($MB_ICONINFORMATION, $MB_TOPMOST), "Success", "Registered: " & $sAutoItKeyString, 120, $hGUI)
    Else
        $sCurrentHotkey = ""
        GUICtrlSetData($idStatusLabel, "Active Hotkey Hook: None")
        MsgBox(BitOR($MB_ICONERROR, $MB_TOPMOST), "Hotkey Registration Blocked!", _
                "Registration Failed! Another active background application or game has already claimed the [" & $sAutoItKeyString & "] shortcut.", 120, $hGUI)
    EndIf

EndFunc   ;==>_SetNewHotkey

Func _MyCustomAction()
    MsgBox(BitOR($MB_ICONINFORMATION, $MB_TOPMOST), "Action Successful", "Macro combination intercepted and running your function", 2)
EndFunc   ;==>_MyCustomAction

..will not give you the commonly used "{ESC}" and some other keys, but we have the $WC_HOTKEY in WindowsClassConstants.au3 and no example on to how to use it. At least none that I found.

Edit: it seems that I didn't search good enough ( /topic/96492-hotkey-control-udf-msctls_hotkey32/ , /forum/topic/176502-hot-key-control/ , etc. ) 😅

 

Edited by argumentum

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

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