简体   繁体   English

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

[英]What is the best way to trap key press combinations in owner form?

I have a global parent form with multiple child forms and would like to have a shortcut key combination for the user to cycle between them. 我有一个具有多个子窗体的全局父窗体,并且希望有一个快捷键组合供用户在它们之间循环。 I would like this logic to be handled by the parent form so that the child forms are kept independent of this. 我希望这种逻辑由父表单处理,以便子表单保持与此无关。

This apparently common scenario (eg switching active documents in Visual Studio, active tabs in browsers, etc) has proven surprisingly hard to implement. 事实证明,这种显然常见的场景(例如,在Visual Studio中切换活动文档,在浏览器中切换活动标签等)很难实现。 The only way I found of doing it so far is to use a global hook or a hotkey. 到目前为止,我发现这样做的唯一方法是使用全局挂钩或热键。 The problem with this approach is that they stop other applications from using the same hotkey, as the setting is applied system-wide. 这种方法的问题在于,由于该设置在系统范围内应用,因此它们会阻止其他应用程序使用相同的热键。

What is the best way for an owner form to listen for particular key presses even when the child forms are in focus? 对于所有者表单,即使子表单处于焦点状态,最好的方法是收听特定的按键吗?

Ok, I found an easy way to do it using message filters. 好的,我找到了一种使用消息过滤器的简单方法。 It turns out you can register global message filters with an Application using the IMessageFilter interface. 事实证明,您可以使用IMessageFilter接口向Application注册全局消息过滤器。 For example: 例如:

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;
    }
}

This message filter will listen for a particular key combination and then call some static or class method in order to jump between all open windows. 该消息过滤器将侦听特定的组合键,然后调用一些静态或类方法以在所有打开的窗口之间跳转。 You can pass specific window handles that you want to cycle between as arguments to the message filter, as it is just a normal class. 您可以将要在其间循环的特定窗口句柄作为参数传递给消息过滤器,因为它只是普通的类。

You can register filters with the application at any moment with the following: 您可以随时使用以下内容在应用程序中注册过滤器:

Application.AddMessageFilter(filter);

and remove it with the following: 并使用以下命令将其删除:

Application.RemoveMessageFilter(filter);

If using an MDI form in winforms, the Ctrl + Tab shortcut will automatically be registered for changing windows. 如果在Winforms中使用MDI表单,则Ctrl + Tab快捷键将自动注册以更改窗口。 If you're trying to trap for other key combinations, set KeyPreview to true on your MDI form and handle the key presses there.. 如果您尝试捕获其他按键组合,请在MDI表单上将KeyPreview设置为true并在那里处理按键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM