C # 'da programlı olarak tuşa basma olaylarını nasıl oluşturabilirim?


107

Klavyede basılmakta olan bir tuşa benzeyen bir olayı programlı olarak nasıl oluşturabilirim?


6
Sadece olayı ateşlemek için mi ihtiyacınız var?
Daniel A. White

'Gerçek' bir tuşa basmayı simüle etmek için yönetilmeyen koda adım atmanız gerektiğini düşünüyorum.
Jonas B

Evet, sadece olayın ateşlenmesine ihtiyacım var.
Dan Vogel

1
@GONeale: Vay be, üç yıllık bir yorum. Tamam ozaman. Evet, bunun için geçerli kullanımlar var, bu yüzden ilk başta API var. Ancak çok az ve çok uzak. Tecrübelerime göre, birçok kişi bunu, bir problemin üstesinden gelmenin en iyi yolunu gerçekten anlamadıkları için yapıyor, yani, "Düğme tıklama olay işleyicimdeki kodu sadece bir düğmeye tıklandığında değil, çağırmak istiyorum". Bu nedenle, yeni başlayanlar için, gerçekten yapmaları gereken şey o kodu almak, bir işleve atmak ve kodun başka bir yerinden çağırmak olduğunda, bir düğme tıklamasını simüle etmek mantıklı görünüyor.
Ed S.

6
@EdS: Soru tam anlamıyla güzeldi. Bir tuş takımı oluşturmayla ilgili çok fazla ayrıntı ekledim ve yine de aynı cevabı aldım. Tam olarak ihtiyacım olanı aldığımı düşünürsek, bu bana "kalitesiz" bir soru gibi gelmiyor.
Dan Vogel

Yanıtlar:


147

Soru WPF olarak etiketlenmiştir, ancak şimdiye kadarki cevaplar belirli WinForms ve Win32'dir.

Bunu WPF'de yapmak için, bir KeyEventArgs oluşturun ve hedefte RaiseEvent'i çağırın. Örneğin, şu anda odaklanılan öğeye bir Anahtar Ekle KeyDown olayı göndermek için:

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 }
);

Bu çözüm yerel aramalara veya Windows dahili aramalarına dayanmaz ve diğerlerinden çok daha güvenilir olmalıdır. Ayrıca, belirli bir öğe üzerinde bir tuşa basmanın simülasyonunu da sağlar.

Bu kodun yalnızca PreviewKeyDown, KeyDown, PreviewKeyUp ve KeyUp olayları için geçerli olduğunu unutmayın. TextInput olayları göndermek istiyorsanız, bunun yerine şunu yapacaksınız:

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 }
);

Ayrıca şunları unutmayın:

  • Denetimler Önizleme olaylarını almayı bekler, örneğin PreviewKeyDown KeyDown'dan önce gelmelidir

  • Target.RaiseEvent (...) öğesinin kullanılması, olayı hızlandırıcılar, metin oluşturma ve IME gibi meta işleme olmadan doğrudan hedefe gönderir. Bu normalde istediğiniz şeydir. Öte yandan, herhangi bir nedenle gerçek klavye tuşlarını simüle etmek için gerçekten ne yaparsanız, bunun yerine InputManager.ProcessInput () kullanırsınız.


1
Önerinizi az önce denedim, bir etki görmüyorum. Odaklanılan öğeye bir keyDown olay işleyicisi ekledim. Oluşturduğum olay alındı, ancak KeyState Yok, ScanCode 0 ve isDown yanlış. Bu değerleri aldığımı varsayıyorum çünkü klavyenin gerçek durumu bu. Gerçek klavyede bir tuşa basmak, KeyState = Down, isDown = true ve ScanCode'un bir değeri vardır.
Dan Vogel

25
keydown'un ilk kodunu denediğimde "hedef" te hata aldım onu ​​görsele dönüştüremiyorum neden?
kartal

