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

Иногда в программах требуется получать состояние управляющих клавиш или изменять их состояние. Во времена MS-DOS достаточно было просто прочитать или записать значение WORD по определенному адресу памяти, при этом светодиодные индикаторы клавиатуры реагировали на это включением или выключением. Были очень популярны крохотные, в несколько байт, программы для выключения NumLock при загрузке системы, типа таких:
;-----------------------------------------------------------
; Программа для выключения индикатора NumLock под MS-DOS
; Размер .com-файла после компиляции 9 байт
;-----------------------------------------------------------
.286
.model  tiny
.code                         ; Сегмент кода
        org     100h          ; Зарезервировано для PSP
start:
        pop     ax            ; После запуска в стеке 0, AX=0
        mov     ds,ax         ; DS=0
        mov     ds:[417h],ax  ; WORD DS:[417h] - состояние *Lock'ов
        int     20h           ; Выход из программы
end     start

В свое время это был самый минимальный рабочий код для выключения клавиши NumLock, хоть и не совсем корректный в плане работы со стеком.

В среде Windows все значительно усложнилось. Теперь получать состояние переключателей приходится при помощи функции GetKeyState. Для изменения состояния клавиш в Windows есть функция SetKeyboardState, но она не меняет состояния светодиодов на клавиатуре. Поэтому придется искать другой путь, например, через функцию keybd_event эмулировать нажатия на соответствующие клавиши. Для удобства я написал небольшую функцию, устанавливающую нужный переключатель в нужное состояние.
;------------------------------------------------------------------
; Функция переключения индикаторов
; Входные параметры:
;    dKey   - идентификатор клавиши
;    dState - состояние (TRUE = включено, FALSE = выключено)
;------------------------------------------------------------------
proc SetLockState dKey:DWORD, dState:DWORD
        pusha
 
        ; Получить состояние управляющей клавиши
        invoke  GetKeyState,[dKey]
        ; Если клавиша уже в нужном положении, то ничего не делать
        cmp     eax,[dState]
        je      @f
 
        ; Имитировать нажатие клавиши на клавиатуре
        invoke  keybd_event,[dKey],0,0,NULL
        invoke  keybd_event,[dKey],0,KEYEVENTF_KEYUP,NULL
@@:
        popa
        ret
endp

Параметры вызова: dKey - код клавиши, для этого в FASM уже предопределены константы VK_CAPITAL, VK_NUMLOCK и VK_SCROLL, dState - нужное состояние (TRUE - включено, FALSE - выключено). Пример вызова:
        ...
        stdcall SetLockState,VK_CAPITAL,FALSE  ; Выключить CapsLock
        stdcall SetLockState,VK_NUMLOCK,TRUE   ; Включить NumLock
        ...

В приложении программа, управляющая индикаторами и состоянием клавиш NumLock, CapsLock и ScrollLock. Обратной связи не предусмотрено, поэтому ручные нажатия на клавиши не меняют состояния checkbox'ов.
Теги:
NumLock, CapsLock, ScrollLock
Добавлено: 10 Апреля 2018 20:39:43 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...