HotKey System(Windows only)

Share your advanced PureBasic knowledge/code with the community.
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

HotKey System(Windows only)

Post by blueb »

Been working and adding to this, because I needed it for a program that I'm working on.. I think it's fairly complete.
Have a look, perhaps I missed some things.

Code: Select all

; =================================================================
;     File Name:    HotKeyExecutor.pbi
;   Description:    Universal Hotkey Execution Include for PureBasic
;        Author:    Blueb
;          Date:    June 19, 2025
;    PB-Version:    Tested with 6.21(x64) and Windows 11 Pro x64
; Typical Usage:
;        
; =================================================================
; Features:
;   - Execute keyboard shortcuts programmatically
;   - Supports all standard keys, media keys, and special keys
;   - Differentiates between left/right modifier keys
;   - Built-in intelligent delay system for reliability
;   - Easy integration into any project
; Usage:
;   1. XIncludeFile "HotkeyExecutor.pbi" with your program
;   2. Call ExecuteHotkey("Your+Shortcut") to trigger hotkeys
;   3. Use HandleCommand(2, "Your+Shortcut") from inside your program
; ============================================================
; How to use....
;[ Basic Integration ]
; XIncludeFile "HotkeyExecutor.pbi"
; 
; ; Execute a shortcut
; ExecuteHotkey("Win+E") ; Open File Explorer
; -------------------------------------------------------

;[ Inside You Program ]
; XIncludeFile "HotkeyExecutor.pbi"
; 
; ; Handle user command
; HandleCommand(2, "Ctrl+Shift+Esc") ; Open Task Manager
; -------------------------------------------------------

;[ Specialized Shortcuts ]
; ; Left Windows key combinations
; ExecuteHotkey("LWin+Tab") ; Task View
; 
; ; Media controls
; ExecuteHotkey("VOLUME_UP")
; 
; ; Right Alt (AltGr) for special characters
; ExecuteHotkey("RAlt+E") ; Euro symbol on some layouts
; -------------------------------------------------------

;-----[ Performance Tips: ]-----
;
;     1. Delay Constants:
;           - Adjust #KEY_EVENT_DELAY if needed (15ms works well for most systems)
;           - Increase #MIN_MAIN_KEY_HOLD if keys aren't registering
;     2. Debugging:
;           - Use the built-in self-test (run as main file)
;           - Check debug output for parsing errors
;           - Reduce delays temporarily for testing
;     3. Special Cases:
;           - For extremely fast execution needs, you can reduce delays
;           - For problematic applications, increase the main key hold time
;
; This IncludeFile seeks to be a universal solution for any PureBasic project. 
; The intelligent delay system eliminates the need for manual delays in most cases, while 
; still providing reliable execution across different systems and applications. The code 
; is optimized, well-structured, and ready for production use.
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

; Structure to hold hotkey information
Structure HotKeyStruct
  mainKey.i
  List Modifiers.i()
EndStructure

; =====================================================
; Virtual Key Constants for Windows API
; =====================================================

; Mouse buttons (not typically used with keyboard events)
;#VK_LBUTTON = $01
;#VK_RBUTTON = $02
;#VK_MBUTTON = $04
;#VK_XBUTTON1 = $05
;#VK_XBUTTON2 = $06

; Standard keys
#VK_BACK = $08
#VK_TAB = $09
#VK_CLEAR = $0C
#VK_RETURN = $0D
#VK_SHIFT = $10
#VK_CONTROL = $11
#VK_MENU = $12      ; ALT key
#VK_PAUSE = $13
#VK_CAPITAL = $14   ; CAPS LOCK

; IME keys
#VK_KANA = $15
#VK_HANGUL = $15    ; Old name for KANA
#VK_JUNJA = $17
#VK_FINAL = $18
#VK_HANJA = $19
#VK_KANJI = $19

; ESC key
#VK_ESCAPE = $1B

; IME mode keys
#VK_CONVERT = $1C
#VK_NONCONVERT = $1D
#VK_ACCEPT = $1E
#VK_MODECHANGE = $1F

; Spacebar
#VK_SPACE = $20

