четверг, 19 сентября 2013 г.

Контроль устройств из VBS. Описание API вызова RunGetKeyboardSetcom.VBS

Данный VBS-скрипт предназначен для определения раскладки клавиатуры (по-умолчанию RUS/LAT) активного окна и автоматического управления внешней подсветкой (светодиодами, светодиодной лентой или иной нагрузкой через умощняющие ключи с соответствующей развязкой) путем контроля сигналов DTR (пин 4)/RTS (пин 7) последовательного физического или виртуального COM-порта over USB (на основе USB/UART конверторов типа CP21xx/FTDI/PL2303 и прочих), c голосовым сопровождением при переключении раскладки.




Сам VBScript умеет работать только с COM-объектами, для работы с WinAPI функциями используется внешний COM-сервер (библиотека) 'dynwrap.dll' или 'dynwrapX.dll'. Данная библиотека распространяется свободно. COM-сервер (ActiveX) позволяет вызвать любую экспортируемую функцию любой DLL. Cвоего рода, обертка. Как и любой COM - объект, 'dynwrap.dll' тоже требует регистрации в системе. В скрипте осуществлена его авторегистрация при запуске в скрытом режиме.

Cобственно, скрипт:
' RunGetKeyboardSetcom.VBS
' Пример простейшего скрипта определения RUS-LAT раскладки
' + контроля DTR or RTS порта COM (or virtual COM over USB) на VBS
' + голосового сопровождения при переключении раскладки
' через COM-сервер DynWrapx.dll
' Разработчик: Бадло Сергей Григорьевич
' H-page: [url]http://raxp.radioliga.com[/url]
' Ограничения: Win OS


' подключаем голосовое сопровождение
Dim Speak
Set Speak = CreateObject("sapi.spvoice")
' регистрируем COM объект DynamicWrapperX в тихом режиме
Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run ("regsvr32.exe dynwrapx.dll /s"),3, true
' создаем объект DynamicWrapperX
Set Wrap = CreateObject("DynamicWrapperX")
Wrap.Register "user32.dll", "GetKeyboardLayout", "i=l", "f=s", "r=l"
Wrap.Register "user32.dll", "GetForegroundWindow", "f=s", "r=l"
Wrap.Register "user32.dll", "GetWindowThreadProcessId", "i=ll", "f=s", "r=l"
' регистрируем функи для работы с портом
Wrap.Register "KERNEL32.DLL", "CreateFile", "i=sllllll", "r=l"
Wrap.Register "KERNEL32.DLL", "WriteFile", "i=lllll", "r=l"
Wrap.Register "KERNEL32.DLL", "CloseHandle", "i=l", "r=l"
Wrap.Register "KERNEL32.DLL", "EscapeCommFunction", "i=hu", "r=l"
' забиваем аттрибуты
GENERIC_WRITE = 1073741824
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
OPEN_EXISTING = 3
FILE_ATTRIBUTE_NORMAL = 128
' пин 7
SETRTS = 3 ' Set RTS high
CLRRTS = 4 ' Set RTS low
' пин 4
SETDTR = 5 ' Set DTR high
CLRDTR = 6 ' Set DTR low
' открываем нужный нам порт COM1
hFile = Wrap.CreateFile("COM1", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
' отключаем сигналы
s = Wrap.EscapeCommFunction(hFile, 4)
s = Wrap.EscapeCommFunction(hFile, 6)
' определяем для активной нити
hWindow = Wrap.GetForegroundWindow()
idProcess = Wrap.GetWindowThreadProcessId(hWindow, 0)
res = Wrap.GetKeyboardLayout(idProcess)

' активируем нужный сигнал до цикла
if (res = "67699721") then
 s = Wrap.EscapeCommFunction(hFile, SETRTS)
 s = Wrap.EscapeCommFunction(hFile, CLRDTR)
 Speak.Speak "Установлена английская раскладка клавиатуры."
End if
if (res = "68748313") then
 s = Wrap.EscapeCommFunction(hFile, SETDTR)
 s = Wrap.EscapeCommFunction(hFile, CLRRTS)
 Speak.Speak "Установлена русская раскладка клавиатуры."
End if

' запускаем бесконечный цикл с задержкой
Do
WScript.Sleep 1000 'кол-во миллисекунд
hWindow = Wrap.GetForegroundWindow()
idProcess = Wrap.GetWindowThreadProcessId(hWindow, 0)
res2 = Wrap.GetKeyboardLayout(idProcess)
if (res2 <> res) and (res2 = "67699721") then
 s = Wrap.EscapeCommFunction(hFile, SETRTS)
 s = Wrap.EscapeCommFunction(hFile, CLRDTR)
 ' при надоедливости голоса комментируем его
 Speak.Speak "English."
End if
if (res2 <> res) and (res2 = "68748313") then
 s = Wrap.EscapeCommFunction(hFile, SETDTR)
 s = Wrap.EscapeCommFunction(hFile, CLRRTS)
 ' при надоедливости голоса комментируем его
 Speak.Speak "Rus."
End if
res = res2
Loop
Wrap.CloseHandle(hFile)

ПОРЯДОК ИСПОЛЬЗОВАНИЯ
  1. Подключите контролируемую нагрузку к COM-порту или USB-конвертор (считаем, что драйвера уже установлены).
  2. Запуститите скрипт 'rungetkeyboardsetcom.vbs' или инструкцию 'ЗАПУСТИТЬ инструкцию в голосовом режиме!.vbs'.
  3. При запуске будет осуществлено управление сигналами RTS/DTR и озвучена текущая раскладка.
  4. При необходимости озвучивание можно деактивировать закомментировав метод Speak объекта 'sapi.spvoice'.

Комментариев нет:

Отправить комментарий

В комментариях уважайте собеседника, внимательно читайте посты и не додумывайте. Просьбы и предложения из разряда: «можно ваш Skype/Viber/телефон», «напишите мне в vk/FB», а также другие им подобные — игнорируются. Выход новых версий ПО, внешняя ссылка, переставшая работать с течением времени и т.п. не является основанием для претензий. Желающие спокойно подискутировать и высказаться — Welcome. Желающие спонсировать блог — Donate. Нарушение этих простых правил ведет к бану и удалению комментариев без предупреждения.