Hmm, I haven't time to help you but I already investigate without a good result, it seems microsoft drivers and manufacturers have the secret... maybe try some google search with "autohotkey keyboard IwantthisMSDNfunction"...
However, for example an old script who can help you to understand and test yours functions:
Code: Select all
#SingleInstance Force
#Persistent
#NoEnv
Process, Priority, , High
SetBatchLines, -1
hDriver:=DllCall("GetModuleHandle", "uint", 0) ; can be the good solution if dead key header and other...
;KbdLayerDescriptor() GetKeyboardLayoutName()
;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\%KeyboardLayoutName%
hKbdHook := DllCall("SetWindowsHookEx", "int", 0x0D, "uint", RegisterCallback("LowLevelKeyboardProc"), "uint", hDriver, "uint", 0)
OnExit, UnhookKeyboardAndExit
Return
LowLevelKeyboardProc(nCode, wParam, lParam) {
; if ( A_CaretX=0 && A_CaretY=0 ) ; I don't want a Keylogger , but a CharLogger, I want real hotstring comparaison, not multisequencedHotKey
; but disrupt menu key ( alt, F10 )
VK:=NumGet(lParam+0), SC:=NumGet(lParam+4), flag:=NumGet(lParam+8)
log := "code " nCode " | event " wParam
log .= "`nVK " VK " | SC " SC
log .= "`nflag " flag " " flag & 0x80 ? " Up" : " Down"
log .= flag & 0x1 ? " Ext" : ""
log .= flag & 0x10 ? " Inj" : ""
log .= flag & 0x20 ? " Alt" : ""
if !(flag & 0x10) ; only physical input
{
TID := DllCall("GetWindowThreadProcessId", "Int", WinExist("A"), "Int", 0)
TID0 := DllCall("GetCurrentThreadId", "UInt", 0)
DllCall("AttachThreadInput", "UInt", TID0, "UInt", TID, "Int", 1)
HKL := DllCall("GetKeyboardLayout", "Int", TID) ; not useless to call very often ( alt+shift change langauge deteection)
VarSetCapacity(KeyState, 256)
DllCall( "GetKeyboardState", "uint", &KeyState )
;DllCall("AttachThreadInput", "UInt", TID0, "UInt", TID, "Int", 0)
VarSetCapacity(Character, 32)
DK := DllCall("ToUnicodeEx", "UInt", VK, "UInt", SC, "UInt", &KeyState, "Str", Character, "UInt", 64, "UInt", 1, "UInt", HKL)
if ( (DK!=-1) && !(flag & 0x80) && (DllCall("MapVirtualKey", "uint", VK, "uint", 2)>0) )
{
log .= "`nChar [" Character "]"
tooltip % log
}
; need to intercept translate (Wm_KEYDOWN TO WM_CHAR) because ToUnicodeEx create a translation dead key are double ^ -> ^^
; and (DllCall("MapVirtualKey", "uint", VK, "uint", 2)>0) prevent it with deadkey detection but creat an other problem ê -> e
; but stored Character are good and depend where MapVirtualKey are in the code... or use sendU with {BS} ><
}
return DllCall("CallNextHookEx", "uint", hKbdHook, "int", nCode, "uint", wParam, "uint", lParam)
}
esc::
UnhookKeyboardAndExit:
DllCall("UnhookWindowsHookEx", "uint", hKbdHook)
ExitApp
Therefore there is many ways because you can catch and predict what you will write with the keyboard layout and the key combo, I guess that modern application only have and use a big data table of what every langage and keyboard can produce and they don't call a function or an API or a drivers to know this. (for example multi langage keyboard overlay, or charlogger, also you can add and map an exotic keyboard manually)