Как нажать клавишу и отпустить ее с помощью C #? - PullRequest
8 голосов
/ 05 октября 2008

Я пишу программу на C #, которая фиксирует сигналы от внешнего устройства и отправляет нажатия клавиш в другое приложение. Я использую SendKeys, и он отлично работает.

SendKeys «нажимает» клавишу, удерживая и отпуская ее немедленно. Я хотел бы нажать и отпустить по желанию.

Мой вопрос: «есть ли способ отправить сигнал« push »на клавишу, а затем сигнал« отпустить »через определенное время?»

Я не уверен, что SendKeys может это сделать. Любая подсказка?

Ответы [ 4 ]

5 голосов
/ 05 октября 2008

Я не думаю, что это возможно из .NET напрямую Вы можете попробовать использовать собственный вызов keybd_event, вызвав функцию p /, как описано здесь: http://pinvoke.net/default.aspx/user32.keybd_event

MSDN для keybd_event здесь: http://msdn.microsoft.com/en-us/library/ms646304(VS.85).aspx

Надеюсь, это поможет!

4 голосов
/ 01 марта 2012

В принятом ответе используется keybd_event, который устарел. Официальный API теперь SendInput. Есть также хорошая обертка для этого в http://inputsimulator.codeplex.com.

Ничто из вышеперечисленного, однако, не в полной мере отвечает сценарию "удержания ключа". Это связано с тем, что удержание клавиши будет генерировать несколько сообщений WM_KEYDOWN, за которыми следует одно сообщение WM_KEYUP после выпуска (вы можете проверить это с помощью Spy ++).

Частота сообщений WM_KEYDOWN зависит от аппаратного обеспечения, настроек BIOS и нескольких настроек Windows: KeyboardDelay и KeyboardSpeed. Последние доступны из Windows Forms (SystemInformation.KeyboardDelay, SystemInformation.KeyboardSpeed).

Используя вышеупомянутую библиотеку Input Simulator, я реализовал метод удержания клавиш, который имитирует реальное поведение. Он await/async готов и поддерживает отмену.

static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs, 
                            int repeatDelayMs, int repeatRateMs, CancellationToken token)
{
    var tcs = new TaskCompletionSource<object>();
    var ctr = new CancellationTokenRegistration();
    var startCount = Environment.TickCount;
    Timer timer = null;
    timer = new Timer(s =>         
    {
        lock (timer)
        {
            if (Environment.TickCount - startCount <= holdDurationMs)
                InputSimulator.SimulateKeyDown(key);
            else if (startCount != -1)
            { 
                startCount = -1; 
                timer.Dispose();
                ctr.Dispose();                    
                InputSimulator.SimulateKeyUp(key);
                tcs.TrySetResult(null);
            }
        }
    });
    timer.Change(repeatDelayMs, repeatRateMs);

    if (token.CanBeCanceled)
        ctr = token.Register(() =>
                       {
                           timer.Dispose();
                           tcs.TrySetCanceled();
                       });
    return tcs.Task;
}
3 голосов
/ 05 октября 2008

Вы можете использовать SendInput или keyb_event, оба являются встроенными функциями API. SendInput имеет некоторые преимущества перед keybd_event, но SendInput доступен только начиная с XP.

Вот ссылка MSDN http://msdn.microsoft.com/en-us/library/ms646310.aspx

Надеюсь, это поможет

1 голос
/ 06 октября 2008

Когда-то я пытался сделать то же самое в powerpoint, чтобы скрыть курсор, а потом остановить слайд-шоу. Но это сложно и сложно, так как в PowerPoint появилось много окон верхнего уровня, а также сложно определить, какая часть эмуляции потерпела неудачу, если она не работает. Изучив очередь сообщений с помощью Spy ++, я заметил, что команда акселератора была отправлена ​​после нажатия клавиши, поэтому вместо этого я эмулировал команду акселератора, и она работает как шарм. Таким образом, вы можете захотеть посмотреть на альтернативу, как это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...