Тема: AHK: Переназначение LED-индикаторов клавиатуры
Господа, заранее прошу прощения за детский вопрос, но я не разработчик и осилить язык глубже азов быстро не могу. Собственно проблема возникла при совмещении нескольких шатко-валко работающих по отдельности скриптов в один. Но лучше по порядку.
В обоих скриптах используется Keyboard LED control авторства Shimanov'а, Peter'а, JGR и evl'а, а точнее — дописанный Lexikos'ом Keyboard LED control for AutoHotkey_L. Он там в конце темы, но давайте я скопирую сюда код, чтоб вы ничего не искали.
/*
Keyboard LED control for AutoHotkey_L
http://www.autohotkey.com/forum/viewtopic.php?p=468000#468000
KeyboardLED(LEDvalue, "Cmd", Kbd)
LEDvalue - ScrollLock=1, NumLock=2, CapsLock=4
Cmd - on/off/switch
Kbd - index of keyboard (probably 0 or 2)
*/
KeyboardLED(LEDvalue, Cmd, Kbd=0)
{
SetUnicodeStr(fn,"\Device\KeyBoardClass" Kbd)
h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0)
If Cmd= switch ;switches every LED according to LEDvalue
KeyLED:= LEDvalue
If Cmd= on ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate)
KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
If Cmd= off ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate)
{
LEDvalue:= LEDvalue ^ 7
KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
}
success := DllCall( "DeviceIoControl"
, "ptr", h_device
, "uint", CTL_CODE( 0x0000000b ; FILE_DEVICE_KEYBOARD
, 2
, 0 ; METHOD_BUFFERED
, 0 ) ; FILE_ANY_ACCESS
, "int*", KeyLED << 16
, "uint", 4
, "ptr", 0
, "uint", 0
, "ptr*", output_actual
, "ptr", 0 )
NtCloseFile(h_device)
return success
}
CTL_CODE( p_device_type, p_function, p_method, p_access )
{
Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method
}
NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs)
{
VarSetCapacity(objattrib,6*A_PtrSize,0)
VarSetCapacity(io,2*A_PtrSize,0)
VarSetCapacity(pus,2*A_PtrSize)
DllCall("ntdll\RtlInitUnicodeString","ptr",&pus,"ptr",&wfilename)
NumPut(6*A_PtrSize,objattrib,0)
NumPut(&pus,objattrib,2*A_PtrSize)
status:=DllCall("ntdll\ZwCreateFile","ptr*",fh,"UInt",desiredaccess,"ptr",&objattrib
,"ptr",&io,"ptr",0,"UInt",fattribs,"UInt",sharemode,"UInt",createdist
,"UInt",flags,"ptr",0,"UInt",0, "UInt")
return % fh
}
NtCloseFile(handle)
{
return DllCall("ntdll\ZwClose","ptr",handle)
}
SetUnicodeStr(ByRef out, str_)
{
VarSetCapacity(out,2*StrPut(str_,"utf-16"))
StrPut(str_,&out,"utf-16")
}Итак, первый используемый мной скрипт составлен evl'ом и доступен во всё той же теме, во втором её сообщении. Скрипт инвертирует состояние индикатора Num Lock. Т. е. когда дополнительная цифровая клавиатура включена, индикатор не горит. В скрипт помимо приведённого выше блока входит следующий код:
Gosub, ~NumLock
Return
~NumLock::
~CapsLock::
~ScrollLock::
Sleep, 10 ; improve reliability of setting LED state sometimes
If (GetKeyState("Numlock", "T"))
KeyboardLED(2,"off")
Else
KeyboardLED(2,"on")
ReturnВторой, используемый мной скрипт должен зажигать индикатор Scroll Lock, когда включена английская раскладка клавиатуры. Он составлен по мотивам реализации Ludens'а. Однако, у Ludens'а индикатор зажигался, поскольку модифицировалось само состояние переключателя Scroll Lock. Я же хочу обойти переключатель и затронуть только индикатор, если есть такая возможность. Итак, в предлагаемом мной варианте помимо приведённого в начале блока используется следующий код:
#Persistent
SetTimer RussianLED
RussianLED:
WinGet, WID, ID, A
WT := DllCall("GetWindowThreadProcessId", "UInt", WID, "UInt", 0)
LID := DllCall("GetKeyboardLayout", "UInt", WT)
Russian := LID = 68748313 ? 1 : 0
If Russian
KeyboardLED(7,"off")
Else
KeyboardLED(7,"on")
ReturnКак я уже сказал, по отдельности эти скрипты работоспособны. Вопрос в том, чтобы добиться их одновременной слаженной работы, по возможности записав всё одним скриптом. И вершин удовольствия я достигну, если в этот единый скрипт можно будет безболезненно добавить ещё несколько переназначений, автозамен и прочих мелочей.

