以所有者形式捕获按键组合的最佳方法是什么?

本文关键字:组合 最佳 方法 是什么 所有者 | 更新日期: 2023-09-27 18:17:41

我有一个具有多个子窗体的全局父窗体,并希望有一个快捷键组合供用户在它们之间循环。我希望这个逻辑由父窗体处理,以便子窗体保持独立。

这个显然很常见的场景(例如在Visual Studio中切换活动文档,在浏览器中切换活动选项卡等)被证明是非常难以实现的。到目前为止,我发现的唯一方法是使用全局钩子或热键。这种方法的问题是,它们会阻止其他应用程序使用相同的热键,因为该设置是在系统范围内应用的。

当子窗体处于焦点中时,所有者窗体侦听特定按键的最佳方式是什么?

以所有者形式捕获按键组合的最佳方法是什么?

好的,我找到了一个使用消息过滤器的简单方法。事实证明,您可以使用IMessageFilter接口向Application注册全局消息过滤器。例如:

class HotKeyMessageFilter : IMessageFilter
{
    const int WM_KEYDOWN = 0x100;
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            var keyCode = (Keys)m.WParam;
            if (keyCode == Keys.Tab && Form.ModifierKeys.HasFlag(Keys.Control))
            {
                if (Form.ModifierKeys.HasFlag(Keys.Shift)) CycleActiveForm(-1);
                else CycleActiveForm(1);
            }
        }
        return false;
    }
}

这个消息过滤器将监听一个特定的键组合,然后调用一些静态或类方法,以便在所有打开的窗口之间跳转。您可以将想要在消息过滤器之间循环的特定窗口句柄作为参数传递给消息过滤器,因为它只是一个普通的类。

你可以随时用下面的命令向应用程序注册过滤器:

Application.AddMessageFilter(filter);

,然后用以下命令删除:

Application.RemoveMessageFilter(filter);

如果在winforms中使用MDI表单,Ctrl+Tab快捷键将自动注册为更改窗口。如果您试图捕获其他键组合,请在MDI表单上将KeyPreview设置为true,并在那里处理按键。