Tasti di scelta rapida globali in WPF che funzionano da ogni finestra

Devo usare i tasti di scelta rapida che funzioneranno da ogni finestra e pulpito. In winforms ho usato:

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

e

 UnregisterHotKey(this.Handle, 9000); 

e

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

Nella mia aplicazione WPF ho provato a fare:

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

e

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

Funziona solo quando la mia applicazione è triggers e in alto, ma non funziona quando l’applicazione è ridotta a icona (ad esempio). C’è qualche metodo per farlo?

È ansible utilizzare lo stesso approccio di WinForms con alcuni adattamenti:

  • usa WindowInteropHelper per ottenere HWND (invece di Handle proprietà di un modulo)
  • utilizzare HwndSource per gestire i messaggi della finestra (anziché eseguire l’override di WndProc di un modulo)
  • non utilizzare l’enumerazione della Key da WPF – i suoi valori non sono quelli che vuoi

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