Alternatives to Send/SendInput/ControlSend:
To send text (individual Unicode characters): WM_CHAR.
To send an individual key press: WM_KEYDOWN, WM_KEYUP.
To send an individual key press plus modifiers:
WM_KEYDOWN, WM_KEYUP, but also use SetKeyboardState as in the example below.
To receive an individual key press, and to work out the correct parameter values for WM_KEYDOWN, WM_KEYUP, that you would use to send a key press:
Use OnMessage to check for the 2 messages, and receive the parameters, for when keys are pressed manually or sent via Send/SendInput.
To receive an individual key press, and modifiers:
Use OnMessage to check for the key press and use GetKeyState to check for modifiers.
Instead of GetKeyState, the dll function GetKeyboardState can be used.
The reasons for investigating Send/SendInput, were to understand how best to receive input when creating GUIs via AutoHotkey, and to be able to send key presses to a specific hWnd unlike via Send/SendInput.
Further reasons are to understand how key presses can be sent in programming languages generally, without standard AutoHotkey functions, and to understand the AutoHotkey source code.
To find out how AutoHotkey does this, search the cpp source code files for 'GetKeyboardState' and 'SetKeyboardState'.
Note: regarding methods outlined here, there may be other methods.
Note: the code below worked although it is possible that improvements could be made.
If anyone has any further comments regarding these issues, or the code, or regarding AutoHotkey and receiving/sending key presses, they would be most welcome.
Code: Select all
q:: ;send ctrl+shift+left without using Send/SendInput/ControlSend
;e.g. tested on Notepad (Windows 7)
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
if !(vCtlClassNN = "")
ControlGet, hWnd, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
vTIDAhk := DllCall("kernel32\GetCurrentThreadId", "UInt")
VarSetCapacity(PBYTE1, 256, 0)
DllCall("user32\GetKeyboardState", "Ptr",&PBYTE1)
vTID := DllCall("user32\GetWindowThreadProcessId", "Ptr",hWnd, "Ptr",0, "UInt")
DllCall("user32\AttachThreadInput", "UInt",vTIDAhk, "UInt",vTID, "Int",1)
VarSetCapacity(PBYTE2, 256, 0)
NumPut(0x80, PBYTE2, 0x10, "UChar") ;VK_SHIFT := 0x10
NumPut(0x80, PBYTE2, 0x11, "UChar") ;VK_CONTROL := 0x11
DllCall("user32\SetKeyboardState", "Ptr",&PBYTE2)
;VK_LEFT := 0x25
SendMessage, 0x100, 0x25, 0x014B0001,, % "ahk_id " hWnd ;WM_KEYDOWN := 0x100
SendMessage, 0x101, 0x25, 0xC14B0001,, % "ahk_id " hWnd ;WM_KEYUP := 0x101
DllCall("user32\AttachThreadInput", "UInt",vTIDAhk, "UInt",vTID, "Int",0)
DllCall("user32\SetKeyboardState", "Ptr",&PBYTE1)
return