; Navigation keys
#VK_PRIOR = $21     ; PAGE UP
#VK_NEXT = $22      ; PAGE DOWN
#VK_END = $23
#VK_HOME = $24
#VK_LEFT = $25
#VK_UP = $26
#VK_RIGHT = $27
#VK_DOWN = $28
#VK_SELECT = $29
#VK_PRINT = $2A
#VK_EXECUTE = $2B
#VK_SNAPSHOT = $2C  ; PRINT SCREEN
#VK_INSERT = $2D
#VK_DELETE = $2E
#VK_HELP = $2F

; Regular Number keys (0-9)
#VK_0 = $30
#VK_1 = $31
#VK_2 = $32
#VK_3 = $33
#VK_4 = $34
#VK_5 = $35
#VK_6 = $36
#VK_7 = $37
#VK_8 = $38
#VK_9 = $39

; Letter keys (A-Z)
#VK_A = $41
#VK_B = $42
#VK_C = $43
#VK_D = $44
#VK_E = $45
#VK_F = $46
#VK_G = $47
#VK_H = $48
#VK_I = $49
#VK_J = $4A
#VK_K = $4B
#VK_L = $4C
#VK_M = $4D
#VK_N = $4E
#VK_O = $4F
#VK_P = $50
#VK_Q = $51
#VK_R = $52
#VK_S = $53
#VK_T = $54
#VK_U = $55
#VK_V = $56
#VK_W = $57
#VK_X = $58
#VK_Y = $59
#VK_Z = $5A

; Windows keys
#VK_LWIN = $5B
#VK_RWIN = $5C
#VK_APPS = $5D      ; Application key (context menu)

; System power keys
#VK_SLEEP = $5F

; Numpad keys
#VK_NUMPAD0 = $60
#VK_NUMPAD1 = $61
#VK_NUMPAD2 = $62
#VK_NUMPAD3 = $63
#VK_NUMPAD4 = $64
#VK_NUMPAD5 = $65
#VK_NUMPAD6 = $66
#VK_NUMPAD7 = $67
#VK_NUMPAD8 = $68
#VK_NUMPAD9 = $69
#VK_MULTIPLY = $6A
#VK_ADD = $6B
#VK_SEPARATOR = $6C
#VK_SUBTRACT = $6D
#VK_DECIMAL = $6E
#VK_DIVIDE = $6F

; Function keys
#VK_F1 = $70
#VK_F2 = $71
#VK_F3 = $72
#VK_F4 = $73
#VK_F5 = $74
#VK_F6 = $75
#VK_F7 = $76
#VK_F8 = $77
#VK_F9 = $78
#VK_F10 = $79
#VK_F11 = $7A
#VK_F12 = $7B
#VK_F13 = $7C
#VK_F14 = $7D
#VK_F15 = $7E
#VK_F16 = $7F
#VK_F17 = $80
#VK_F18 = $81
#VK_F19 = $82
#VK_F20 = $83
#VK_F21 = $84
#VK_F22 = $85
#VK_F23 = $86
#VK_F24 = $87

; Lock keys
#VK_NUMLOCK = $90
#VK_SCROLL = $91    ; SCROLL LOCK

; Modifier keys with left/right distinction
#VK_LSHIFT = $A0
#VK_RSHIFT = $A1
#VK_LCONTROL = $A2
#VK_RCONTROL = $A3
#VK_LMENU = $A4     ; Left ALT
#VK_RMENU = $A5     ; Right ALT (AltGr)

; Browser control keys
#VK_BROWSER_BACK = $A6
#VK_BROWSER_FORWARD = $A7
#VK_BROWSER_REFRESH = $A8
#VK_BROWSER_STOP = $A9
#VK_BROWSER_SEARCH = $AA
#VK_BROWSER_FAVORITES = $AB
#VK_BROWSER_HOME = $AC

; Volume control keys
#VK_VOLUME_MUTE = $AD
#VK_VOLUME_DOWN = $AE
#VK_VOLUME_UP = $AF

; Media control keys
#VK_MEDIA_NEXT_TRACK = $B0
#VK_MEDIA_PREV_TRACK = $B1
#VK_MEDIA_STOP = $B2
#VK_MEDIA_PLAY_PAUSE = $B3

; Application launch keys
#VK_LAUNCH_MAIL = $B4
#VK_LAUNCH_MEDIA_SELECT = $B5
#VK_LAUNCH_APP1 = $B6
#VK_LAUNCH_APP2 = $B7

