• 在WPF中使用全局快捷键


    今天写一个小程序中使用到了全局快捷键,找到了我之前写的文章在c#中使用全局快捷键翻了一下,发现它是WinForm版本的,而我现在大部分写WPF程序了,便将其翻译了为WPF版本的了。 

     1     static class Hotkey
     2     {
     3         #region 系统api
     4         [DllImport("user32.dll")]
     5         [return: MarshalAs(UnmanagedType.Bool)]
     6         static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk);
     7 
     8         [DllImport("user32.dll")]
     9         static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    10         #endregion
    11 
    12         /// <summary>
    13         /// 注册快捷键
    14         /// </summary>
    15         /// <param name="window">持有快捷键窗口</param>
    16         /// <param name="fsModifiers">组合键</param>
    17         /// <param name="key">快捷键</param>
    18         /// <param name="callBack">回调函数</param>
    19         public static void Regist(Window window, HotkeyModifiers fsModifiers, Key key, HotKeyCallBackHanlder callBack)
    20         {
    21             var hwnd = new WindowInteropHelper(window).Handle;
    22             var _hwndSource = HwndSource.FromHwnd(hwnd);
    23             _hwndSource.AddHook(WndProc);
    24 
    25             int id = keyid++;
    26 
    27             var vk = KeyInterop.VirtualKeyFromKey(key);
    28             if (!RegisterHotKey(hwnd, id, fsModifiers, (uint)vk))
    29                 throw new Exception("regist hotkey fail.");
    30             keymap[id] = callBack;
    31         }
    32 
    33         /// <summary> 
    34         /// 快捷键消息处理 
    35         /// </summary> 
    36         static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    37         {
    38             if (msg == WM_HOTKEY)
    39             {
    40                 int id = wParam.ToInt32();
    41                 if (keymap.TryGetValue(id, out var callback))
    42                 {
    43                     callback();
    44                 }
    45             }
    46             return IntPtr.Zero;
    47         }
    48 
    49         /// <summary> 
    50         /// 注销快捷键 
    51         /// </summary> 
    52         /// <param name="hWnd">持有快捷键窗口的句柄</param> 
    53         /// <param name="callBack">回调函数</param> 
    54         public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack)
    55         {
    56             foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keymap)
    57             {
    58                 if (var.Value == callBack)
    59                     UnregisterHotKey(hWnd, var.Key);
    60             }
    61         }
    62 
    63 
    64         const int WM_HOTKEY = 0x312;
    65         static int keyid = 10;
    66         static Dictionary<int, HotKeyCallBackHanlder> keymap = new Dictionary<int, HotKeyCallBackHanlder>();
    67 
    68         public delegate void HotKeyCallBackHanlder();
    69     }
    70 
    71     enum HotkeyModifiers
    72     {
    73         MOD_ALT = 0x1,
    74         MOD_CONTROL = 0x2,
    75         MOD_SHIFT = 0x4,
    76         MOD_WIN = 0x8
    77     }
    View Code

    代码仍然差不多,使用的方式更加简单一点:

    protected override void OnSourceInitialized(EventArgs e)
    {
        Hotkey.Regist(thisHotkeyModifiers.MOD_ALTKey.T, () =>
        {
            MessageBox.Show("hello");
        });

        _context = new MainContext();
        this.DataContext = _context;
        _context.Process();
    }

    需要注意的是,调用Hotkey.Regist函数时,需要窗口是分配了句柄的,因此建议在OnLoad事件或OnSourceInitialized函数中进行。

  • 相关阅读:
    Raid卡在Write back 与Write through 时的性能差异
    mysql 的outfile以及infile 语法简单备份恢复表
    @SneakyThrows
    java中的mmap实现--转
    以ATT&CK为例构建网络安全知识图
    横向移动攻击点与识别
    Tomcat开启JMX监控
    mysql serverTimezone
    自增还是UUID?数据库主键的类型选择,为啥不能用uuid做MySQL的主键?
    数据库:查询结果中增加数据库不存在的字段的方法
  • 原文地址:https://www.cnblogs.com/TianFang/p/7668753.html
Copyright © 2020-2023  润新知