【问题标题】:Winforms: Keyboard shortcuts for Winforms app hosting other applications in its panelsWinforms:Winforms 应用程序在其面板中托管其他应用程序的键盘快捷键
【发布时间】:2012-03-13 14:56:08
【问题描述】:

我有一个 Winforms 应用程序,它的面板中有两个 PDF 查看器(非托管 C++)。

我希望为项目处理提供应用程序范围的热键(打开、保存、关闭、...),即使用户关注托管的 PDF 查看器也可以使用。

我设法通过 Winapi 和 RegisterHotKey 实现了这一点,但客户不喜欢那些是系统范围的(例如,它们禁用了相同的 MS Word 热键)

我确实尝试在表单的激活/停用事件上禁用和启用全局热键,但是即使我不离开自己的应用程序也会出现这些事件,例如在顶部菜单条目或对话框上。

对于应用程序范围的热键是否有其他解决方案,即使焦点在托管应用程序上也可以工作?

解决方案:

在主窗体中,我处理这样的激活和停用事件:

public void PDFPicker_Activated(object sender, EventArgs e)
    {
        var foregroundHwnd = GUI.winapiwrap.GetForegroundWindow();
        if (foregroundHwnd==this.Handle ||   this.OwnedForms.Any(form => form.Handle==foregroundHwnd))
        {
            if (!this.hotkeys.Any())
            {
                registerHotkeys();
                this.Text = "Hotkeys just registered";
            }                
        }
    }
    public void PDFPicker_Deactivate(object sender, EventArgs e)
    {
        var foregroundHwnd = GUI.winapiwrap.GetForegroundWindow();
        if (foregroundHwnd == this.Handle || this.OwnedForms.Any(form => form.Handle == foregroundHwnd))
        {

        }
        else
        {
          unregisterHotkeys();
          this.Text = "Hotkeys off";
        }
    }

然后在对话框中,它位于 OwnedForms 数组中,我只调用这个:

private void QuestionPostingPanel_Activated(object sender, EventArgs e)
    {
        parent.PDFPicker_Activated(sender, e);            
    }

    private void QuestionPostingPanel_Deactivate(object sender, EventArgs e)
    {
        parent.PDFPicker_Deactivate(sender, e);
    }

如果有更多这样的对话框,我会继承 AbstractDialog : Form,添加这两个事件函数和对父级的引用,然后从这个 AbstractDialog 继承所有这些。

在注册/注销 GlobalHotkeys 时,当我尝试并行执行此操作时,这对我来说是个问题 - 全局热键绑定到一个线程。

【问题讨论】:

  • 如果您的应用程序不是活动窗口,您不能检查活动应用程序并且不处理按键吗?或者使用一些计时器轮询来检查活动窗口,如果您的应用程序不是活动窗口,则禁用键盘快捷键。
  • 第一个会禁用其他应用程序的热键...

标签: c# winforms


【解决方案1】:

然后检查表单激活/停用事件是否表单是前台窗口 (::GetForegroundWindow()),然后适当地禁用/启用热键。

【讨论】:

  • 谢谢,这在某些情况下有效。但有时我需要多次重新打开其他应用程序(例如记事本)以使其热键可用。
  • 现在我知道了原因:我有一个浮动对话框(它是在我的主窗体上添加了 this.AddOwnedForm(..) 的一个窗体),当我将我的应用程序输入此对话框时,它没有启用热键。
  • 当我从此对话框离开应用程序时,它也不会禁用热键。我也可以检查这个小对话框的激活/停用并操作其中的热键,但如果我有更多这样的对话框,它对我来说似乎并不干燥。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 2015-07-20
相关资源
最近更新 更多