C# Winforms:Winforms应用程序在其面板中承载其他应用程序的键盘快捷键

C# Winforms:Winforms应用程序在其面板中承载其他应用程序的键盘快捷键,c#,winforms,C#,Winforms,我有一个Winforms应用程序,它的面板中有两个PDF查看器(非托管C++) 我希望有用于项目处理的应用程序范围的热键(打开、保存、关闭等),即使用户关注的是托管的PDF查看器,这些热键也能工作 我设法通过Winapi和RegisterHotKey实现了这一点,但客户端不喜欢系统范围内的这些(例如,它们禁用相同的MS Word热键) 我曾尝试在表单的激活/停用事件上禁用和启用全局热键,但即使我没有离开自己的应用程序,这些事件也会出现,例如在顶部菜单项或对话框上 是否有其他针对应用程序范围热键的

我有一个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继承它们


在注册/注销全局热键时,我尝试并行注册时遇到了一个问题-全局热键被绑定到一个线程。

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

如果应用程序不在活动窗口中,您不能检查活动的应用程序并且不处理按键吗?或者使用一些计时器轮询来检查活动窗口,如果您的应用程序不是活动窗口,则禁用键盘快捷键。第一个将保持其他应用程序热键禁用…谢谢,这在某些情况下有效。但有时我需要多次重新打开另一个应用程序(例如记事本)以使其热键可用。现在我明白了原因:我有一个浮动对话框(它是我主窗体上的一个窗体添加了这个.AddOwnedForm(..),当我将我的应用程序输入该对话框时,它不会启用热键。当我从该对话框离开应用程序时,它也不会禁用热键。我也可以检查这个小对话框的激活/停用,并操作其中的热键,但如果我有更多这样的对话框,它对我来说似乎并不干燥。