日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

在WPF中實(shí)現(xiàn)全局快捷鍵功能_C#教程

作者:天方 ? 更新時(shí)間: 2022-08-21 編程語言

今天寫一個(gè)小程序中使用到了全局快捷鍵,找到了我之前寫的文章在c#中使用全局快捷鍵翻了一下,發(fā)現(xiàn)它是WinForm版本的,而我現(xiàn)在大部分寫WPF程序了,便將其翻譯了為WPF版本的了。

    static class Hotkey
    {
        #region 系統(tǒng)api
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk);

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

        /// <summary>
        /// 注冊(cè)快捷鍵
        /// </summary>
        /// <param name="window">持有快捷鍵窗口</param>
        /// <param name="fsModifiers">組合鍵</param>
        /// <param name="key">快捷鍵</param>
        /// <param name="callBack">回調(diào)函數(shù)</param>
        public static void Regist(Window window, HotkeyModifiers fsModifiers, Key key, HotKeyCallBackHanlder callBack)
        {
            var hwnd = new WindowInteropHelper(window).Handle;
            var _hwndSource = HwndSource.FromHwnd(hwnd);
            _hwndSource.AddHook(WndProc);

            int id = keyid++;

            var vk = KeyInterop.VirtualKeyFromKey(key);
            if (!RegisterHotKey(hwnd, id, fsModifiers, (uint)vk))
                throw new Exception("regist hotkey fail.");
            keymap[id] = callBack;
        }

        /// <summary>
        /// 快捷鍵消息處理
        /// </summary>
        static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_HOTKEY)
            {
                int id = wParam.ToInt32();
                if (keymap.TryGetValue(id, out var callback))
                {
                    callback();
                }
            }
            return IntPtr.Zero;
        }

        /// <summary>
        /// 注銷快捷鍵
        /// </summary>
        /// <param name="hWnd">持有快捷鍵窗口的句柄</param>
        /// <param name="callBack">回調(diào)函數(shù)</param>
        public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack)
        {
            foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keymap)
            {
                if (var.Value == callBack)
                    UnregisterHotKey(hWnd, var.Key);
            }
        }


        const int WM_HOTKEY = 0x312;
        static int keyid = 10;
        static Dictionary<int, HotKeyCallBackHanlder> keymap = new Dictionary<int, HotKeyCallBackHanlder>();

        public delegate void HotKeyCallBackHanlder();
    }

    enum HotkeyModifiers
    {
        MOD_ALT = 0x1,
        MOD_CONTROL = 0x2,
        MOD_SHIFT = 0x4,
        MOD_WIN = 0x8
    }

代碼仍然差不多,使用的方式更加簡(jiǎn)單一點(diǎn):

protected override void OnSourceInitialized(EventArgs e)
{
    Hotkey.Regist(this, HotkeyModifiers.MOD_ALT, Key.T, () =>
    {
        MessageBox.Show("hello");
    });

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

需要注意的是,調(diào)用Hotkey.Regist函數(shù)時(shí),需要窗口是分配了句柄的,因此建議在OnLoad事件或OnSourceInitialized函數(shù)中進(jìn)行。

原文鏈接:https://www.cnblogs.com/TianFang/p/7668753.html

欄目分類
最近更新