; OEM keys (layout specific)
#VK_OEM_1 = $BA     ; ;: for US keyboard
#VK_OEM_PLUS = $BB  ; =+
#VK_OEM_COMMA = $BC ; ,<
#VK_OEM_MINUS = $BD ; -_
#VK_OEM_PERIOD = $BE ; .>
#VK_OEM_2 = $BF     ; /? for US keyboard
#VK_OEM_3 = $C0     ; `~ for US keyboard
#VK_OEM_4 = $DB     ; [{
#VK_OEM_5 = $DC     ; \|
#VK_OEM_6 = $DD     ; ]}
#VK_OEM_7 = $DE     ; '"
#VK_OEM_8 = $DF     ; Various
#VK_OEM_102 = $E2   ; <> or \| on RT 102-key keyboard

; IME keys
#VK_PROCESSKEY = $E5

; Special handling keys
#VK_PACKET = $E7    ; Used to pass Unicode characters

; Attn key
#VK_ATTN = $F6

; Cursor control keys
#VK_CRSEL = $F7
#VK_EXSEL = $F8

; Erase EOF key
#VK_EREOF = $F9

; Play key
#VK_PLAY = $FA

; Zoom key
#VK_ZOOM = $FB

; Reserved
#VK_NONAME = $FC

; PA1 key
#VK_PA1 = $FD

; Clear key
#VK_OEM_CLEAR = $FE

; Common aliases
#VK_ENTER = #VK_RETURN
;#VK_CANCEL = #VK_PAUSE       ; Pause/Break key
#VK_PRINTSCREEN = #VK_SNAPSHOT
#VK_ALT = #VK_MENU
#VK_RETURN = #VK_RETURN

; ; Virtual Key Constants
#VK_LSHIFT = $A0
#VK_RSHIFT = $A1
#VK_LCONTROL = $A2
#VK_RCONTROL = $A3
#VK_LMENU = $A4    ; Left Alt
#VK_RMENU = $A5    ; Right Alt
#VK_LWIN = $5B
#VK_RWIN = $5C
#VK_SNAPSHOT = $2C  ; Virtual key code for Print Screen
; 
; 
; Media Keys
#VK_VOLUME_MUTE = $AD
#VK_VOLUME_DOWN = $AE
#VK_VOLUME_UP = $AF
#VK_MEDIA_NEXT_TRACK = $B0
#VK_MEDIA_PREV_TRACK = $B1
#VK_MEDIA_STOP = $B2
#VK_MEDIA_PLAY_PAUSE = $B3

; Configuration Constants (adjust as needed)
#KEY_EVENT_DELAY = 15  ; Base delay between key events (milliseconds)
#MIN_MAIN_KEY_HOLD = 30 ; Minimum hold time for main key (milliseconds)


; Virtual Key Mappings with left/right support
Procedure.w StringToVK(key.s)
   Debug key.s
  Select UCase(key)
    ; Modifier Keys (left/right)
    Case "LSHIFT": ProcedureReturn #VK_LSHIFT
    Case "RSHIFT": ProcedureReturn #VK_RSHIFT
    Case "LCTRL", "LCONTROL": ProcedureReturn #VK_LCONTROL
    Case "RCTRL", "RCONTROL": ProcedureReturn #VK_RCONTROL
    Case "LALT": ProcedureReturn #VK_LMENU
    Case "RALT": ProcedureReturn #VK_RMENU
    Case "LWIN": ProcedureReturn #VK_LWIN
    Case "RWIN": ProcedureReturn #VK_RWIN
      
    ; Generic Modifiers (default to left)
    Case "SHIFT": ProcedureReturn #VK_LSHIFT
    Case "CTRL", "CONTROL": ProcedureReturn #VK_LCONTROL
    Case "ALT": ProcedureReturn #VK_LMENU
    Case "WIN", "WINDOWS", "CMD", "COMMAND": ProcedureReturn #VK_LWIN
    Case "PRINTSCREEN", "PRTSC", "PRTSCN", "SNAPSHOT": ProcedureReturn #VK_SNAPSHOT
          
    ; Letters A-Z
    Case "A": ProcedureReturn 'A'
    Case "B": ProcedureReturn 'B'
    Case "C": ProcedureReturn 'C'
    Case "D": ProcedureReturn 'D'
    Case "E": ProcedureReturn 'E'
    Case "F": ProcedureReturn 'F'
    Case "G": ProcedureReturn 'G'
    Case "H": ProcedureReturn 'H'
    Case "I": ProcedureReturn 'I'
    Case "J": ProcedureReturn 'J'
    Case "K": ProcedureReturn 'K'
    Case "L": ProcedureReturn 'L'
    Case "M": ProcedureReturn 'M'
    Case "N": ProcedureReturn 'N'
    Case "O": ProcedureReturn 'O'
    Case "P": ProcedureReturn 'P'
    Case "Q": ProcedureReturn 'Q'
    Case "R": ProcedureReturn 'R'
    Case "S": ProcedureReturn 'S'
    Case "T": ProcedureReturn 'T'
    Case "U": ProcedureReturn 'U'
    Case "V": ProcedureReturn 'V'
    Case "W": ProcedureReturn 'W'
    Case "X": ProcedureReturn 'X'
    Case "Y": ProcedureReturn 'Y'
    Case "Z": ProcedureReturn 'Z'
      
    ; Numbers 0-9
    Case "0": ProcedureReturn '0'
    Case "1": ProcedureReturn '1'
    Case "2": ProcedureReturn '2'
    Case "3": ProcedureReturn '3'
    Case "4": ProcedureReturn '4'
    Case "5": ProcedureReturn '5'
    Case "6": ProcedureReturn '6'
    Case "7": ProcedureReturn '7'
    Case "8": ProcedureReturn '8'
    Case "9": ProcedureReturn '9'
      
    ; Function Keys F1-F24
    Case "F1": ProcedureReturn $70
    Case "F2": ProcedureReturn $71
    Case "F3": ProcedureReturn $72
    Case "F4": ProcedureReturn $73
    Case "F5": ProcedureReturn $74
    Case "F6": ProcedureReturn $75
    Case "F7": ProcedureReturn $76
    Case "F8": ProcedureReturn $77
    Case "F9": ProcedureReturn $78
    Case "F10": ProcedureReturn $79
    Case "F11": ProcedureReturn $7A
    Case "F12": ProcedureReturn $7B
    Case "F13": ProcedureReturn $7C
    Case "F14": ProcedureReturn $7D
    Case "F15": ProcedureReturn $7E
    Case "F16": ProcedureReturn $7F
    Case "F17": ProcedureReturn $80
    Case "F18": ProcedureReturn $81
    Case "F19": ProcedureReturn $82
    Case "F20": ProcedureReturn $83
    Case "F21": ProcedureReturn $84
    Case "F22": ProcedureReturn $85
    Case "F23": ProcedureReturn $86
    Case "F24": ProcedureReturn $87
      
    ; Special Keys
    Case "TAB": ProcedureReturn $09
    Case "ENTER", "RETURN": ProcedureReturn $0D
    Case "ESC", "ESCAPE": ProcedureReturn $1B
    Case "SPACE": ProcedureReturn $20
    Case "BACKSPACE", "BACK": ProcedureReturn $08
    Case "DELETE", "DEL": ProcedureReturn $2E
    Case "INSERT", "INS": ProcedureReturn $2D
    Case "HOME": ProcedureReturn $24
    Case "END": ProcedureReturn $23
    Case "PAGEUP", "PGUP": ProcedureReturn $21
    Case "PAGEDOWN", "PGDN": ProcedureReturn $22
      
    ; Arrow Keys
    Case "UP": ProcedureReturn $26
    Case "DOWN": ProcedureReturn $28
    Case "LEFT": ProcedureReturn $25
    Case "RIGHT": ProcedureReturn $27
      
    ; Media Keys
    Case "VOLUME_MUTE": ProcedureReturn #VK_VOLUME_MUTE
    Case "VOLUME_DOWN": ProcedureReturn #VK_VOLUME_DOWN
    Case "VOLUME_UP": ProcedureReturn #VK_VOLUME_UP
    Case "MEDIA_PLAY": ProcedureReturn #VK_MEDIA_PLAY_PAUSE
    Case "MEDIA_STOP": ProcedureReturn #VK_MEDIA_STOP
    Case "MEDIA_NEXT": ProcedureReturn #VK_MEDIA_NEXT_TRACK
    Case "MEDIA_PREV": ProcedureReturn #VK_MEDIA_PREV_TRACK
      
    ; Numpad Keys (if needed)
    Case "NUMPAD0": ProcedureReturn $60
    Case "NUMPAD1": ProcedureReturn $61
    Case "NUMPAD2": ProcedureReturn $62
    Case "NUMPAD3": ProcedureReturn $63
    Case "NUMPAD4": ProcedureReturn $64
    Case "NUMPAD5": ProcedureReturn $65
    Case "NUMPAD6": ProcedureReturn $66
    Case "NUMPAD7": ProcedureReturn $67
    Case "NUMPAD8": ProcedureReturn $68
    Case "NUMPAD9": ProcedureReturn $69
    Case "NUMPAD_MULTIPLY": ProcedureReturn $6A
    Case "NUMPAD_ADD": ProcedureReturn $6B
    Case "NUMPAD_SEPARATOR": ProcedureReturn $6C
    Case "NUMPAD_SUBTRACT": ProcedureReturn $6D
    Case "NUMPAD_DECIMAL": ProcedureReturn $6E
    Case "NUMPAD_DIVIDE": ProcedureReturn $6F       

     ; Browser Control Keys
    Case "BROWSER_BACK": ProcedureReturn $A6
    Case "BROWSER_FORWARD": ProcedureReturn $A7
    Case "BROWSER_REFRESH": ProcedureReturn $A8
    Case "BROWSER_STOP": ProcedureReturn $A9
    Case "BROWSER_SEARCH": ProcedureReturn $AA
    Case "BROWSER_FAVORITES": ProcedureReturn $AB
    Case "BROWSER_HOME": ProcedureReturn $AC
    
    ; Application Control Keys
    Case "LAUNCH_MAIL": ProcedureReturn $B4
    Case "LAUNCH_MEDIA": ProcedureReturn $B5
    Case "LAUNCH_APP1": ProcedureReturn $B6
    Case "LAUNCH_APP2": ProcedureReturn $B7

    ; Special System Keys
    Case "APPS": ProcedureReturn $5D       ; Context menu key
    Case "SLEEP": ProcedureReturn $5F
    Case "CANCEL": ProcedureReturn $03     ; Break key
    Case "SCROLL_LOCK": ProcedureReturn $91
    Case "PAUSE": ProcedureReturn $13
    Case "NUMLOCK": ProcedureReturn $90
    Case "CAPSLOCK": ProcedureReturn $14
    
    ; Enhanced Navigation
    Case "SELECT": ProcedureReturn $29
    Case "EXECUTE": ProcedureReturn $2B
    Case "HELP": ProcedureReturn $2F
    
    ; OEM Keys
    Case "OEM_PLUS": ProcedureReturn $BB
    Case "OEM_COMMA": ProcedureReturn $BC
    Case "OEM_MINUS": ProcedureReturn $BD
    Case "OEM_MINUS": ProcedureReturn #VK_OEM_MINUS
    Case "OEM_PERIOD": ProcedureReturn $BE
    Case "OEM_1": ProcedureReturn $BA
    Case "OEM_2": ProcedureReturn $BF
    Case "OEM_3": ProcedureReturn $C0
    Case "OEM_4": ProcedureReturn $DB
    Case "OEM_5": ProcedureReturn $DC
    Case "OEM_6": ProcedureReturn $DD
    Case "OEM_7": ProcedureReturn $DE
    Case "OEM_8": ProcedureReturn $DF      

    Default: 
      Debug "[Hotkey] Unknown key: " + key
      ProcedureReturn 0
  EndSelect
