箭头键事件未到 [英] Arrow key events not arriving

查看:103
本文介绍了箭头键事件未到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我有一个带有自定义控件的表单(仅此而已)。自定义控件完全为空,并且窗体的KeyPreview设置为true。



使用此设置,我没有收到任何箭头键或Tab的KeyDown事件。我在键盘上拥有的所有其他键均有效。我已经将KeyDown事件处理程序与具有此类事件的所有事物连接在一起,因此我确定我不会丢失任何东西。



还要注意的是,如果我删除了(完全为空)自定义控件,我确实得到了箭头键事件。



这到底是怎么回事?



编辑:



我将此添加到了表单和控件中,但是我仍然没有得到箭头键:

 受保护的覆盖无效WndProc(ref Message m){
switch(m.Msg){
case 0x100:// WM_KEYDOWN
//这是控件的版本。在表单中是this.Text
ParentForm.Text =((Keys)m.WParam).ToString();
休息时间;
}
base.WndProc(ref m);
}

我也检查了Spy ++,并确定表单本身未获取任何内容WM_KEYDOWN消息,它们都将进入控件。但是,也就是说,控件正在获取箭头键WM_KEYDOWN消息。



编辑2:我还用此版本更新了ZIP文件。请看一下,如果您想提供帮助...



编辑3:



我认为这样的,有点。表单正在吃着箭头键,可能是为了保持孩子的注意力。这可以通过以下事实证明:如果表单为空,我确实会获得事件。



无论如何,如果我将此代码添加到表单中,我将再次开始获取事件:

 公共重写bool PreProcessMessage(ref Message msg){
switch(msg.Msg){
情况0x100:// WM_KEYDOWN
返回false;
}
返回base.PreProcessMessage(ref msg);
}

当我覆盖此内容时,表单没有机会执行肮脏的工作,所以我得到了我期望的KeyDown事件。我认为这样做的副作用是我不能再使用键盘来导航表单(在这种情况下,这不是什么大问题,因为它是游戏,并且本练习的全部目的是实现键盘导航!) / p>

如果有办法,问题仍然在于如何禁用此适当 ...

解决方案

我已经做了一些广泛的测试,并且我已经弄清楚了所有事情。 我写了一篇博客文章,详细介绍了该解决方案。



简而言之,您想以以下形式覆盖ProcessDialogKey方法:

 受保护的覆盖布尔ProcessDialogKey(Keys keyData){
return false;
}

这将导致箭头键(和制表符)作为正常的KeyDown传递事件。然而!这也会导致正常的对话键功能(使用Tab键导航控件等)失败。如果您想保留该值,但仍然得到KeyDown事件,请改用此方法:

 受保护的重写bool ProcessDialogKey(Keys keyData) {
OnKeyDown(new KeyEventArgs(keyData));
返回base.ProcessDialogKey(keyData);
}

这将传递KeyDown消息,同时仍在进行正常的对话导航。


Basically, I have a form with a custom control on it (and nothing else). The custom control is completely empty, and the form has KeyPreview set to true.

With this setup, I am not receiving any KeyDown events for any arrow keys or Tab. Every other key that I have on my keyboard works. I have KeyDown event handlers hooked up to everything that has such events, so I'm sure I'm not missing anything.

Also of note is that if I remove the (completely empty) custom control, I DO get the arrow key events.

What on earth is going on here?

EDIT:

I added this to both the form and the control, but I'm STILL not getting arrow keys:

protected override void WndProc(ref Message m) {
    switch (m.Msg) {
        case 0x100: //WM_KEYDOWN
            //this is the control's version. In the form, it's this.Text
            ParentForm.Text = ((Keys)m.WParam).ToString();
            break;
    }
    base.WndProc(ref m);
}

I also checked with Spy++, and determined that the form itself is not getting any WM_KEYDOWN messages, they're all going to the control. However, that said, the control IS getting the arrow key WM_KEYDOWN messages. Sigh.

Edit 2: I've also updated the ZIP file with this version. Please look at it, if you want to help...

Edit 3:

I've figured this out, sort of. The form is eating the arrow keys, probably in an attempt to maintain focus amongst its children. This is proven by the fact that I DO get the events if the form is empty.

Anyway, if I add this code to the form, I start getting the events again:

public override bool PreProcessMessage(ref Message msg) {
    switch (msg.Msg) {
        case 0x100: //WM_KEYDOWN
            return false;
    }
    return base.PreProcessMessage(ref msg);
}

When I override this, the form doesn't get a chance to do its dirty work, and so I get my KeyDown events as I expect. I assume that a side effect of this is that I can no longer use my keyboard to navigate the form (not a big deal in this case, as it's a game, and the entire purpose of this exercise is to implement keyboard navigation!)

The question still remains about how to disable this "properly", if there is a way...

解决方案

I've done some extensive testing, and I've figured everything out. I wrote a blog post detailing the solution.

In short, you want to override the ProcessDialogKey method in the form:

protected override bool ProcessDialogKey(Keys keyData) {
    return false;
}

This will cause the arrow keys (and tab) to be delivered as normal KeyDown events. HOWEVER! This will also cause the normal dialogue key functionality (using Tab to navigate controls, etc) to fail. If you want to retain that, but still get the KeyDown event, use this instead:

protected override bool ProcessDialogKey(Keys keyData) {
    OnKeyDown(new KeyEventArgs(keyData));
    return base.ProcessDialogKey(keyData);
}

This will deliver a KeyDown message, while still doing normal dialogue navigation.

这篇关于箭头键事件未到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