2009-10-29 7 views
96

Как я могу программно создать событие, которое будет имитировать нажатие клавиши на клавиатуре?Как я могу программно генерировать события нажатия клавиш на C#?

+6

Вам нужно только событие, чтобы его запустить? –

+0

Думаю, вам нужно будет войти в неуправляемый код, чтобы имитировать «настоящий» нажатие. –

+0

Запахи уродливого взлома ... –

ответ

133

Вопрос отмечен WPF, но ответы до сих пор являются конкретными WinForms и Win32.

Чтобы сделать это в WPF, просто создайте KeyEventArgs и вызовите RaiseEvent на цель. Например, чтобы отправить ключ KeyDown события вставки в настоящее время сосредоточено элемент:

var key = Key.Insert;     // Key to send 
    var target = Keyboard.FocusedElement; // Target element 
    var routedEvent = Keyboard.KeyDownEvent; // Event to send 

    target.RaiseEvent(
    new KeyEventArgs(
     Keyboard.PrimaryDevice, 
     PresentationSource.FromVisual(target), 
     0, 
     key) 
    { RoutedEvent=routedEvent } 
); 

Это решение не зависит от нативных вызовов или Windows, внутренностей и должно быть гораздо более надежным, чем другие. Он также позволяет моделировать нажатия клавиш на конкретном элементе.

Обратите внимание, что этот код применим только к событиям PreviewKeyDown, KeyDown, PreviewKeyUp и KeyUp. Если вы хотите, чтобы отправить события TextInput вы будете делать это вместо:

var text = "Hello"; 
    var target = Keyboard.FocusedElement; 
    var routedEvent = TextCompositionManager.TextInputEvent; 

    target.RaiseEvent(
    new TextCompositionEventArgs(
     InputManager.Current.PrimaryKeyboardDevice, 
     new TextComposition(InputManager.Current, target, text)) 
    { RoutedEvent = routedEvent } 
); 

отметить также, что:

  • управления ожидают получить Preview события, например PreviewKeyDown должен предшествовать KeyDown

  • Использование target.RaiseEvent (...) отправляет событие непосредственно на цель без метаобработки, например ускорителей, текстовой композиции и IME. Обычно это то, что вы хотите. С другой стороны, если вы действительно делаете , что бы имитировать фактические клавиши клавиатуры по какой-то причине, вместо этого вы должны использовать InputManager.ProcessInput().

+1

Я просто попробовал ваше предложение, я не вижу никакого эффекта. Я привязал обработчик события keyDown к сфокусированному элементу. Событие, которое я поднял, получено, но KeyState - None, ScanCode равен 0, а isDown - false. Я предполагаю, что получаю эти значения, потому что это фактическое состояние клавиатуры. Нажатие клавиши на фактической клавиатуре KeyState = Down, isDown = true, а ScanCode имеет значение. –

+0

Да, KeyState = None и IsDown = false, потому что они дают фактическое состояние клавиатуры.Но KeyState, IsDown и ScanCode не используются нигде в Microsoft WPF-коде, поэтому, если у вас нет пользовательских элементов управления, которые их используют, это не имеет значения. Ваша проблема более вероятна, что код ищет PreviewKeyDown вместо KeyDown или использует события TextInput, которые отправляются отдельно (например, TextBox использует события TextInput), или вы хотите вызывать ускорители, для которых вам нужен InputManager. ProcessEvent. Но обычно вы не хотите этого делать. –

+0

Я отредактировал свой ответ и добавил подробности о том, как использовать события TextInput. –

22

Я не использовал его, но SendKeys может делать то, что вы хотите.

Используйте SendKeys для отправки нажатия клавиш и комбинации клавиш для активного применения. Этот класс не может быть создан . Чтобы отправить нажатие клавиши на класс и сразу же начните с поток вашей программы, используйте «Отправить». К дождитесь появления каких-либо процессов, начатых нажатием клавиши , используйте команду SendWait.

System.Windows.Forms.SendKeys.Send("A"); 
System.Windows.Forms.SendKeys.Send("{ENTER}"); 

Microsoft имеет еще несколько примеров использования here.

+3

Я попытался использовать SendKeys.Send, и я получаю это InvalidOperationException: «SendKeys не может запускаться внутри этого приложения, потому что приложение не обрабатывает сообщения Windows. Либо измените приложение для обработки сообщений, либо используйте метод SendKeys.SendWait». Использование SendKey.SendWait не влияет. –

+0

Убедитесь, что вы не отправляете ключевое событие самому себе. Перед отправкой события переключите фокус на соответствующий процесс. Вторая связанная статья имеет некоторую помощь в этом. –

23

Для создания ключевых событий без контекста Windows Forms, Мы можем использовать следующий метод,

[DllImport("user32.dll")] 
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); 

пример кода приведен ниже:

const int VK_UP = 0x26; //up key 
const int VK_DOWN = 0x28; //down key 
const int VK_LEFT = 0x25; 
const int VK_RIGHT = 0x27; 
const uint KEYEVENTF_KEYUP = 0x0002; 
const uint KEYEVENTF_EXTENDEDKEY = 0x0001; 
int press() 
{ 
    //Press the key 
    keybd_event((byte)VK_UP, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); 
    return 0; 
} 

Список виртуальных клавиш определены here.

Чтобы получить полную картину, пожалуйста, используйте ссылку ниже, http://tksinghal.blogspot.in/2011/04/how-to-press-and-hold-keyboard-key.html

+0

Подходит, если ваше окно будет сверху. Он частично решил мою ситуацию, спасибо! – Sergey

+0

В дополнение к ответу Раджеша, если вы хотите сделать это на мобильной платформе, вы должны импортировать «coredll.ddl» – user1123236

8

Легко! (потому что кто-то уже сделал работу для нас ...)

После тратить много времени на то, чтобы это с предложенными ответами я наткнулся на этот Codeplex проект Windows Input Simulator который сделал это просто, как может быть, чтобы имитировать ключ пресса:

  1. Установите пакет, можно сделать или с помощью менеджера пакетов NuGet или от менеджера консоли пакета, как:

    Install-Package InputSimulator

  2. Используйте это 2 строки кода:

    inputSimulator = new InputSimulator() inputSimulator.Keyboard.KeyDown(VirtualKeyCode.RETURN)

И это все!

+0

Это работает очень хорошо, однако я не смог найти, как сделать эту работу с помощью комбинации клавиш , – Werdna

+0

Когда вы говорите, что сочетание клавиш вы имеете в виду как CTRL-C? – petric

+0

да или даже если вы хотите, чтобы консольное приложение отображалось в полноэкранном режиме, например, Alt-Enter, я знаю, что вы можете использовать F11 для входа в полноэкранный режим, но было бы неплохо увидеть, будет ли работать Alt-Enter :) – Werdna

Смежные вопросы