Teclas rápidas globales en WPF que funcionan desde todas las ventanas

Tengo que usar teclas rápidas que funcionarán desde todas las ventanas y el púlpito. En winforms utilicé:

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

y

 UnregisterHotKey(this.Handle, 9000); 

y

 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; } } 

En mi aplicación WPF lo intenté:

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

y

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

Pero solo funciona cuando mi aplicación está activa y en la parte superior, pero no funciona cuando la aplicación está minimizada (por ejemplo). ¿Hay algún método para hacerlo?

Puede usar el mismo enfoque que en WinForms con alguna adaptación:

  • use WindowInteropHelper para obtener HWND (en lugar de la propiedad Handle de un formulario)
  • utilice HwndSource para manejar mensajes de ventana (en lugar de anular WndProc de un formulario)
  • no use la enumeración Key de WPF ; sus valores no son los que usted quiere

Código completo:

 [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 }