Arduino.ru
Добрый день господа, я знаю таких проектов полно, но мне лень искать искать и править.
Arduino 1.6.5 так как страшие версии не правильно понимают экран
FLProg на всякий случай
Arduino Nano Atmega 328
Экран 2х16 1602A подключенный через I2C, адрес 0х27
Хочу сделать кликер/счетчик нажатия на кнопку. Работа легкая, но повторюсь лень
- Войдите на сайт для отправки комментариев
Втр, 08/03/2016 — 08:22
Зарегистрирован: 07.03.2016
Написал скетч с помощью FLProg, но счетчик сичатает нажата кнопка или нет, а мне нужно чтобы общее количество нажатий было.
bool _count1I = 0; unsigned long _count1P = 0UL; bool _bounseInputD12S = 0; bool _bounseInputD12O = 0; unsigned long _bounseInputD12P = 0UL; bool _bounseInputD13S = 0; bool _bounseInputD13O = 0; unsigned long _bounseInputD13P = 0UL; void setup() < Serial.begin(9600); pinMode(13, INPUT); //кликать суды pinMode(12, INPUT); //сброс _bounseInputD12O = digitalRead(12); _bounseInputD13O = digitalRead(13); >void loop() < bool _bounceInputTmpD12 = (digitalRead (12)); if (_bounseInputD12S) < if (millis() >= (_bounseInputD12P + 40)) > else < if (_bounceInputTmpD12 != _bounseInputD12O ) > bool _bounceInputTmpD13 = (digitalRead (13)); if (_bounseInputD13S) < if (millis() >= (_bounseInputD13P + 40)) > else < if (_bounceInputTmpD13 != _bounseInputD13O ) > if (_bounseInputD13O) < if (! _count1I) < _count1P = _count1P+1; _count1I = 1; >> else < _count1I=0; >if (_bounseInputD12O) _count1P = 0; Serial.print(_count1I);; delay (100); >
P.S. Пока пишу на сериал порт, дабы не нагибаться постоянно
- Войдите на сайт для отправки комментариев
Как сделать кликер в ардуино
Добрый день.
Хочу представить вам аппаратный кликер на базе UOpilot.
Для начала вам необходима будет плата Arduino micro (Arduino Leonardo) обязательно с чипом Atmega 32u4. Другие не подойдут, так как не определяются системой как HID устройство, и придется долго настраивать аппаратную и программную составляющую.
Можете выбрать следующие:

Как только вы заполучили свою новую плату, скачиваем и устанавливаем последнюю версию Arduino IDE с офф. сайта Arduino.cc
Пробуем подключить, она должна у вас определится в устройствах как Mikro или Leonardo.
Если не появляется, тогда устанавливаем драйвера, для не оригинальных плат с алиэкспресс нужен спец драйвер CH340 (ch341ser), пробуйте с разных сайтов, даже с одинаковым названием, они почему-то разные.
Вот тут можно посмотреть драйвер
Запоминаем СОМ порт!
Открываем Arduino IDE
Настраиваем нашу плату:

Закидываем скретч отсюда: https://forum.uokit.com/index.php?s=&sh. st&p=436373
устаревший скетч с ошибкой. Используйте скетч из ссылки выше.
#include
int i = 0;
int trigerKey = 0;
int lengthStr = 0;
int key[20];
int tmDelayValue;
String tmDelayStr;
void setup() Serial.begin(9600);
Keyboard.begin();
>
void loop() // Собираем информацию из порта
while (Serial.available()) key[i++] = Serial.read();
delay(5);
>
// Триггер, что данные пришли
if (i != 0 && lengthStr == 0) lengthStr = i;
i = 0;
>
if (lengthStr != 0)
for (i = 0; i <= lengthStr; i++)delay(5);
//Находим задержку с которой необходимо нажимать кнопки
if (trigerKey == 0) if (key[i] == 124) tmDelayValue = tmDelayStr.toInt();
trigerKey = 1;
i++;
>
else tmDelayStr += char (key[i]);
>
>
//Находим и нажимаем спец кнопки если необходимо
if (trigerKey == 1) if (key[i] == 94) //94 - символ "^"
if (key[i] == 64) //64 - символ "@"
if (key[i] == 126) //126 - символ "~"
if (key[i] == 124) //124 - символ "|"
>
//Нажимаем по очереди остальные кнопки с задержкой
if (trigerKey == 2) delay(tmDelayValue);
Keyboard.print(char (key[i]));
>
>
// Сбрасываем все
Keyboard.releaseAll();
i = 0;
trigerKey = 0;
lengthStr = 0;
tmDelayStr = "";
>
>