EndProcedure

; Parse hotkey string into structured format
Procedure ParseHotkeyString(HotkeyString.s)
  Protected Keys.s = UCase(Trim(HotkeyString))
  Protected mainKey = 0
  Protected NewList Modifiers.i()
  Protected Dim Parts.s(10)
  Protected PartCount, i
  Protected part.s, vk.i, isModifier.i
  
  ; Split string into components
  PartCount = CountString(Keys, "+")
  For i = 0 To PartCount
    Parts(i) = Trim(StringField(Keys, i + 1, "+"))
  Next i
  
  ; Process each key part
  For i = 0 To PartCount
    part = Parts(i)
    vk = StringToVK(part)
    
    If vk = 0
      Debug "[Hotkey] Invalid key: " + part
      ProcedureReturn 0
    EndIf
    
    ; Check if it's a modifier key
    isModifier = #False
    Select vk
      Case #VK_LSHIFT, #VK_RSHIFT, #VK_LCONTROL, #VK_RCONTROL,
           #VK_LMENU, #VK_RMENU, #VK_LWIN, #VK_RWIN
        isModifier = #True
    EndSelect
    
    If isModifier
      AddElement(Modifiers())
      Modifiers() = vk
      ; If this is the only key, treat as main key too
      If PartCount = 0
        mainKey = vk
      EndIf
    Else
      ; Handle main key (only one allowed)
      If mainKey = 0
        mainKey = vk
      Else
        Debug "[Hotkey] Multiple main keys detected: " + part
        ProcedureReturn 0
      EndIf
    EndIf
  Next i
  
  ; Use last modifier as main key if none specified
  If mainKey = 0 And ListSize(Modifiers()) > 0
    LastElement(Modifiers())
    mainKey = Modifiers()
    DeleteElement(Modifiers())
  EndIf
  
  If mainKey = 0
    Debug "[Hotkey] No main key specified!"
    ProcedureReturn 0
  EndIf
  
  ; Create and populate the structure
  Protected *hotkey.HotKeyStruct = AllocateStructure(HotKeyStruct)
  If *hotkey = 0
    Debug "[Hotkey] Memory allocation failed!"
    ProcedureReturn 0
  EndIf
  
  ; Initialize and populate the modifiers list
  NewList *hotkey\Modifiers.i()
  CopyList(Modifiers(), *hotkey\Modifiers())
  *hotkey\mainKey = mainKey
  
  ProcedureReturn *hotkey
