简体   繁体   中英

Capturing ctrl + multiple key downs

Is there an easy way to capture a ctrl + key1 , key2 event in a winforms app similar to that in visual studio such as ctrl + e , c = comment out selected lines?

I am currently overriding my forms OnKeyDown event:

protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        if (e.Control && e.KeyCode.ToString() == "N")
        {
            //do something...
        }
    }

The article in the comment may have been for WPF but the idea in it can still be used

Construct a class such as

    public class MultiKeyGesture
    {
        private List<Keys> _keys;
        private Keys _modifiers;
        public MultiKeyGesture(IEnumerable<Keys> keys, Keys modifiers)
        {
            _keys = new List<Keys>(keys);
            _modifiers = modifiers;
            if (_keys.Count == 0)
            {
                throw new ArgumentException("At least one key must be specified.", "keys");
            }
        }

        private int currentindex;
        public bool Matches(KeyEventArgs e)
        {
            if (e.Modifiers == _modifiers && _keys[currentindex] == e.KeyCode)
                //at least a partial match
                currentindex++;
            else
                //No Match
                currentindex = 0;
            if (currentindex + 1 > _keys.Count)
            {
                //Matched last key
                currentindex = 0;
                return true;
            }
            return false;
        }
    }

but ignore the inheritance.

to use it

    private MultiKeyGesture Shortcut1 = new MultiKeyGesture(new List<Keys> { Keys.A, Keys.B }, Keys.Control);
    private MultiKeyGesture Shortcut2 = new MultiKeyGesture(new List<Keys> { Keys.C, Keys.D }, Keys.Control);
    private MultiKeyGesture Shortcut3 = new MultiKeyGesture(new List<Keys> { Keys.E, Keys.F }, Keys.Control);

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        if (Shortcut1.Matches(e))
            BackColor = Color.Green;
        if (Shortcut2.Matches(e))
            BackColor = Color.Blue;
        if (Shortcut3.Matches(e))
            BackColor = Color.Red;
    }

If you only have a two key shortcut, like VS does, you could store the last key pressed in a variable.

private Keys lastKeyPressed = null;

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    if(e.Control && lastKeyPressed != null)
    {
        if(lastKeyPressed == Keys.firstKey && e.KeyCode == Keys.secondKey)
        {
        }
        else if (...) // so on and so forth.
    }
    else if(e.Control)
        lastKeyPressed = e.KeyCode;
}

protected override void OnKeyUp(KeyEventsArgs e)
{
    if(!e.Control)
       lastKeyPressed = null;
}

This would do a two key shortcut, and would reset it when the ctrl key is released. This is just untested pseudo code but its the concept of saving the last pressed key when Ctrl is being held then resetting it when ctrl is released that I'm trying to convey.

Call e.Modifiers for control key and e.KeyCode for the combined key.

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
   // For Tow Key Shortcut.
   if (e.Modifiers == Keys.Control && e.KeyCode == Keys.B)
   {}
   
     // For Triple Key Shortcut.
   if (e.Modifiers.ToString() == (Keys.Shift+", "+Keys.Control) && e.KeyCode == Keys.B)
   {} 
}

// For Form level Key events you must have to set KeyPreview to True;
public Form1()
{
    InitializeComponent();
    this.KeyPreview = true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM