【问题标题】:What is the best way to trap key press combinations in owner form?以所有者形式捕获按键组合的最佳方法是什么?
【发布时间】:2016-11-11 15:56:07
【问题描述】:

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

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

即使在子窗体处于焦点时,所有者窗体也能监听特定按键的最佳方式是什么?

【问题讨论】:

  • 您可以订阅您创建的每个子窗口的PreviewKeyDown 事件,或者将它们传送到处理它们的通用视图模型。
  • ctrl + tab 应该已经默认添加了。
  • @AbdulRehmanSayed 我没有使用 MDI 框架,只是具有共同所有者的子窗口。我宁愿避免使用 MDI,或者至少了解 MDI 是如何实现这一点的。

标签: c# winforms keyboard-shortcuts


【解决方案1】:

好的,我找到了一种使用消息过滤器的简单方法。事实证明,您可以使用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);

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我没有直接使用 MDI 框架。他们是如何实现这些快捷方式的?它真的只是 MDI 特定的东西吗?或者当您设置 MdiParent 时,它们是否连接到 KeyPreview?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多