按Alt键时,如何防止控制框获得焦点?

时间:2013-08-14 15:23:13

标签: c# winforms

在我的应用程序中,我希望用户能够按住 Alt 对鼠标操作应用某些修改。与使用鼠标滚轮时垂直滚动不同,视图将水平滚动(当 Alt 被保持时)。

这很好用,但在释放 Alt 后,我的控件不再具有焦点。当我按 Space 时,我明白为什么。窗口菜单得到了关注,因为我按了 Alt

enter image description here

如何防止这种情况发生?

3 个答案:

答案 0 :(得分:4)

修复此问题并非易事,您需要阻止WM_SYSKEYDOWN消息到达默认窗口过程。只有在通过焦点到达控件之前对其进行过滤才能实现。这可以通过让表单实现IMessageFilter接口来实现。像这样:

public partial class Form1 : Form, IMessageFilter {
    public Form1() {
        InitializeComponent();
        Application.AddMessageFilter(this);
    }
    protected override void OnFormClosed(FormClosedEventArgs e) {
        Application.RemoveMessageFilter(this);
        base.OnFormClosed(e);
    }
    public bool PreFilterMessage(ref Message m) {
        // Trap WM_SYSKEYUPDOWN message for the ALT key
        if ((Keys)m.WParam.ToInt32() == Keys.Menu) {
            if (m.Msg == 0x104) { AltKeyPressed = true; return true; }
            if (m.Msg == 0x105) { AltKeyPressed = false; return true; }
        }
        return false;
    }
    private bool AltKeyPressed;
}

注意许多副作用,它会停止菜单正常运行,使用Alt的快捷键击不再起作用。请考虑使用Ctrl或Shift。

答案 1 :(得分:0)

释放Alt手势后,通过调用Control.Focus()以编程方式强制您的控件获得焦点。

为什么这个黑客可以接受?因为此行为仅限于控件具有焦点并且手势成功处理的实例。

答案 2 :(得分:0)

我认为您需要在键盘事件上注册并将事件标记为已处理,
我不是指KeyPressed甚至是KeyDown ...... 我的意思是OnPreviewKeyDown(不要记住确切的名字,但谷歌搜索会这样做)