3
Dan, bir değiştiriciyle (ctrl / alt / shift) bir tuşa basmayı nasıl taklit edeceğini biliyor musun? Özellikle InputBinding'i simüle etmem gerekiyor: m_shell.InputBindings.Add (new KeyBinding (m_command, Key.Insert, ModifierKeys.Control | ModifierKeys.Alt));
Shrike

14
Hakkında hedef sorunu, ben kullanarak dışarı çalıştı Keyboard.PrimaryDevice.ActiveSourcebkz stackoverflow.com/questions/10820990/...
OscarRyz

4
Bu cevap çok iyi, ancak @Shrike'ın da belirttiği gibi, değiştiricili bir anahtar göndermek için kullanılamaz. (Örn Ctrl+C.)
ANeves

27

Windows Forms Context olmadan anahtar olaylar üretmek için aşağıdaki yöntemi kullanabiliriz,

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

örnek kod aşağıda verilmiştir:

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;
}

Sanal Anahtarların listesi burada tanımlanmıştır .

Resmin tamamını görmek için lütfen aşağıdaki bağlantıyı kullanın, http://tksinghal.blogspot.in/2011/04/how-to-press-and-hold-keyboard-key.html


Pencereniz üstte olacaksa uygundur. Durumumu kısmen çözdü, teşekkürler!
Sergey

Rajesh'in cevabına ek olarak, bunu mobil platformda yapmak istiyorsanız, "coredll.ddl" dosyasını içe aktarmalısınız
user1123236

21

Ben kullanmadım ama SendKeys istediğini yapabilir.

Etkin uygulamaya tuş vuruşlarını ve tuş vuruşu kombinasyonlarını göndermek için Gönder Tuşları'nı kullanın. Bu sınıf somutlaştırılamaz. Bir sınıfa bir tuş vuruşu göndermek ve programınızın akışına hemen devam etmek için Gönder'i kullanın. Tuş vuruşuyla başlatılan işlemleri beklemek için SendWait'i kullanın.

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

Microsoft'un burada daha fazla kullanım örneği var .


3
SendKeys.Send'i kullanmayı denedim ve şu InvalidOperationException'ı alıyorum: "Uygulama Windows mesajlarını işlemediğinden SendKeys bu uygulama içinde çalışamaz. Mesajları işlemek için uygulamayı değiştirin veya SendKeys.SendWait yöntemini kullanın." SendKey.SendWait'i kullanmanın bir etkisi yoktur.
Dan Vogel

Önemli olayı kendinize göndermediğinizden emin olun. Olayı göndermeden önce odağı uygun işleme getirin. İkinci bağlantılı makale bu konuda biraz yardım içeriyor.
Michael Petrotta

11

Kolayca! (çünkü işi bizim için zaten başkası yaptı ...)

Önerilen cevaplarla bunu denemek için çok zaman harcadıktan sonra , bir tuşa basmayı simüle etmeyi olabildiğince basitleştiren bu kodepleks projesine rastladım Windows Giriş Simülatörü :

  1. Paketi yükleyin, yapılabilir veya NuGet paket yöneticisinden veya aşağıdaki gibi paket yöneticisi konsolundan yapılabilir:

    Kurulum Paketi Giriş Simülatörü

  2. Bu 2 satırlık kodu kullanın:

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

Ve bu kadar!

-------DÜZENLE--------

Codeplex'teki proje sayfası bazı nedenlerden dolayı işaretlenmiştir, bu NuGet galerisinin bağlantısıdır.


Bu çok iyi çalışıyor, ancak bunu bir tuş kombinasyonu ile nasıl çalıştıracağımı bulamadım,
user1234433222

Tuş kombinasyonu dediğinizde CTRL-C gibi mi demek istiyorsunuz?
Ravid Goldenberg

evet veya bir konsol uygulamasının tam ekrana
geçmesini isteseniz

1
Bunu yapabilirsiniz, ben denememiş olsam da, sadece inputSimulator.Keyboard.ModifiedKeyStroke (VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C) kullanın;
Ravid Goldenberg

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.