EndProcedure

; Execute key combination with intelligent delays
Procedure SendKeyCombo(*hotkey.HotKeyStruct)
  If *hotkey = 0
    ProcedureReturn #False
  EndIf
  
  Protected keyCount = ListSize(*hotkey\Modifiers()) + 1 ; +1 for main key
  Protected useDelay = #KEY_EVENT_DELAY
  Protected holdTime.i
  
  ; Press all modifiers
  ForEach *hotkey\Modifiers()
    keybd_event_(*hotkey\Modifiers(), 0, 0, 0)
    Delay(useDelay)
  Next
  
  ; Press main key with slightly longer hold time
  keybd_event_(*hotkey\mainKey, 0, 0, 0)
  
  ; Calculate hold time - PureBasic doesn't have Max(), so we do:
  holdTime = useDelay * 2
  If holdTime < #MIN_MAIN_KEY_HOLD
    holdTime = #MIN_MAIN_KEY_HOLD
  EndIf
  Delay(holdTime)
  
  ; Release main key
  keybd_event_(*hotkey\mainKey, 0, #KEYEVENTF_KEYUP, 0)
  Delay(useDelay)
  
  ; Release modifiers in reverse order
  If LastElement(*hotkey\Modifiers())
    Repeat
      keybd_event_(*hotkey\Modifiers(), 0, #KEYEVENTF_KEYUP, 0)
      Delay(useDelay)
    Until PreviousElement(*hotkey\Modifiers()) = 0
  EndIf
  
  ; Add extra delay for complex shortcuts
  If keyCount > 3
    Delay(useDelay * 2)
  EndIf
  
  ProcedureReturn #True
EndProcedure

; ============================================================
; Public Interface
; ============================================================

; Execute a hotkey from string
Procedure ExecuteHotkey(HotkeyString.s)
  Protected *hotkey = ParseHotkeyString(HotkeyString)
  
  If *hotkey
    Protected result = SendKeyCombo(*hotkey)
    FreeStructure(*hotkey)
    ProcedureReturn result
  EndIf
  ProcedureReturn #False
  
EndProcedure

; Where to integrate with command handling system (in your programs, for example)
Procedure HandleCommand(Type.l, Command.s)
  Select Type
    Case 0  ; Folder
      RunProgram("explorer.exe", Chr(34) + Command + Chr(34), "")
      
    Case 1  ; EXE
      RunProgram(Command, "", "")
      
    Case 2  ; Hotkey implementation
      ExecuteHotkey(Command)
      
    ; Add more types as needed
    ; Case 3: Open URL
    ;   RunProgram("cmd", "/c start " + Chr(34) + Command + Chr(34), "", #PB_Program_Hide)
    ; -------------------------------------------------------
    ; Sample usage of all implemented features

      ; Open folder
      ;HandleCommand(0, "C:\My Documents")
      
      ; Launch program
      ;HandleCommand(1, "notepad.exe")
      
      ; Execute hotkeys
       ;HandleCommand(2, "Win+R")               ; Run dialog
;       HandleCommand(2, "Ctrl+S")              ; Save
;       HandleCommand(2, "LWin+LCtrl+Left")     ; Virtual desktop left
;       HandleCommand(2, "PrtScn")              ; Full screen to clipboard
;       HandleCommand(2, "Alt+PrtScn")          ; Active window to clipboard
;       HandleCommand(2, "Win+PrtScn")          ; Save screenshot to disk (Win8+)
;       HandleCommand(2, "MEDIA_NEXT_TRACK")    ; Next media track
; -------------------------------------------------------

  EndSelect
EndProcedure

; ============================================================
; Testing  (tried many different cases)
; ===========================================================;
CompilerIf #PB_Compiler_IsMainFile
   
; Sample test cases
;   Debug "===== Hotkey Module Self-Test ====="
;   
;   Debug "Testing basic shortcuts:"
    ;ExecuteHotkey("Win+R")
;   Delay(1000)
;   
;   ExecuteHotkey("Ctrl+S")
;   Delay(1000)
;   
;   Debug "Testing left/right modifiers:"
;   ExecuteHotkey("LWin")
;   Delay(1000)
;   
;   ExecuteHotkey("RWin")
;   Delay(1000)
;   
;   Debug "Testing complex shortcuts:"
;   ExecuteHotkey("LWin+LCtrl+Left")
;   Delay(1000)
;   
;   Debug "Testing media keys:"
;   ExecuteHotkey("MEDIA_PLAY")
;   Delay(1000)
;   
;   Debug "===== Self-Test Complete ====="
   
; more self testing...  
   ;ExecuteHotkey("LWin")      ; Show desktop
   ;ExecuteHotkey("RWin")      ; Open context menu
   ;ExecuteHotkey("Win+R")     ; Run dialog
   ;ExecuteHotkey("Win+E")     ; File Explorer
   ;ExecuteHotkey("Ctrl+Esc")  ; Start menu
   
   ;ExecuteHotkey("LWin+D")    ; Show desktop
   ;ExecuteHotkey("RWin+X")    ; Quick Link menu
   
   ;ExecuteHotkey("LWin+LCtrl+Left")  ; Switch virtual desktop
   ;ExecuteHotkey("RCtrl+RShift+Esc") ; Task manager
   ;ExecuteHotkey("Win + PrtScn")
   ;ExecuteHotkey("LCtrl+LShift+Esc") ; Task manager same as above 2 methods
   
   ; More Tests
   ;ExecuteHotkey("LWin+LCtrl+O") ; see virtual keyboard
   ;ExecuteHotkey("Ctrl+S") ; save
   ;ExecuteHotkey("LWIN+LCTRL+N") ; Narator
   
   ;Check 'lower case' letters
   ;ExecuteHotkey("lwin+lctrl+n") ; Narator works
   
   ; Browser controls
   ; ExecuteHotkey("Browser_Back")       ; Go back in browser
   ; ExecuteHotkey("Browser_Refresh")    ; Refresh page
   ; 
   ; ; Application controls
    ExecuteHotkey("Launch_Mail")        ; Open email client
   ; ExecuteHotkey("Launch_Media")       ; Open media player
   ; 
   ; Special functions
   ; ExecuteHotkey("Sleep")              ; Put system to sleep
   ; ExecuteHotkey("Apps")               ; Open context menu
   ; 
   
   ; Printer Tests
      ; ExecuteHotkey("PrtScn")       ; Full screen to clipboard
       ;Delay(1000)                   ; Wait a moment
      ; ExecuteHotkey("Alt+PrtScn")   ; Active window to clipboard
       ;Delay(1000)
       ; ExecuteHotkey("Win+PrtScn")   ; Save to file (Windows 8+)
   
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
   
;HandleCommand tests (normally would run from your program)
    HandleCommand(2, "Win+R")               ; Run dialog
  ; HandleCommand(1, "notepad.exe")         ; Start Notepad

;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤   
 CompilerEndIf
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: HotKey System

Post by jacdelad »

Thanks, I will try this. Just one thing: Instead of loooooooots of cases, wouldn't it be better with a virtual table or at least map?
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: HotKey System

Post by blueb »

Maybe.. When I found additional stuff, I added it. So it might be setup better.. but it works for me. :mrgreen:
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Post Reply