Blog. Just Blog

Управление клавишами NumLock, CapsLock и ScrollLock

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда в программах требуется получать состояние управляющих клавиш или изменять их состояние. Во времена MS-DOS достаточно было просто прочитать или записать значение WORD по определенному адресу памяти, при этом светодиодные индикаторы клавиатуры реагировали на это включением или выключением. Были очень популярны крохотные, в несколько байт, программы для выключения NumLock при загрузке системы, типа таких:
  1. ;-----------------------------------------------------------
  2. ; Программа для выключения индикатора NumLock под MS-DOS
  3. ; Размер .com-файла после компиляции 9 байт
  4. ;-----------------------------------------------------------
  5. .286
  6. .model  tiny
  7. .code                         ; Сегмент кода
  8.         org     100h          ; Зарезервировано для PSP
  9. start:
  10.         pop     ax            ; После запуска в стеке 0, AX=0
  11.         mov     ds,ax         ; DS=0
  12.         mov     ds:[417h],ax  ; WORD DS:[417h] - состояние *Lock'ов
  13.         int     20h           ; Выход из программы
  14. end     start
В свое время это был самый минимальный рабочий код для выключения клавиши NumLock, хоть и не совсем корректный в плане работы со стеком.

В среде Windows все значительно усложнилось. Теперь получать состояние переключателей приходится при помощи функции GetKeyState. Для изменения состояния клавиш в Windows есть функция SetKeyboardState, но она не меняет состояния светодиодов на клавиатуре. Поэтому придется искать другой путь, например, через функцию keybd_event эмулировать нажатия на соответствующие клавиши. Для удобства я написал небольшую функцию, устанавливающую нужный переключатель в нужное состояние.
  1. ;------------------------------------------------------------------
  2. ; Функция переключения индикаторов
  3. ; Входные параметры:
  4. ;    dKey   - идентификатор клавиши
  5. ;    dState - состояние (TRUE = включено, FALSE = выключено)
  6. ;------------------------------------------------------------------
  7. proc SetLockState dKey:DWORD, dState:DWORD
  8.         pusha
  9.  
  10.         ; Получить состояние управляющей клавиши
  11.         invoke  GetKeyState,[dKey]
  12.         ; Если клавиша уже в нужном положении, то ничего не делать
  13.         cmp     eax,[dState]
  14.         je      @f
  15.  
  16.         ; Имитировать нажатие клавиши на клавиатуре
  17.         invoke  keybd_event,[dKey],0,0,NULL
  18.         invoke  keybd_event,[dKey],0,KEYEVENTF_KEYUP,NULL
  19. @@:
  20.         popa
  21.         ret
  22. endp
Параметры вызова: dKey - код клавиши, для этого в FASM уже предопределены константы VK_CAPITAL, VK_NUMLOCK и VK_SCROLL, dState - нужное состояние (TRUE - включено, FALSE - выключено). Пример вызова:
  1.         ...
  2.         stdcall SetLockState,VK_CAPITAL,FALSE  ; Выключить CapsLock
  3.         stdcall SetLockState,VK_NUMLOCK,TRUE   ; Включить NumLock
  4.         ...
В приложении программа, управляющая индикаторами и состоянием клавиш NumLock, CapsLock и ScrollLock. Обратной связи не предусмотрено, поэтому ручные нажатия на клавиши не меняют состояния checkbox'ов.

Lock Keys Control DemoLock Keys Control Demo

Lock.Keys.Control.Demo.zip (3,371 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 9710 | Комментариев: 3

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (13.06.2011 в 01:46):
Вряд ли
ave (11.06.2011 в 20:41):
А на Javascript чтото подобное можно сделать?
Dimi4 (15.10.2009 в 23:58):
На VBS простіше)

set WshShell = WScript.CreateObject("WScript.Shell")
KL = true

do while KL
  if WshShell.AppActivate("Microsoft Word") then
    WriteWord()
    KL = false
  end if
  WScript.Sleep 100
loop
function WriteWord()
WshShell.SendKeys "http://uasc.org.ua =)"
WScript.Sleep(300)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(30)
WshShell.SendKeys "{Scrolllock}"
WScript.Sleep(40)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(40)
WshShell.SendKeys "{Scrolllock}"
WScript.Sleep(60)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(70)
WshShell.SendKeys "{Scrolllock}"
WScript.Sleep(80)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(90)
WshShell.SendKeys "{Scrolllock}"
WScript.Sleep(100)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(110)
WshShell.SendKeys "{Scrolllock}"
WScript.Sleep(120)
WshShell.SendKeys "{CAPSLOCK}"
WScript.Sleep(130)
WshShell.SendKeys "{Scrolllock}"
end function

Запустіть MS Office Word та подивіться на клавіатуру)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.003 сек.) / Память: 4.5 Mb
Наверх