Я ещё сделал сразу вариант с задержкой отпусканий, ну а совершенствовать код мне пока не интересно
У меня и в том и в этом варианте ни разу такого не было.
#SingleInstance Force
#NoEnv
ListLines Off
SetBatchLines -1
AutoTrim, Off
CoordMode, ToolTip
DllCall("PostMessage", "Ptr", A_ScriptHWND, "UInt", 0x50, "UInt", 0, "UInt", 0x409) ; eng layout
hHookKeybd := DllCall("SetWindowsHookEx"
, Int, WH_KEYBOARD_LL := 13
, Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
, Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
, UInt, 0, Ptr)
OnExit(Func("Exit").Bind(hHookKeybd))
Return
Esc::ExitApp
Exit(hHookKeybd) {
DllCall("UnhookWindowsHookEx", Ptr, hHookKeybd)
}
LowLevelKeyboardProc(nCode, wParam, lParam) {
static oMem := [], lpData, size := VarSetCapacity(lpData, 16 + A_PtrSize*2, 0)
DllCall("RtlMoveMemory", Ptr, &lpData, Ptr, lParam, Ptr, size)
oMem.Push([wParam, &lpData])
timer := Func("EventHandling").Bind(oMem) ; во избежание фризов клавиатуры обработка событий должна
SetTimer, % timer, -10 ; происходить обязательно по таймеру, а не в теле этой функции
Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}
EventHandling(oMem) {
static oMembers := ["vk", "sc", "flags"]
, oFlagOffsets := {LLKHF_EXTENDED: 0, LLKHF_UP: 7}
, oArr := {}, Str := " > ", Sleep := 500
if !isobject(oMem)
goto KeyDelete
while (oMem[1] != "") {
key := oMem.RemoveAt(1)
lp := key[2]
for k, v in oMembers
%v% := NumGet(lp + (k - 1)*4, "UInt")
for k, v in oFlagOffsets
%k% := (flags >> v) & 1
sc |= LLKHF_EXTENDED << 8
vkCode := Format("vk{:X}", vk)
scCode := Format("sc{:X}", sc)
If !LLKHF_UP && (oArr[vkCode . scCode] = "")
{
Str .= (oArr[vkCode . scCode] := GetKeyName(vkCode . scCode)) " > "
SetTimer, KeyState, -1
}
ToolTip % Str, 5, 5, 2
}
Return
KeyState:
If !oArr.Count()
{
SetTimer, KeyState, Off
Return
}
For key, name in oArr
{
If GetKeyState(name, "P")
Continue
oArr.Delete(key)
funcobj := Func("EventHandling").Bind(name)
SetTimer, % funcobj, -%Sleep%
}
SetTimer, KeyState, -1
Return
KeyDelete:
Str := StrReplace(Str, " > " oMem " > ", " > ", , 1)
ToolTip % Str, 5, 5, 2
If (Str = " > ")
ToolTip, , , , 2
Return
}