【问题标题】:How do I prevent the control box getting focus when I press Alt?当我按 Alt 时,如何防止控制框获得焦点?
【发布时间】:2013-08-15 00:50:33
【问题描述】:

在我的应用程序中,我希望用户能够按住 Alt 以将某些修改应用于鼠标操作。就像使用鼠标滚轮而不是垂直滚动一样,视图将水平滚动(同时 Alt 被按住)。

这很好用,但是在释放 Alt 之后,我的控件不再具有焦点。当我按 Space 时,我明白了原因。窗口菜单获得焦点是因为我按下了 Alt

如何防止这种情况发生?

【问题讨论】:

  • 我今天学习了kbd标签。
  • @rageit:在Super User 上很受欢迎;)

标签: c# winforms


【解决方案1】:

解决这个问题并不容易,您需要防止 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。

【讨论】:

  • 太棒了。这就像一个魅力。我什至可以直接在我想要这种行为的Control 中实现它。我试图在这段代码中模拟 Photoshop 的行为(Alt+Wheel 缩放画布),这就是我不使用 Ctrl 或 Shift 的原因。但是,这是一个需要此功能的Control,我担心由于可移植性而可能产生的副作用。我会看看我会如何处理它:)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    我认为您需要注册键盘事件并将该事件标记为已处理,
    我不是说 KeyPressed 甚至 KeyDown ...... 我的意思是 OnPreviewKeyDown (不记得确切的名称,但谷歌搜索会做)

    【讨论】:

    • 是的,我在构建网格控件时使用过一次...当您将事件标记为已处理时。
    • Hans 展示了一种更高级的方法,通过干预消息循环来忽略此 KeyDown 消息。
    • 考虑到“副作用”的数量(如前所述,“很多”),我会在称之为更高级之前暂停一下。
    猜你喜欢
    • 2013-11-26
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    相关资源
    最近更新 更多