在WPF全局热键从每一个窗口的工作 [英] Global hotkeys in WPF working from every window

查看:148
本文介绍了在WPF全局热键从每一个窗口的工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用这将从每一个窗口和讲坛合作热键。在的WinForms我用:

I have to use hotkeys which will be working from every window and pulpit. In winforms I used:

RegisterHotKey(this.Handle, 9000, 0x0002, (int)Keys.F10);

UnregisterHotKey(this.Handle, 9000);

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg)
    {
        case 0x312:
        switch (m.WParam.ToInt32())
        {
            case 9000:
            //function to do
            break;
        }
        break;
    }
}

在我的WPF aplication我试图做的:

In my WPF aplication I tried do:

AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)HandleKeyDownEvent);

private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
    if (e.Key == Key.F11 && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
    {
        //function to do
    }
}    

但它只能时我的应用程序是活动的并在上面,但是当应用程序被最小化(例如)它不工作。任何方法来做到这一点?

But it works only when my application is active and on the top, but it doesn't work when the application is minimized (for example). Is any method to do it?

推荐答案

您可以使用同样的方法在一些适应的WinForms:

You can use the same approach as in WinForms with some adaptation:


  • 使用 WindowInteropHelper 获得 HWND (而不是处理窗体的属性)

  • 使用 HwndSource 来处理窗口消息(而不是覆盖的WndProc 的一种形式)

  • 请不要使用枚举从 WPF - 它的价值观是不是你想要的

  • use WindowInteropHelper to get HWND (instead of Handle property of a form)
  • use HwndSource to handle window messages (instead of overriding WndProc of a form)
  • don't use Key enumeration from WPF - it's values are not the ones you want

完成code:

[DllImport("User32.dll")]
private static extern bool RegisterHotKey(
    [In] IntPtr hWnd,
    [In] int id,
    [In] uint fsModifiers,
    [In] uint vk);

[DllImport("User32.dll")]
private static extern bool UnregisterHotKey(
    [In] IntPtr hWnd,
    [In] int id);

private HwndSource _source;
private const int HOTKEY_ID = 9000;

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    var helper = new WindowInteropHelper(this);
    _source = HwndSource.FromHwnd(helper.Handle);
    _source.AddHook(HwndHook);
    RegisterHotKey();
}

protected override void OnClosed(EventArgs e)
{
    _source.RemoveHook(HwndHook);
    _source = null;
    UnregisterHotKey();
    base.OnClosed(e);
}

private void RegisterHotKey()
{
    var helper = new WindowInteropHelper(this);
    const uint VK_F10 = 0x79;
    const uint MOD_CTRL = 0x0002;
    if(!RegisterHotKey(helper.Handle, HOTKEY_ID, MOD_CTRL, VK_F10))
    {
        // handle error
    }
}

private void UnregisterHotKey()
{
    var helper = new WindowInteropHelper(this);
    UnregisterHotKey(helper.Handle, HOTKEY_ID);
}

private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    const int WM_HOTKEY = 0x0312;
    switch(msg)
    {
        case WM_HOTKEY:
            switch(wParam.ToInt32())
            {
                case HOTKEY_ID:
                    OnHotKeyPressed();
                    handled = true;
                    break;
            }
            break;
    }
    return IntPtr.Zero;
}

private void OnHotKeyPressed()
{
    // do stuff
}

这篇关于在WPF全局热键从每一个窗口的工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