以所有者形式捕获按键组合的最佳方法是什么?
What is the best way to trap key press combinations in owner form?
我有一个包含多个子窗体的全局父窗体,并希望有一个快捷键组合供用户在它们之间循环。我希望这个逻辑由父表单处理,以便子表单独立于此。
这种看似常见的场景(例如,在 Visual Studio 中切换活动文档、浏览器中的活动选项卡等)已被证明难以实现。到目前为止,我发现这样做的唯一方法是使用全局挂钩或热键。这种方法的问题是它们会阻止其他应用程序使用相同的热键,因为该设置是在系统范围内应用的。
所有者窗体监听特定按键的最佳方式是什么,即使在子窗体处于焦点时也是如此?
如果在 winforms 中使用 MDI 窗体,Ctrl+Tab 快捷方式将自动注册以更改 windows。如果您尝试捕获其他组合键,请在您的 MDI 窗体上将 KeyPreview 设置为 true 并在那里处理按键操作..
好的,我找到了一种使用邮件过滤器来完成此操作的简单方法。事实证明,您可以使用 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;
}
}
此消息过滤器将侦听特定的组合键,然后调用一些静态或 class 方法以便在所有打开的 windows 之间跳转。您可以将要循环的特定 window 句柄作为参数传递给消息过滤器,因为它只是一个普通的 class.
您可以随时通过以下方式向应用程序注册过滤器:
Application.AddMessageFilter(filter);
并使用以下内容删除它:
Application.RemoveMessageFilter(filter);
我有一个包含多个子窗体的全局父窗体,并希望有一个快捷键组合供用户在它们之间循环。我希望这个逻辑由父表单处理,以便子表单独立于此。
这种看似常见的场景(例如,在 Visual Studio 中切换活动文档、浏览器中的活动选项卡等)已被证明难以实现。到目前为止,我发现这样做的唯一方法是使用全局挂钩或热键。这种方法的问题是它们会阻止其他应用程序使用相同的热键,因为该设置是在系统范围内应用的。
所有者窗体监听特定按键的最佳方式是什么,即使在子窗体处于焦点时也是如此?
如果在 winforms 中使用 MDI 窗体,Ctrl+Tab 快捷方式将自动注册以更改 windows。如果您尝试捕获其他组合键,请在您的 MDI 窗体上将 KeyPreview 设置为 true 并在那里处理按键操作..
好的,我找到了一种使用邮件过滤器来完成此操作的简单方法。事实证明,您可以使用 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;
}
}
此消息过滤器将侦听特定的组合键,然后调用一些静态或 class 方法以便在所有打开的 windows 之间跳转。您可以将要循环的特定 window 句柄作为参数传递给消息过滤器,因为它只是一个普通的 class.
您可以随时通过以下方式向应用程序注册过滤器:
Application.AddMessageFilter(filter);
并使用以下内容删除它:
Application.RemoveMessageFilter(filter);