WPF实现监听快捷键的方式分享

 

1.调用Win32 API

优先级最高,全局监听, 支持最小化失焦等情况

那么,假如我要在一个WPF程序监听CTRL+5按键,首先在主窗口程序添加以下代码:

      /// <summary>
      /// CTRL+5事件Id
      /// </summary>
      private const int Ctrl5KeyEventId = 9000;


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

      [DllImport("user32.dll")]
      public static extern bool UnregisterHotKey(IntPtr hWnd, int id);


      protected override void OnSourceInitialized(EventArgs e)
      {
          base.OnSourceInitialized(e);

          var handle = new WindowInteropHelper(this).Handle;
          var source = HwndSource.FromHwnd(handle);
          source?.AddHook(HwndHook);
          //真正注册快捷键监听处理: 同时注册数字键和小键盘的CTRL+5
          RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.D5));
          RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.NumPad5));
      }


      private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
      {
          const int wmHotkey = 0x0312;

          switch (msg)
          {
              case wmHotkey:
                  switch (wParam.ToInt32())
                  {
                      case Ctrl5KeyEventId:
                          Debug.WriteLine("Win32监听CTRL+5成功");
                          break;
                  }
                  break;
          }

          return IntPtr.Zero;
      }


      protected override void OnClosing(CancelEventArgs e)
      {
          base.OnClosing(e);

          var handle = new WindowInteropHelper(this).Handle;
          //关闭窗口后取消注册
          UnregisterHotKey(handle, Ctrl5KeyEventId);
      }

 

2.监听WPF的KeyDown事件

不够清真,可选择,最小化失焦等情况监听失效

      public MainWindow()
      {
          InitializeComponent();
          KeyDown += MainWindow_KeyDown;
      }


      private void MainWindow_KeyDown(object sender, KeyEventArgs e)
      {
          if (Keyboard.Modifiers == ModifierKeys.Control && (e.Key == Key.D5 || e.Key == Key.NumPad5))
          {
              Debug.WriteLine("WPF的KeyDown事件监听CTRL+5成功"); ;
              e.Handled = true;
          }
      }

 

3.XAML绑定命令方式

WPF当然优先选中命令绑定啦,清真,最小化失焦等情况监听失效

以下为Window主窗体的XAML代码

    <Window.CommandBindings>
      <CommandBinding Command="{x:Static local:Commands.Ctrl5Command}" Executed="Ctrl5Command_OnExecuted"/>
  </Window.CommandBindings>
  <Window.InputBindings>
      <KeyBinding Modifiers="Control" Key="D5"  Command="{x:Static  local:Commands.Ctrl5Command}" />
      <KeyBinding Modifiers="Control" Key="NumPad5"  Command="{x:Static  local:Commands.Ctrl5Command}" />
  </Window.InputBindings>

在Window主窗体后台代码创建命令对应的Executed方法

        private void Ctrl5Command_OnExecuted(object sender, ExecutedRoutedEventArgs e)
      {
          Debug.WriteLine("WPF的XAML绑定命令监听CTRL+5成功");
      }

新增命令相关的静态类:

    public static class Commands
  {
      public static ICommand Ctrl5Command { get; } = new RoutedCommand();
  }

 

4.细节

三个监听方案的优先级

其中Win32 > XAML绑定命令 = KeyDown事件,假如同时监听的话,其中会只处理高优先级的,以上面的例子,假如

我同时监听三个,只会处理win32的

Win32监听CTRL+5成功

全局监听问题

其中win32支持全局监听键盘,也就是窗口在失焦情况下,例如最小化,也能监听得到,其中XAML绑定命令和KeyDown事件不支持失焦情况,最小化等情况也就监听不到了,因此,要按业务选择方案

 

5.DEMO

DEMO链接

以上就是WPF实现监听快捷键的方式分享的详细内容,更多关于WPF监听快捷键的资料请关注编程宝库其它相关文章!

DateTime被放在System命名空间下,在顶级语句中不必using可直接使。 单个字母格式化DateTime最常用的属性是Now,表示当前的时刻,其数据类型也是DateTime。但一般 ...