Тема: АНК: (из Коллекции) скрипт-индикатор для NumLock CapsLock ScrollLock..
На работе беспроводная клавиатура, но идея скрипта понравилась, использую дома и на проводной.
Решил, что будет удобнее, если и текущая раскладка будет отображаться на кнопке "Пуск", а стандартную можно убрать.
Благодаря решениям teadrinker и creature.ws раскладка отображается и в консольных приложениях.
В какой-то теме подсмотрел как расширить кнопку, объединил, в итоге получился скрипт:
#persistent ; необходимо, только если используется в качестве отдельного скрипта
; или встраивается в скрипт без строк автозамены, горячих клавиш или команд GUI.
SetTimer, Start, 100 ; настройте второй параметр, чтобы изменить интервал реагирования
Start:
StartButtonText = %NumToggle%%ScrollToggle%%InsToggle% %CapsLang%
GetKeyState, NumToggle, Numlock, T
If NumToggle = U
NumToggle = -
Else
NumToggle = N
GetKeyState, ScrollToggle, ScrollLock, T
If ScrollToggle = U
ScrollToggle = -
Else
ScrollToggle = S
GetKeyState,InsToggle, Insert, T
If InsToggle = U
InsToggle = -
Else
InsToggle = I
GetKeyState, CapsToggle, CapsLock, T ; проверяем, включен ли Capslock
InputLocale:= GetInputLangName(GetInputLangID("A"))
StringLeft, InputLocale, InputLocale, 2
StringUpper, InputLocale, InputLocale
If CapsToggle = U
StringLower, InputLocale, InputLocale
CapsLang := InputLocale
ControlMove, Button1, 0,, 62,, ahk_class Shell_TrayWnd ; увеличение размера кнопки "Пуск"
ControlSetText,Button1,%StartButtonText%,ahk_class Shell_TrayWnd ;изменение текста на кнопке "Пуск"
Return
GetInputLangID(window)
{
If !(hWnd := WinExist(window))
return
WinGetClass, Class
if (Class == "ConsoleWindowClass")
{
WinGet, consolePID, PID
DllCall("AttachConsole", Ptr, consolePID)
VarSetCapacity(buff, 16)
DllCall("GetConsoleKeyboardLayoutName", Str, buff)
DllCall("FreeConsole")
langID := "0x" . SubStr(buff, -3)
}
Else
langID := DllCall("GetKeyboardLayout", Ptr, DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0, Ptr), Ptr) & 0xFFFF
return langID
}
GetInputLangName(langId)
{
Size := (DllCall("GetLocaleInfo", UInt, langId, UInt, 0x1001, UInt, 0, UInt, 0) * 2) ; LOCALE_SENGLANGUAGE := 0x1001
VarSetCapacity(localeSig, Size, 0)
DllCall("GetLocaleInfo", UInt, langId, UInt, 0x1001, Str, localeSig, UInt, Size)
return localeSig
}
Отображение CapsLock отдельной буквой убрал. Вместо этого верхний или нижний регистр отображается в названии раскладки.
Вопросы по этому скрипту:
Можно ли раскладку выводить цветным шрифтом на цветном фоне? Можно ли вывести на месте картинки?
Т.е. хотелось бы получить отображение, как у оригинальной: белым шрифтом на синем фоне.
В теме подсмотрел как можно изменить изображение у кнопки "Пуск".
Второй вариант скрипта с изображениями:
#persistent ; необходимо, только если используется в качестве отдельного скрипта
; или встраивается в скрипт без строк автозамены, горячих клавиш или команд GUI.
;SetBatchLines, -1
StringCaseSense, On
Gui, +ToolWindow -Caption
Gui, +Lastfound
GUI_ID := WinExist()
WinGet, TaskBar_ID, ID, ahk_class Shell_TrayWnd
DllCall("SetParent", "uint", GUI_ID, "uint", Taskbar_ID)
Gui, Margin, 0, 0
Gui, Add, Picture, x2 y3 w16 h16 gStartM vStartM, xx_s.bmp
Gui, Show, x0 y0 , Start Button
PrevInputLocale:="xx" ; переменная введена для того, чтобы не мерцало изображение с раскладкой
SetTimer, Start, 100 ; настройте второй параметр, чтобы изменить интервал реагирования
Return
Start:
StartButtonText = %NumToggle%%ScrollToggle%%InsToggle%
GetKeyState, NumToggle, Numlock, T
If NumToggle = U
NumToggle = -
Else
NumToggle = N
GetKeyState, ScrollToggle, ScrollLock, T
If ScrollToggle = U
ScrollToggle = -
Else
ScrollToggle = S
GetKeyState,InsToggle, Insert, T
If InsToggle = U
InsToggle = -
Else
InsToggle = I
GetKeyState, CapsToggle, CapsLock, T ; проверяем, включен ли Capslock
InputLocale:= GetInputLangName(GetInputLangID("A"))
StringLeft, InputLocale, InputLocale, 2
If CapsToggle = U
StringLower, InputLocale, InputLocale
Else
StringUpper, InputLocale, InputLocale
IF (InputLocale <> PrevInputLocale)
{
IF InputLocale = en
GuiControl,, Static1, en_s.bmp
Else If InputLocale = EN
GuiControl,, Static1, EN.bmp
Else If InputLocale = ru
GuiControl,, Static1, ru_s.bmp
Else If InputLocale = RU
GuiControl,, Static1, RU.bmp
ELSE
{
If CapsToggle = U
GuiControl,, Static1, xx_s.bmp
Else
GuiControl,, Static1, XX.bmp
}
PrevInputLocale := InputLocale
}
ControlSetText,Button1,%A_Space%%StartButtonText%,ahk_class Shell_TrayWnd ;изменение текста на кнопке "Пуск"
Return
GetInputLangID(window)
{
If !(hWnd := WinExist(window))
return
WinGetClass, Class
if (Class == "ConsoleWindowClass")
{
WinGet, consolePID, PID
DllCall("AttachConsole", Ptr, consolePID)
VarSetCapacity(buff, 16)
DllCall("GetConsoleKeyboardLayoutName", Str, buff)
DllCall("FreeConsole")
langID := "0x" . SubStr(buff, -3)
}
Else
langID := DllCall("GetKeyboardLayout", Ptr, DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0, Ptr), Ptr) & 0xFFFF
return langID
}
GetInputLangName(langId)
{
Size := (DllCall("GetLocaleInfo", UInt, langId, UInt, 0x1001, UInt, 0, UInt, 0) * 2) ; LOCALE_SENGLANGUAGE := 0x1001
VarSetCapacity(localeSig, Size, 0)
DllCall("GetLocaleInfo", UInt, langId, UInt, 0x1001, Str, localeSig, UInt, Size)
return localeSig
}
StartM:
Send ^{Esc}
return
Недостатки.
На каждый язык нужно свое изображение. Если состояние CapsLock показывать в раскладке как в этом скрипте, требуется по дополнительному изображению на каждый язык.
Можно ли каким-то образом менять текст изображения прямо в скрипте, т.е. использовать одно изображение?
Хотя большинство использует 2-4 языка и дорисовать иконки - небольшая проблема.
Решение этого вопроса - лишь заявка на универсальность.