Comment détecter la actuellement pressée?

dans Windows Forms , vous pouvez connaître, à tout moment, la position actuelle du curseur grâce à la classe Curseurs .

La même chose ne semble pas être disponible pour le clavier. Est-il possible de savoir si, par exemple, la touche Shift est pressée?

est-il absolument nécessaire de retracer toutes les notifications de clavier (événements KeyDown et KeyUp)?

121
demandé sur Peter Mortensen 2009-07-09 00:09:09

11 réponses

if ((Control.ModifierKeys & Keys.Shift) != 0) 

cela sera également vrai si Ctrl + Shift est en baisse. Si vous voulez vérifier si Shift seul est pressé,

if (Control.ModifierKeys == Keys.Shift)

si vous êtes dans une classe qui hérite Control (tel qu'un formulaire), vous pouvez supprimer le Control.

157
répondu SLaks 2013-12-26 21:54:16

le code ci-dessous indique comment détecter presque toutes les touches actuellement pressées, pas seulement la touche Shift .

private KeyMessageFilter m_filter = new KeyMessageFilter();

private void Form1_Load(object sender, EventArgs e)
{
    Application.AddMessageFilter(m_filter);
}


public class KeyMessageFilter : IMessageFilter
{
    private const int WM_KEYDOWN = 0x0100;
    private const int WM_KEYUP = 0x0101;
    private bool m_keyPressed = false;

    private Dictionary<Keys, bool> m_keyTable = new Dictionary<Keys, bool>();

    public Dictionary<Keys, bool> KeyTable
    {
        get { return m_keyTable; }
        private set { m_keyTable = value; }
    }

    public bool IsKeyPressed()
    {
        return m_keyPressed;
    }

    public bool IsKeyPressed(Keys k)
    {
        bool pressed = false;

        if (KeyTable.TryGetValue(k, out pressed))
        {
            return pressed;
        }

        return false;
    }

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            KeyTable[(Keys)m.WParam] = true;

            m_keyPressed = true;
        }

        if (m.Msg == WM_KEYUP)
        {
            KeyTable[(Keys)m.WParam] = false;

            m_keyPressed = false;
        }

        return false;
    }
}
52
répondu Ash 2017-02-27 10:21:54

vous pouvez également regarder les suivants si vous Système de référence.Windows.Entrée

if (Keyboard.Modifiers == ModifierKeys.Shift)

l'espace de nom du clavier peut également être utilisé pour vérifier l'état pressé d'autres touches avec le clavier.IsKeyDown (Key), ou si vous êtes abonné à un événement KeyDownEvent ou similaire, les arguments event contiennent une liste des clés actuellement pressées.

22
répondu Jeff Wain 2009-07-08 20:35:52

la plupart de ces réponses sont soit beaucoup trop compliquées ou ne semblent pas fonctionner pour moi (par exemple Système.Windows.D'entrée il ne semble pas exister). Puis j'ai trouvé un code qui fonctionne très bien.: http://www.switchonthecode.com/tutorials/winforms-accessing-mouse-and-keyboard-state

dans le cas où la page disparaîtrait dans le futur je poste le code source pertinent ci-dessous:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MouseKeyboardStateTest
{
  public abstract class Keyboard
  {
    [Flags]
    private enum KeyStates
    {
      None = 0,
      Down = 1,
      Toggled = 2
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern short GetKeyState(int keyCode);

    private static KeyStates GetKeyState(Keys key)
    {
      KeyStates state = KeyStates.None;

      short retVal = GetKeyState((int)key);

      //If the high-order bit is 1, the key is down
      //otherwise, it is up.
      if ((retVal & 0x8000) == 0x8000)
        state |= KeyStates.Down;

      //If the low-order bit is 1, the key is toggled.
      if ((retVal & 1) == 1)
        state |= KeyStates.Toggled;

      return state;
    }

    public static bool IsKeyDown(Keys key)
    { 
      return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
    }

    public static bool IsKeyToggled(Keys key)
    { 
      return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
    }
  }
}
15
répondu parsley72 2012-02-20 03:59:12

depuis la version 3.0 de .net Framework, il est possible d'utiliser la méthode Keyboard.IsKeyDown du nouvel espace de noms System.Windows.Input . Par exemple:

if (((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && Keyboard.IsKeyDown(Key.F))
{
    // CTRL + F is currently pressed
}

même si elle fait partie de WPF, cette méthode fonctionne très bien pour les applications WinForm (à condition que vous ajoutiez des références à PresentationCore.dll et WindowsBase.dll ). Malheureusement, les versions 3.0 et 3.5 de la méthode Keyboard.IsKeyDown n'ont pas fonctionné pour WinForm applications. Par conséquent, si vous voulez l'utiliser dans une application WinForm, vous aurez besoin de cibler .net Framework 4.0 ou plus tard pour qu'il fonctionne.

10
répondu Steven Doggart 2014-10-08 13:18:34

Vous pouvez P/Invoke jusqu'à la Win32 GetAsyncKeyState pour tester n'importe quelle touche sur le clavier.

vous pouvez passer dans les valeurs des touches enum (par exemple les touches.Shift) à cette fonction, donc il ne nécessite que quelques lignes de code pour l'ajouter.

8
répondu Jason Williams 2015-12-15 15:46:06
if ((ModifierKeys == Keys.Control) && ((e.KeyChar & (char)Keys.F) != 0))
{
     // CTRL+F pressed !
}
5
répondu Mahdi 2011-09-21 08:01:03
if (Form.ModifierKeys == Keys.Shift)

fonctionne pour une zone de texte si le code ci-dessus est dans l'événement keydown de la forme et aucun autre contrôle ne capture l'événement keydown pour la clé vers le bas.

on peut aussi souhaiter arrêter le traitement des clés avec:

e.Handled = true;
2
répondu g.g 2015-12-10 17:10:09
if (Control.ModifierKeys == Keys.Shift)
    //Shift is pressed

la position du curseur x/y est une propriété, et une touche (comme un clic de souris/mousemove) est un événement. La meilleure pratique consiste habituellement à laisser l'interface être axée sur les événements. A peu près le seul moment où vous auriez besoin de ce qui précède est si vous essayez de faire un truc shift + mouseclick.

2
répondu Rob Elliott 2015-12-15 15:46:54

Le meilleur moyen que j'ai trouvé pour gérer le clavier sur un Windows Forms forme est d'après la frappe et avant le contrôle reçoit l'événement. Microsoft maintient une propriété de niveau Form intégrée appelée .KeyPreview pour faciliter cette chose précise:

public frmForm()
{
    // ...
    frmForm.KeyPreview = true;
    // ...
}

alors les événements _KeyDown, _keyypress et / ou _KeyUp du formulaire peuvent être combinés pour accéder aux événements d'entrée avant que le contrôle de forme focalisé ne voit jamais ils, et vous pouvez appliquer la logique handler pour capturer l'événement là ou le laisser passer au contrôle de forme focalisé.

bien qu'elle ne soit pas aussi gracieuse que l'architecture de routage d'événements XAML , elle simplifie la gestion des fonctions au niveau des formulaires dans les Winformes. Voir les notes du MSDN sur le clavier pour les mises en garde.

2
répondu Hardryv 2015-12-15 15:49:20

Dans WinForms:

if( Form.ModifierKeys == Keys.Shift )

cela ressemble à un duplicata de la question sur le débordement de la pile la touche Detect Shift est-elle pressée sans utiliser d'événements dans les formes Windows? .

0
répondu Will Eddins 2017-05-23 12:10:30