заливаем его в плату.
Должно написать «Загрузка завершена»
Теперь переходим в Пилот
Добавляем функцию
--lua
local function sendKey (symbol)
file = io.open("COM7","w") --меняем только номер COM порта, остальное не трогаем
file:write(symbol)
file:close()
end
Пользоваться так: sendKey («1000|^|axv»)
пишем в кавычках
1. До первой вертикальной черты это задержка между каждым нажатием кнопок в мс.
2. После первой черты и до второй это спец символы (~@^, такие как настроены в Пилоте, другие не используйте так как ничего все равно работать не будет), если символы не нужны просто удалите их, 2 вертикальные черты обязательны.
3. Набор символов которые необходимо нажать (каждая кнопка будет нажиматься через заданный интервал), русские символы не работают.
PS в данном примере CTRL+a, CTRL+x, CTRL+v, это чтобы вы могли проверить правильно ли работает или нет. Вверх
8.3.2020, 11:50
Arduino позволяет эмулировать нажатия клавиш клавиатуры и мыши, в том числе в приложениях, которые блокируют нажатия.
Может поворачивать камеру в шутерах и играх, в которых камера поворачивается с зажатой правой кнопкой мыши.
Работает только с активным окном.
Пилот версии 2.41 или выше. Запускать от администратора.
Извлечь архив, файл arduino.lua закинуть в папку, где находится exe пилота. Скетч загрузить в ардуино.
Для работы функций мыши нужно в настройках мыши снять галочку ‘Включить повышенную точность установки указателя’.
В функцию get_port (2341, 8036) нужно передавать vid и pid ардуино. Узнать их можно в Arduino IDE, пункт меню ‘Инструменты’, ‘Получить информацию о плате’.
При переполнении буфера, хотя такого не должно быть, 3 секунды будет гореть встроенный светодиод L. В этом случае нужно увеличить паузы между нажатиями клавиш мыши/клавиатуры.
Все координаты в командах мыши указывать абсолютные, т. е. относительно левого верхнего угла экрана.
Список функций
get_port (vid, pid) — узнать в каком com порте находится ардуино
set_delay_key (ms) — установить задержку нажатий клавиатуры
set_delay_mouse (ms) — установить задержку нажатий мыши
set_delay_mousemove(ms) — установить паузу в мсек между каждым шагом перемещения курсора, чем меньше, тем быстрее перемещается курсор
set_offset_mousemove(step) — шаг перемещения курсора от 1 до 127, чем больше, тем быстрее перемещается курсор.
set_random_delay_key(random) — рандом от 0 до 9 мсек между нажатием и отпусканием клавиш клавиатуры
set_random_delay_mouse(random) — рандом от 0 до 4 мсек между нажатием и отпусканием клавиш
key (code) — нажать клавишу клавиатуры
text (text) — отослать текст, в том числе русские символы
key_down (code) — зажать (не отжимая) клавишу клавиатуры
key_up (code) — отжать клавишу клавиатуры
mouse.move (x, y) — переместить мышь
mouse.click (x, y, button) — кликнуть мышью, button должен содержать код клавиши мыши
mouse.left (x, y) — клик левой кнопкой
mouse.right (x, y) — клик правой кнопкой
mouse.middle (x, y) — клик средней кнопкой
mouse.dbl (x, y, button) — двойной клик, button должен содержать код клавиши мыши
mouse.left_dbl (x, y) — двойной клик левой кнопкой мыши
mouse.right_dbl (x, y) — двойной клик правой кнопкой мыши
mouse.middle_dbl (x, y) — двойной клик средней кнопкой мыши
mouse.down (x, y, button) — зажать (не отжимая) кнопку мыши, button должен содержать код клавиши мыши
mouse.left_down (x, y) — зажать (не отжимая) левую кнопку мыши
mouse.right_down (x, y) — зажать (не отжимая) правую кнопку мыши
mouse.middle_down (x, y) — зажать (не отжимая) среднюю кнопку мыши
mouse.up (x, y, button) — отжать кнопку мыши, button должен содержать код клавиши мыши
mouse.left_up (x, y) — отжать левую кнопку мыши
mouse.right_up (x, y) — отжать правую кнопку мыши
mouse.middle_up (x, y) — отжать среднюю кнопку мыши
mouse.drag (x, y, x2, y2) — зажать левую кнопку мыши в точке x y, переместить в точку x2 y2
mouse.wheel_up (x, y, count) — прокручивание колёсика мыши вверх, count — насколько щелчков прокрутить
mouse.wheel_down (x, y, count) — прокручивание колёсика мыши вниз, count — насколько щелчков прокрутить
Список многосимвольных клавиш
mouse_left_button = 1
mouse_right_button = 2
mouse_middle_button = 4
left_ctrl = 0x80
left_shift = 0x81
left_alt = 0x82
left_gui = 0x83
right_ctrl = 0x84
right_shift = 0x85
right_alt = 0x86
right_gui = 0x87
up_arrow = 0xDA
down_arrow = 0xD9
left_arrow = 0xD8
right_arrow = 0xD7
backspace = 0xB2
tab = 0xB3
enter = 0xB0
esc = 0xB1
insert = 0xD1
delete = 0xD4
page_up = 0xD3
page_down = 0xD6
home = 0xD2
[«end»] = 0xD5
caps_lock = 0xC1
f1 = 0xC2
f2 = 0xC3
f3 = 0xC4
f4 = 0xC5
f5 = 0xC6
f6 = 0xC7
f7 = 0xC8
f8 = 0xC9
f9 = 0xCA
f10 = 0xCB
f11 = 0xCC
f12 = 0xCD
F1 = 0xC2
F2 = 0xC3
F3 = 0xC4
F4 = 0xC5
F5 = 0xC6
F6 = 0xC7
F7 = 0xC8
F8 = 0xC9
F9 = 0xCA
F10 = 0xCB
F11 = 0xCC
F12 = 0xCD
Пример использования клавиатуры
--lua
local hw = require'arduino'
hw.com = hw.get_port (2341, 8036) -- указать vid и pid ардуино
if hw.com < 1 then -- если номер порта меньше 1
log ('error = ' .. tostring(hw.com)) -- код ошибки, если 0 значит устройство с указанными vip и pid не найдено
end_script ()
end
hw.set_delay_key (20) -- установить паузу между нажатиями клавиш клавиатуры
hw.set_random_delay_key(10) -- установить рандом между нажатием и отпускание клавиш
-- т. е. между нажатием и отпусканием клавиши будет пауза от 20 до 29 мсек
wait (3000) -- пауза 3 секунды чтобы переключиться на нужное окно
hw.key ('k') -- нажать клавишу 'k'
hw.key (hw.enter) -- нажать 'Enter'
wait (1000) -- пауза 1 сек.
hw.key_down ('s') -- зажать клавишу 's'
wait (3000) -- пауза 3 сек., при этом клавиша будет зажата
hw.key_up ('s') -- отпустить клавишу 's'
hw.key (hw.enter) -- нажать 'Enter'
hw.text ('Hello Привет') -- напечатать текст
hw.key ('V') -- нажать Shift+'v'
Пример использования мыши
--lua
local hw = require'arduino'
hw.com = hw.get_port (2341, 8036) -- указать vid и pid ардуино
if hw.com < 1 then -- если номер порта меньше 1
log ('error = ' .. tostring(hw.com)) -- код ошибки
end_script ()
end
hw.set_delay_mouse (20) -- установить паузу между нажатиями клавиш мыши
hw.set_offset_mousemove(4) -- шаг перемещения курсора
hw.set_random_delay_mouse(10) -- установить рандом между нажатиями клавиш мыши
-- т. е. между нажатием и отпусканием кнопки мыши будет пауза от 20 до 29 мсек.
hw.mouse.left (200, 100) -- клик левой кнопкой мыши в координатах 200, 100
hw.mouse.right (200, 100) -- клик правой кнопкой мыши
wait (3000) -- пауза 3 секунды
hw.mouse.left_dbl (35, 35) -- двойной клик левой кнопкой мыши
wait (2000)
hw.mouse.left_down (200, 200) -- зажать левую кнопку мыши
wait(500)
hw.mouse.left_up (900, 300) -- отпустить левую кнопку мыши
Как сделать кликер в ардуино
При подключении платы Digispark к USB компьютера, она определяется как компьютерная мышь.
Принцип работы заключается в том, что при нажатии на кнопку эмитируется нажатие левой кнопки мыши в бесконечном цикле с рандомной задержкой между кликами. За задержку отвечает переменная “j” и она имеет два параметра, это значения 200 и 3000. В нашем случае величина задержки будет генерироваться в пределах от 200 миллисекунд до 3000 миллисекунд.
Остановить цикл можно повторным нажатием на кнопку, или отсоединением платы от компьютера.
Переменная “j” помечена комментарием //НАСТРОЙКА! Настройте её на свое усмотрение и загрузите скетч на плату.
Как прошить плату Digispark на базе микроконтроллера ATtiny 85 смотрите по этой ссылке www.kolotushkin.com/Как прошить плату Digispark на базе микроконтроллера ATtiny 85
//Начало скетча
#include "DigiMouse.h" const int buttonPin = 1; int buttonState = 0; int i = 0;//переменная для цикла while int j = random (200, 3000);//НАСТРОЙКА! void setup() pinMode(buttonPin, INPUT);//определяем переменную buttonPin как вход DigiMouse.begin(); > void loop() buttonState = digitalRead(buttonPin);//проверка состояния кнопки if (buttonState == HIGH) delay(500); //если кнопка нажата, то сделать паузу на 500 мс и перейти к while while (i 1) unsigned long currentTime; //Переменная текущего времени if (millis() - currentTime > j) currentTime = millis(); j = random (200, 3000);//НАСТРОЙКА! DigiMouse.setButtons(1 <0); //нажать на левую кнопку мыши //DigiMouse.setButtons(2 <<0);//нажать на правую кнопку мышиDigiMouse.delay(50);//Задержка 50 миллисекунд DigiMouse.setButtons(0);//отпустить все кнопки DigiMouse.delay(50);//Задержка 50 миллисекунд > buttonState = digitalRead(buttonPin); //проверка состояния кнопки if (buttonState == HIGH) delay(500); // Если кнопка нажата, то сделать паузу на 500 мс и выйти из цикла break; > > > >
//Конец скетча
//Дополнительные команды
DigiMouse.moveX(20); //переместить курсор вправо на 20 пикселей DigiMouse.moveX(-20); //переместить курсор влево на 20 пикселей DigiMouse.moveY(20); //переместить курсор вниз на 20 пикселей DigiMouse.moveY(-20); //переместить курсор вверх на 20 пикселей DigiMouse.scroll(10); //крутить колесико вперед на 10 DigiMouse.scroll(10); //крутить колесико назад на 10
В конце скетча имеются Дополнительные команды! На тот случай если вы захотите добавить функции к устройству.
После загрузки припаяйте кнопку к контактам P1 и 5V, как показано на этой схеме.
О том как сделать такую же кнопку смотрите статью “Кнопка Лентяйка для World of Tanks” по этой ссылке www.kolotushkin.com/Кнопка Лентяйка для World of Tanks
Видео версия проекта «Автокликер своими руками на базе Digispark Attiny85.»
Творческая мастерская Мастер Колотушкин 2024
Проекты на базе Arduino для начинающих, электронные самоделки своими руками.
Кликер своими руками
Попросил меня на днях товарищ помочь с одной задачкой: управлять компом с аудиопроигрывателем, установленном на ноутбуке с Windows, с помощью маленького аппаратного пультика. Просил всякие ИК пульты не предлагать. И сделать AVR-е, коих у него осталось некоторое немалое количество, пристраивать потихоньку надо.
Постановка задачи
Задача, очевидно, делится на две части:
- Железячное, работающее на микроконтроллере, и
- Программное, работающее на компьютере и управляющее тем, что на нём находится.
Раз уж работаем с AVR, то почему бы не Arduino?
Поставим задачу.
Аппаратная платформа:
HW1. Управление ведётся кнопками без фиксации;
HW2. Обслуживаем 3 кнопки (в общем случае сколько не жалко);
HW3. Нажатием считается удерживание кнопки не менее 100 миллисекунд;
HW4. Более длинные нажатия игнорируются. Обработка более 1 кнопки за раз не выполняется;
HW5. При нажатии кнопки запускается некоторое действие на компьютере;
HW6. Обеспечить интерфейс связи с компьютером через встроенный Serial/USB-преобразователь;
Программная платформа:
SW1. Обеспечить интерфейс связи с компьютером через выбираемый последовательный порт;
SW2. Преобразовывать приходящие по интерфейсу связи команды в события операционной системы, доставляемые до нужного аудиоплеера.
SW3. Приостановка обработки команд. В том числе по команде с пульта.
Ну и дополнительное требование: если это не вносит серьёзных затрат времени, сделать решения максимально универсальными.
Проектирование и решение
HW1

