Эмуляция нажатия мультимедийных клавиш на клавиатуре
В статье про обработку мультимедийных кнопок я немного коснулся эмуляции их нажатий. Там эмуляция была направлена напрямую в оболочку, сейчас же я расскажу, как выполнять такое действие полноценно, с учетом интересов всех запущенных приложений. Начнем с эмуляции пользовательского ввода с помощью функции SendInput.При всей моей любви к FASM, просто убивает скудность его инклудов. Похоже, что наполнение их данными остановилось на Win2000, а если захочется что-нибудь чуть новее, то все, добро пожаловать в MSDN. И хорошо, если структура окажется на пять-десять записей. Вот и сейчас нам придется самостоятельно описать структуру INPUT и обозначить коды мультимедийных клавиш.
Code (Assembler) : Убрать нумерацию
- struct MOUSEINPUT
- dx dd ?
- dy dd ?
- mouseData dd ?
- dwFlags dd ?
- time dd ?
- dwExtraInfo dd ?
- ends
- struct KEYBDINPUT
- wVk dw ?
- wScan dw ?
- dwFlags dd ?
- time dd ?
- dwExtraInfo dd ?
- ends
- struct HARDWAREINPUT
- uMsg dd ?
- wParamL dw ?
- wParamH dw ?
- ends
- struct INPUT
- type dd ?
- union
- mi MOUSEINPUT
- ki KEYBDINPUT
- hi HARDWAREINPUT
- ends
- ends
- INPUT_KEYBOARD = 1
- VK_VOLUME_UP = 0xAF
- VK_VOLUME_DOWN = 0xAE
- VK_LAUNCH_APP2 = 0xB7
Вот пара примеров, как можно эмулировать нажатия на мультимедийные клавиши. Увеличить громкость:
Code (Assembler) : Убрать нумерацию
- ; Нажать клавишу
- mov [input.type],INPUT_KEYBOARD
- mov [input.ki.wVk],VK_VOLUME_UP
- mov [input.ki.wScan],0x30
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY
- invoke SendInput,1,input,sizeof.INPUT
- ; Отпустить клавишу
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP
- invoke SendInput,1,input,sizeof.INPUT
Code (Assembler) : Убрать нумерацию
- ; Нажать клавишу
- mov [input.type],INPUT_KEYBOARD
- mov [input.ki.wVk],VK_VOLUME_DOWN
- mov [input.ki.wScan],0x2E
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY
- invoke SendInput,1,input,sizeof.INPUT
- ; Отпустить клавишу
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP
- invoke SendInput,1,input,sizeof.INPUT
Code (Assembler) : Убрать нумерацию
- ; Нажать клавишу
- mov [input.type],INPUT_KEYBOARD
- mov [input.ki.wVk],VK_LAUNCH_APP2
- mov [input.ki.wScan],0x21
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY
- invoke SendInput,1,input,sizeof.INPUT
- ; Отпустить клавишу
- mov [input.ki.dwFlags],KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP
- invoke SendInput,1,input,sizeof.INPUT
В процессе тестирования я сделал интересные наблюдения. При изменении громкости аудиоплеер AIMP и мультимедийный плеер Light Alloy отслеживали подобные нажатия и меняли свой собственный уровень громкости, тогда как общий уровень громкости системы оставался неизменным. Когда ни один плеер не работал, то менялась общая громкость звука в системе, такое же поведение показывал и Windows Media Payer, который игнорировал "нажатия" на мультимедийные кнопки.
Второй способ более интересный. Он немного похож на пример из базовой статьи и также основан на отправке сообщения WM_APPCOMMAND. Сперва, как обычно, несколько констант для описания сообщения и кодов мультимедийных кнопок:
Code (Assembler) : Убрать нумерацию
- WM_APPCOMMAND = 0x319
- APPCOMMAND_VOLUME_DOWN = 9
- APPCOMMAND_VOLUME_UP = 10
Code (Assembler) : Убрать нумерацию
- ; Сообщение о нажатой мультимедийной клавише
- invoke SendMessage,[hwnddlg],WM_APPCOMMAND,[hwnddlg],\
- APPCOMMAND_VOLUME_UP shl 16
Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_APPCOMMAND
- je .wm_media
- ...
- ...
- ...
- .wm_media:
- ; Отправить сообщение дальше по цепочке обработчиков
- invoke DefWindowProc,[hwnddlg],[msg],[wparam],[lparam]
- jmp .processed
В подтверждение этой мысли, Windows Media Payer прекрасно реагирует на эмуляцию кнопки Play/Pause, даже находясь в фоновом режиме, потому что как раз использует технику хуков. Другие необработанные сообщения, например, запуск калькулятора, благополучно достигают оболочки, которая, в свою очередь, обрабатывает их по своему усмотрению.
Просмотров: 1641 | Комментариев: 2
Метки: Assembler, клавиатура
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(22.06.2020 в 23:26):
Шайтанама :)
АндрейК
(22.06.2020 в 12:09):
Эх... Было дело: https://www.youtube.com/watch?v=gsSPKbf1Mjw
Добавить комментарий
Заполните форму для добавления комментария