winforms 处理所有windows窗体应用程序中的快捷键,但不处理其他进程中的快捷键

eit6fx6z  于 2023-02-16  发布在  Windows
关注(0)|答案(1)|浏览(130)

如果用户按Control + F,我需要从应用程序的所有打开窗口启动一个新的搜索表单。
目前我正在使用windows user32.dll方法注册一个热键,我想在我的应用程序中显示如下:

// Registers a hot key with Windows.
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
// Unregisters the hot key with Windows.
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

这种方法的问题是,即使选择了不同的应用程序(如Web浏览器),也会启动快捷方式。
我试过将KeyPreview设置为true来使用MainForm_KeyDown,但它只适用于主窗体。我也试过重写ProcessCmdKey,但同样,它只适用于主窗体。
我在想,也许UI自动化库提供了监视输入的支持。否则,是否有可能在Windows热键注册中添加一个过滤器,使其只对我的应用程序的进程ID有效?

xkftehaa

xkftehaa1#

据我所知,你有这些要求:

  • Control-F组合键创建新窗体
  • 无论当前哪个窗体(或控件)具有焦点,热键都应该仍然有效。
  • 热键是应用程序本地的。

实现IMessageFilter应该能够有效地实现以下目标:

public partial class MainForm : Form, IMessageFilter
{
    public MainForm()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
        Disposed += (sender, e) =>Application.RemoveMessageFilter(this);
    }
    const int WM_KEYDOWN = 0x0100;
    public bool PreFilterMessage(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_KEYDOWN:
                switch((Keys)m.WParam | ModifierKeys)
                {
                    case Keys.Control | Keys.F:
                        onNewForm();
                        break;
                }
                break;
        }
        return false;
    }

    int _count = 0;
    private void onNewForm()
    {
        char c = (char)(_count + 'A');
        int dim = ++_count * SystemInformation.CaptionHeight;
        new TextBoxForm
        {
            Name = $"textBoxForm{c}",
            Text = $"TextBoxForm {c}",
            Size = this.Size,
            StartPosition= FormStartPosition.Manual,
            Location = new Point(Left + dim, Top + dim),
        }.Show(this);
    }
}

相关问题