Кнопки кнопки пребывают в положении «нажато» непродолжительное время. Кроме того, кнопки могут дребезжать (то есть формировать множество срабатываний за короткий промежуток времени из-за нестабильного контакта).
К прерываниям их подключать нет смысла — не те времена отклика нужны, чтобы этим заморачиваться. Будем читать их состояния с цифровых пинов. Для обеспечения стабильного чтения кнопки в ненажатом состоянии необходимо подключить входной пин к земле (pull-down) или к питанию (pull-up) через подтягивающий резистор. Воспользуемся встроенным pull-up резистором не будем делать дополнительный дискретный элемент на схеме. С одной стороны кнопку подключим к нашему входу, другой — к земле. Вот что получается:
И так — для каждой кнопки.
HW2
Кнопок надо несколько, поэтому нам нужно некоторое количество однородных записей о том, как кнопки опрашивать и что надо делать, если она нажата. Смотрим в сторону инкапсуляции и делаем класс кнопки Button , который содержит в себе номер пина, с которого ведётся опрос (и сам же его инициализирует), и команду, которую надо послать в порт. С тем, что из себя представляет команда, разберёмся позже.
Класс кнопки будет выглядеть примерно так:
Код класса Button
class Button < public: Button(uint8_t pin, ::Command command) : pin(pin), command(command) <>void Begin() < pinMode(pin, INPUT); digitalWrite(pin, 1); >bool IsPressed() < return !digitalRead(pin); >::Command Command() const < return command; >private: uint8_t pin; ::Command command; >;
После этого шага у нас кнопки стали универсальными и безликими, но с ними можно работать единообразно.
Соберём кнопки воедино и назначим им пины:
Button buttons[] = < Button(A0, Command::Previous), Button(A1, Command::PauseResume), Button(A2, Command::Next), >;
Инициализация всех кнопок делается вызовом метода Begin() для каждой кнопки:
for (auto &button : buttons)
Для того, чтобы определить, какая кнопка нажата, будем перебирать кнопки и проверять, нажато ли что-нибудь. Возвращаем индекс кнопки, либо одно из спецзначений: «не нажато ничего» и «нажато более одной кнопки». Спецзначения, разумеется, не могут пересекаться с допустимыми значениями номеров кнопок.
GetPressed()
int GetPressed() < int index = PressedNothing; for (byte i = 0; i < ButtonsCount; ++i) < if (buttons[i].IsPressed()) < if (index == PressedNothing) < index = i; >else < return PressedMultiple; >> > return index; >
HW3
Кнопки будем опрашивать с некоторым периодом (скажем, 10 мс), и будем считать, что нажатие произошло, если одна и та же кнопка (и ровно одна) удерживалась заданное количество циклов опроса. Делим время фиксации (100 мс) на период опроса (10 мс), получаем 10.
Заведём декрементный счётчик, в который записываем 10 при первой фиксации нажатия, и декрементируем на каждом периоде. Как только он переходит из 1 в 0, запускаем обработку (см HW5)
HW4
Если счётчик уже равен 0, никаких действий не выполняется.
HW5
Как было сказано выше, с каждой кнопкой ассоциирована выполняемая команда. Она должна быть передана через коммуникационный интерфейс.
На этом этапе можно реализовать стратегию работы клавиатурой.
Реализация главного цикла
void HandleButtons() < static int CurrentButton = PressedNothing; static byte counter; int button = GetPressed(); if (button == PressedMultiple || button == PressedNothing) < CurrentButton = button; counter = -1; return; >if (button == CurrentButton) < if (counter >0) < if (--counter == 0) < InvokeCommand(buttons[button]); return; >> > else < CurrentButton = button; counter = PressInterval / TickPeriod; >> void loop()
HW6
Интерфейс связи должен быть понятным и отправителю, и получателю. Поскольку последовательный интерфейс имеет единицу передачи данных в 1 байт и имеет байтовую синхронизацию, то нет особого смысла городить что-то сложное и ограничимся передачей одного байта на команду. Для удобства отладки сделаем передачу одного ASCII-символа на команду.
Реализация на Arduino
Теперь собираем. Полный код реализации показан ниже под спойлером. Для его расширения достаточно указать ASCII-код новой команды и привязать к ней кнопку.
Можно, конечно, было бы просто для каждой кнопки явно указать код символа, но мы так делать не будем: именование команд нам пригодится при реализации клиента для ПК.
Полная реализация
const int TickPeriod = 10; //ms const int PressInterval = 100; //ms enum class Command : char < None = 0, Previous = 'P', Next = 'N', PauseResume = 'C', SuspendResumeCommands = '/', >; class Button < public: Button(uint8_t pin, Command command) : pin(pin), command(command) <>void Begin() < pinMode(pin, INPUT); digitalWrite(pin, 1); >bool IsPressed() < return !digitalRead(pin); >Command GetCommand() const < return command; >private: uint8_t pin; Command command; >; Button buttons[] = < Button(A0, Command::Previous), Button(A1, Command::PauseResume), Button(A2, Command::Next), Button(12, Command::SuspendResumeCommands), >; const byte ButtonsCount = sizeof(buttons) / sizeof(buttons[0]); void setup() < for (auto &button : buttons) < button.Begin(); >Serial.begin(9600); > enum < PressedNothing = -1, PressedMultiple = -2, >; int GetPressed() < int index = PressedNothing; for (byte i = 0; i < ButtonsCount; ++i) < if (buttons[i].IsPressed()) < if (index == PressedNothing) < index = i; >else < return PressedMultiple; >> > return index; > void InvokeCommand(const class Button& button) < Serial.write((char)button.GetCommand()); >void HandleButtons() < static int CurrentButton = PressedNothing; static byte counter; int button = GetPressed(); if (button == PressedMultiple || button == PressedNothing) < CurrentButton = button; counter = -1; return; >if (button == CurrentButton) < if (counter >0) < if (--counter == 0) < InvokeCommand(buttons[button]); return; >> > else < CurrentButton = button; counter = PressInterval / TickPeriod; >> void loop()
И да, я сделал ещё одну кнопку, чтобы иметь возможность приостановки передачи команд на клиента.
Клиент для ПК
Переходим ко второй части.
Поскольку сложного интерфейса нам не надо, и привязка к Windows, то можно пойти разными путями, кому как нравится: WinAPI, MFC, Delphi, .NET (Windows Forms, WPF и т.д.), или же консольки на тех же платформах (ну, кроме MFC).
SW1
Данное требование закрывается через коммуникацию с последовательным портом на выбранной программной платформе: подключаемся к порту, читаем байты, обрабатываем байты.
SW2
Пожалуй, все видели клавиатуры с мультимедийными клавишами. Каждая клавиша на клавиатуре, в том числе мультимедийная, имеет свой код. Самое простое решение нашей задачи — это имитация нажатий мультимедийных клавиш на клавиатуре. С кодами клавиш можно ознакомиться в первоисточнике — MSDN. Осталось научиться их посылать в систему. Это тоже не сложно: есть в WinAPI функция SendInput.
Каждое нажатие клавиши — это два события: нажатие и отпускание.
Если мы пользуемся C/C++, то можно просто подключить заголовочные файлы. На других языках надо сделать проброс вызовов. Так, например, при разработке на .NET придётся импортировать указанную функцию и описать аргументы. Я выбрал .NET за удобство разработки интерфейса.
Я выделил из проекта только содержательную часть, которая сводится к одному классу: Internals .
Вот его код:
Код класса Internals
internal class Internals < [StructLayout(LayoutKind.Sequential)] [DebuggerDisplay("")] private struct INPUT < public uint Type; public KEYBDINPUT Data; public const uint Keyboard = 1; public static readonly int Size = Marshal.SizeOf(typeof(INPUT)); >[StructLayout(LayoutKind.Sequential)] [DebuggerDisplay("Vk= Scan= Flags= Time= ExtraInfo=")] private struct KEYBDINPUT < public ushort Vk; public ushort Scan; public uint Flags; public uint Time; public IntPtr ExtraInfo; private long spare; >[DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure); private static INPUT[] inputs = < new INPUT < Type = INPUT.Keyboard, Data = < Flags = 0 // Push >>, new INPUT < Type = INPUT.Keyboard, Data = < Flags = 2 // Release >> >; public static void SendKey(Keys key) < inputs[0].Data.Vk = (ushort) key; inputs[1].Data.Vk = (ushort) key; SendInput(2, inputs, INPUT.Size); >>
В нём сначала идёт описание структур данных (отрезано только то, что касается клавиатурного ввода, поскольку мы его имитируем), и собственно импорт SendInput .
Поле inputs — массив из двух элементов, будет использоваться для генерации событий клавиатуры. Нет смысла выделять его динамически, если архитектура приложения предполагает, что вызова SendKey в несколько потоков не будет выполняться.
Собственно, дальше дело техники: заполняем соответствующие поля структур виртуальным кодом клавиши и отправляем в очередь ввода операционной системы.
SW3
Требование закрывается очень просто. Заводится флаг и ещё одна команда, которая обрабатывается особым образом: флаг переключается в противоположное логическое состояние. Если он установлен, то остальные команды игнорируются.
Вместо заключения
Улучшайзингом можно заниматься бесконечно, но это уже совсем другая история. Я не привожу здесь проект Windows-клиента, потому как он предоставляет широкий полёт фантазии.
Для управления медиаплеером посылаем один набор «нажатий» клавиш, если надо управлять презентациями — другой. Можно сделать модули управления, собирать их либо статически, либо в виде подключаемых плагинов. Вообще много чего можно. Главное — желание.