Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测箭头键-一次检测多个键_C#_Visual Studio_Visual Studio 2010_Key - Fatal编程技术网

C# 检测箭头键-一次检测多个键

C# 检测箭头键-一次检测多个键,c#,visual-studio,visual-studio-2010,key,C#,Visual Studio,Visual Studio 2010,Key,我试图制作一个简单的应用程序,让用户可以用箭头移动。到目前为止,我成功地让用户在覆盖ProcessCmdKey()方法的情况下上下左右移动 问题是,我很想让用户也斜着走。喜欢同时向上和向右。我试图寻找一些解决办法,但不幸的是没有任何运气。 我将尝试修改它,使左/右键转动/旋转,因此向上键的意思是“向前”,而不是“向上”。但首先,我需要一次制作两把钥匙 所以问题是,我怎样才能做到,一次使用两个键,对角移动 另外,Atm,我正在图片盒上移动一个椭圆,改变点statek=新点(250470)跳线,所以

我试图制作一个简单的应用程序,让用户可以用箭头移动。到目前为止,我成功地让用户在覆盖ProcessCmdKey()方法的情况下上下左右移动

问题是,我很想让用户也斜着走。喜欢同时向上和向右。我试图寻找一些解决办法,但不幸的是没有任何运气。 我将尝试修改它,使左/右键转动/旋转,因此向上键的意思是“向前”,而不是“向上”。但首先,我需要一次制作两把钥匙

所以问题是,我怎样才能做到,一次使用两个键,对角移动


另外,Atm,我正在图片盒上移动一个椭圆,改变
点statek=新点(250470)跳线,所以每次定时器滴答作响时,它都会检查X或Y是否发生了变化,并将其绘制到新的位置。经常滴答作响——这就是我现在试图实现实时运动的方式。这不会是任何复杂的应用程序。

您需要保留一些类型的列表,其中列出了当前处于按键关闭状态的所有按键

这允许您跟踪按下的键,并确定哪些组合是有效的


每个事件在每个按键向下/向上事件中触发一次。因此,在一个事件中检测两个关键点是不可能的,但您可以在事件之外的集合范围内跟踪此信息

您需要保留当前处于按键关闭状态的所有按键的某种类型的列表

这允许您跟踪按下的键,并确定哪些组合是有效的


每个事件在每个按键向下/向上事件中触发一次。因此,在一个事件中检测两个关键点是不可能的,但您可以在事件之外的集合范围内跟踪此信息

首先创建位枚举以保存箭头键状态:

[Flags]
enum ArrowsPressed
{
    None = 0x00,
    Left = 0x01,
    Right = 0x02,
    Up = 0x04,
    Down = 0x08,
    All = 0x0F
}
然后是一个成员来跟踪状态和一个函数来更改状态

ArrowsPressed arrowsPressed;

void ChangeArrowsState(ArrowsPressed changed, bool isPressed)
{
    if (isPressed)
    {
        arrowsPressed |= changed;
    }
    else
    {
        arrowsPressed &= ArrowsPressed.All ^ changed;
    }
}
重写KeyDown和KeyUp(不要忘记将窗体的KeyPreview属性设置为true,以便在子控件想要窃取密钥时让窗体接收密钥

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    switch (e.KeyCode)
    {
        case Keys.Down:
            ChangeArrowsState(ArrowsPressed.Down, true);
            break;
        case Keys.Up:
            ChangeArrowsState(ArrowsPressed.Up, true);
            break;
        case Keys.Left:
            ChangeArrowsState(ArrowsPressed.Left, true);
            break;
        case Keys.Right:
            ChangeArrowsState(ArrowsPressed.Right, true);
            break;
        default:
            return;
    }
    HandleArrows();
    e.Handled = true;
}
protected override void OnKeyUp(KeyEventArgs e)
{
    base.OnKeyUp(e);
    switch (e.KeyCode)
    {
        case Keys.Down:
            ChangeArrowsState(ArrowsPressed.Down, false);
            break;
        case Keys.Up:
            ChangeArrowsState(ArrowsPressed.Up, false);
            break;
        case Keys.Left:
            ChangeArrowsState(ArrowsPressed.Left, false);
            break;
        case Keys.Right:
            ChangeArrowsState(ArrowsPressed.Right, false);
            break;
        default:
            return;
    }
    e.Handled = true;
}
最后,使用点结构保持您的位置,测试所有跟踪的关键点,并按它们指示的方向移动点

Point position;
private void HandleArrows()
{
    if ((arrowsPressed & ArrowsPressed.Down) != ArrowsPressed.None)
    {
        position.Y++;
    }
    if ((arrowsPressed & ArrowsPressed.Up) != ArrowsPressed.None)
    {
        position.Y--;
    }
    if ((arrowsPressed & ArrowsPressed.Left) != ArrowsPressed.None)
    {
        position.X--;
    }
    if ((arrowsPressed & ArrowsPressed.Right) != ArrowsPressed.None)
    {
        position.X++;
    }
    //  Do whatever is needed using position
}

首先创建位枚举以保存箭头键状态:

[Flags]
enum ArrowsPressed
{
    None = 0x00,
    Left = 0x01,
    Right = 0x02,
    Up = 0x04,
    Down = 0x08,
    All = 0x0F
}
然后是一个成员来跟踪状态和一个函数来更改状态

ArrowsPressed arrowsPressed;

void ChangeArrowsState(ArrowsPressed changed, bool isPressed)
{
    if (isPressed)
    {
        arrowsPressed |= changed;
    }
    else
    {
        arrowsPressed &= ArrowsPressed.All ^ changed;
    }
}
重写KeyDown和KeyUp(不要忘记将窗体的KeyPreview属性设置为true,以便在子控件想要窃取密钥时让窗体接收密钥

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    switch (e.KeyCode)
    {
        case Keys.Down:
            ChangeArrowsState(ArrowsPressed.Down, true);
            break;
        case Keys.Up:
            ChangeArrowsState(ArrowsPressed.Up, true);
            break;
        case Keys.Left:
            ChangeArrowsState(ArrowsPressed.Left, true);
            break;
        case Keys.Right:
            ChangeArrowsState(ArrowsPressed.Right, true);
            break;
        default:
            return;
    }
    HandleArrows();
    e.Handled = true;
}
protected override void OnKeyUp(KeyEventArgs e)
{
    base.OnKeyUp(e);
    switch (e.KeyCode)
    {
        case Keys.Down:
            ChangeArrowsState(ArrowsPressed.Down, false);
            break;
        case Keys.Up:
            ChangeArrowsState(ArrowsPressed.Up, false);
            break;
        case Keys.Left:
            ChangeArrowsState(ArrowsPressed.Left, false);
            break;
        case Keys.Right:
            ChangeArrowsState(ArrowsPressed.Right, false);
            break;
        default:
            return;
    }
    e.Handled = true;
}
最后,使用点结构保持您的位置,测试所有跟踪的关键点,并按它们指示的方向移动点

Point position;
private void HandleArrows()
{
    if ((arrowsPressed & ArrowsPressed.Down) != ArrowsPressed.None)
    {
        position.Y++;
    }
    if ((arrowsPressed & ArrowsPressed.Up) != ArrowsPressed.None)
    {
        position.Y--;
    }
    if ((arrowsPressed & ArrowsPressed.Left) != ArrowsPressed.None)
    {
        position.X--;
    }
    if ((arrowsPressed & ArrowsPressed.Right) != ArrowsPressed.None)
    {
        position.X++;
    }
    //  Do whatever is needed using position
}

使用GetKeyboardState改进了版本。这一次,计时器将调用一个函数,该函数将检查是否按下了键,构造ArrowsPressed枚举并调用一个函数 执行移动。如果要使用其他键,请将其放入virtualKeyToArrowsPressed字典中

const int VK_LEFT = 0x25;
const int VK_UP = 0x26;
const int VK_RIGHT = 0x27;
const int VK_DOWN = 0x28;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte[] lpKeyState);

byte[] keys = new byte[256];

[Flags]
enum ArrowsPressed
{
    None = 0x00,
    Left = 0x01,
    Right = 0x02,
    Up = 0x04,
    Down = 0x08,
    All = 0x0F
}
Dictionary<int, ArrowsPressed> virtualKeyToArrowsPressed = new Dictionary<int, ArrowsPressed>
{
    { VK_LEFT, ArrowsPressed.Left },
    { VK_RIGHT, ArrowsPressed.Right },
    { VK_UP, ArrowsPressed.Up },
    { VK_DOWN, ArrowsPressed.Down },
};

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    timer1.Tick += timer1_Tick;
    timer1.Interval = 100;
    timer1.Start();
}

void timer1_Tick(object sender, EventArgs e)
{
    if (GetKeyboardState(keys))
    {
        ArrowsPressed arrowsPressed = ArrowsPressed.None;
        foreach (KeyValuePair<int, ArrowsPressed> kvp in virtualKeyToArrowsPressed)
        {
            if ((keys[kvp.Key] & 0x80) != 0)
            {
                arrowsPressed |= kvp.Value;
            }
        }
        if (arrowsPressed != ArrowsPressed.None)
        {
            HandleArrows(arrowsPressed);
        }
    }
}

