【问题标题】:Check if non-modifier keys are in pressed state during mouse events检查鼠标事件期间非修饰键是否处于按下状态
【发布时间】:2015-01-21 19:25:59
【问题描述】:

根据msdn 文档,在 WinForms 中,我可以检查修饰键(SHIFTCTRLALT)是否处于按下状态状态,在鼠标事件期间。例如:

private void button1_Click(object sender, System.EventArgs e)
{
   /* If the CTRL key is pressed when the 
    * control is clicked, hide the control. */ 
   if(Control.ModifierKeys == Keys.Control)
   {
     ((Control)sender).Hide();
   }
}

如何检查非修饰键,例如 Space 在鼠标移动事件期间是否处于按下状态?

【问题讨论】:

标签: c# winforms keyboard mouseevent


【解决方案1】:

您有多种选择:

选项 1:将自定义消息过滤器添加到您的应用程序:

private KeyMessageFilter _filter = new KeyMessageFilter();

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

public class KeyMessageFilter : IMessageFilter
{
    private Dictionary<Keys, bool> _keyTable = new Dictionary<Keys, bool>();

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

    public bool IsKeyPressed()
    {
        return _keyPressed; 
    }

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

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

        return false; 
    }

    private const int WM_KEYDOWN = 0x0100;

    private const int WM_KEYUP = 0x0101;

    private bool _keyPressed = false;


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

            _keyPressed = true;
        }

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

            _keyPressed = false;
        }

        return false;        
}

选项 2:使用之前链接的 GetKeyState API 函数:

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

选项 3: 自己处理 KeyDown 和 KeyUp 事件。这不是最好的方法,但对于小型应用程序会很好。

【讨论】:

  • 最好将问题标记为重复,提供已回答问题的链接,而不是复制/粘贴该问题的答案,并将其作为您自己的答案传递:stackoverflow.com/a/1927644/580053跨度>
猜你喜欢
  • 2012-10-11
  • 2014-03-31
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2012-06-02
  • 1970-01-01
  • 2013-04-06
相关资源
最近更新 更多