Point position;
private void HandleArrows(ArrowsPressed arrowsPressed)
{
    if ((arrowsPressed & ArrowsPressed.Down) != ArrowsPressed.None)
    {
        position.Y++;
    }
    if ((arrowsPressed & ArrowsPressed.Up) != ArrowsPressed.None)
    {
        position.Y--;
    }
    if ((arrowsPressed & ArrowsPressed.Left) != ArrowsPressed.None)
    {
        position.X--;
    }
    if ((arrowsPressed & ArrowsPressed.Right) != ArrowsPressed.None)
    {
        position.X++;
    }
    //  Do whatever is needed using position
}
const int VK_LEFT=0x25;
常数int VK_UP=0x26;
常数int VK_RIGHT=0x27;
常数int VK_DOWN=0x28;
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部布尔GetKeyboardState(字节[]lpKeyState);
字节[]键=新字节[256];
[旗帜]
枚举箭头
{
无=0x00,
左=0x01,
右=0x02,
Up=0x04,
向下=0x08,
全部=0x0F
}
Dictionary virtualKeyToArrowsPressed=新建字典
{
{VK_左,箭头按下。左},
{VK_RIGHT,ArrowsPressed.RIGHT},
{VK_UP,ArrowsPressed.UP},
{VK_向下,箭头按下。向下},
};
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
timer1.Tick+=timer1\u Tick;
计时器1。间隔=100;
timer1.Start();
}
无效计时器1_刻度(对象发送方,事件参数e)
{
如果(获取键盘状态(键))
{
ArrowsPressed ArrowsPressed=ArrowsPressed.None;
foreach(按下virtualKeyToArrowsPressed中的键值对kvp)
{
if((键[kvp.Key]&0x80)!=0)
{
箭头压力|=kvp.值;
}
}
如果(箭头压力!=箭头压力。无)
{
手把手箭头(按箭头);
}
}
}
点位;
专用空心把手行(箭头压缩箭头压缩)
{
如果((箭头加压&箭头加压。向下)!=箭头加压。无)
{
position.Y++;
}
如果((箭头加压&箭头加压。向上)!=箭头加压。无)
{
位置Y--;
}
如果((箭头压缩&箭头压缩。左)!=箭头压缩。无)
{
位置X--;
}
如果((箭头压力和箭头压力。右侧)!=箭头压力。无)
{
position.X++;
}
//利用位置做任何需要的事情
}

使用GetKeyboardState的改进版本。这一次,计时器将调用一个函数,该函数将检查按键、构造箭头压缩枚举并调用函数 执行移动。如果要使用其他键,请将其放入virtualKeyToArrowsPressed字典中

const int VK_LEFT = 0x25;
const int VK_UP = 0x26;
const int VK_RIGHT = 0x27;
const int VK_DOWN = 0x28;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte[] lpKeyState);

byte[] keys = new byte[256];

[Flags]
enum ArrowsPressed
{
    None = 0x00,
    Left = 0x01,
    Right = 0x02,
    Up = 0x04,
    Down = 0x08,
    All = 0x0F
}
Dictionary<int, ArrowsPressed> virtualKeyToArrowsPressed = new Dictionary<int, ArrowsPressed>
{
    { VK_LEFT, ArrowsPressed.Left },
    { VK_RIGHT, ArrowsPressed.Right },
    { VK_UP, ArrowsPressed.Up },
    { VK_DOWN, ArrowsPressed.Down },
};

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    timer1.Tick += timer1_Tick;
    timer1.Interval = 100;
    timer1.Start();
}

void timer1_Tick(object sender, EventArgs e)
{
    if (GetKeyboardState(keys))
    {
        ArrowsPressed arrowsPressed = ArrowsPressed.None;
        foreach (KeyValuePair<int, ArrowsPressed> kvp in virtualKeyToArrowsPressed)
        {
            if ((keys[kvp.Key] & 0x80) != 0)
            {
                arrowsPressed |= kvp.Value;
            }
        }
        if (arrowsPressed != ArrowsPressed.None)
        {
            HandleArrows(arrowsPressed);
        }
    }
}

Point position;
private void HandleArrows(ArrowsPressed arrowsPressed)
{
    if ((arrowsPressed & ArrowsPressed.Down) != ArrowsPressed.None)
    {
        position.Y++;
    }
    if ((arrowsPressed & ArrowsPressed.Up) != ArrowsPressed.None)
    {
        position.Y--;
    }
    if ((arrowsPressed & ArrowsPressed.Left) != ArrowsPressed.None)
    {
        position.X--;
    }
    if ((arrowsPressed & ArrowsPressed.Right) != ArrowsPressed.None)
    {
        position.X++;
    }
    //  Do whatever is needed using position
}
const int VK_LEFT=0x25;
常数int VK_UP=0x26;
常数int VK_RIGHT=0x27;
常数int VK_DOWN=0x28;
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部布尔GetKeyboardState(字节[]lpKeyState);
字节[]键=新字节[256];
[旗帜]
枚举箭头
{
无=0x00,
左=0x01,
右=0x02,
Up=0x04,
向下=0x08,
全部=0x0F
}
Dictionary virtualKeyToArrowsPressed=新建字典
{
{VK_左,箭头按下。左},
{VK_RIGHT,ArrowsPressed.RIGHT},
{VK_UP,ArrowsPressed.UP},
{VK_向下,箭头按下。向下},
};
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
timer1.Tick+=timer1\u Tick;
计时器1。间隔=100;
timer1.Start();
}
无效计时器1_刻度(对象发送方,事件参数e)
{
如果(获取键盘状态(键))
{
ArrowsPressed ArrowsPressed=ArrowsPressed.None;
foreach(按下virtualKeyToArrowsPressed中的键值对kvp)
{
if((键[kvp.Key]&0x80)!=0)
{
箭头