WPF監聽快捷鍵的幾種方式

来源:https://www.cnblogs.com/ryzen/archive/2023/03/20/17235188.html
-Advertisement-
Play Games

調用Win32 API(優先順序最高,全局監聽, 支持最小化失焦等情況) 那麼,假如我要在一個WPF程式監聽CTRL+5按鍵,首先在主視窗程式添加以下代碼: /// <summary> /// CTRL+5事件Id /// </summary> private const int Ctrl5KeyEv ...


調用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);
        }

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


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

細節

三個監聽方案的優先順序

其中Win32 > XAML綁定命令 = KeyDown事件,假如同時監聽的話,其中會只處理高優先順序的,以上面的例子,假如
我同時監聽三個,只會處理win32的


Win32監聽CTRL+5成功

全局監聽問題

其中win32支持全局監聽鍵盤,也就是視窗在失焦情況下,例如最小化,也能監聽得到,其中XAML綁定命令KeyDown事件不支持失焦情況,最小化等情況也就監聽不到了,因此,要按業務選擇方案

DEMO

DEMO鏈接


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Redis是一款開源的高性能key-value資料庫,廣泛應用於各種場景。在Redis中,數據類型(type)和編碼(encoding)是非常重要的概念。本篇博客將詳細介紹Redis支持的數據類型以及相應的編碼方式和底層實現原理。 ...
  • 教程簡介 IT寶庫MS項目入門教程 - 從基本概念開始,簡單易學地學習MS項目,包括設置,簡介,入門,創建新計劃,設置資源,為任務分配資源,計劃持續時間成本和時間,跟蹤進度,高級計劃,項目狀態報告。 Microsoft Project 是一個國際上享有盛譽的通用的項目管理工具軟體,凝集了許多成熟的項 ...
  • 本文已收錄至Github,推薦閱讀 👉 Java隨想錄 微信公眾號:Java隨想錄 摘要 空指針異常(NullPointerException)可以說是Java程式員最容易遇到的問題了,影響說大不大,說小也不小。為瞭解決這個問題,Java 8 版本中推出了 Optional 類。Optional ...
  • _pycache__文件夾可以看作該文件夾下文件已被python接管或者說編譯過。 在第一次執行代碼的時候,Python解釋器已經把編譯的位元組碼放在__pycache__文件夾中,這樣以後再次運行的話,如果被調用的模塊未發生改變,那就直接跳過編譯這一步,直接去__pycache__文件夾中去運行相關 ...
  • 目前由於功能比較簡單,沒有進行前後端拆分,主要技術點:SpringBoot、WebSocket、webjars、Vue、Element-UI、axios、jszip,核心壓縮庫是 Thumbnailator 提供壓縮支持。源代碼已經在 碼雲 star 公開。歡迎各位大佬批評。 ...
  • 解讀 Servlet 源碼:GenericServlet,ServletConfig,ServletContext 每博一文案 人活著,就得隨時準備經受磨難。他已經看過一些書,知道不論是普通人還是了不起的人,都要在自己的一生中經歷許多磨難。磨難使人堅強。 人和社會、一切鬥爭的總結局也許都是中庸而已。 ...
  • 在剛接觸後臺線程的時候,覺得線程神秘且高深,並且時常有先輩們千叮萬囑:能不用的時候,儘量不要用,千萬不要濫用線程,否則會發生預料不到的結果。在接觸線程一段時間後,感覺線程也不過如此,輕而易舉的就可以創建,所以逐漸大膽起來,項目里隨處可見的都是Task,Thread,async,await等內容。在大... ...
  • 一周一周來算,註,如果本月1號是星期日,則這一月共有六周,即六行,所以乾脆每月都輸出6周就行了,然後再算第一周里的本月一號是周幾,第一周里本月又占了幾天。。。呃。。。反正很亂,想了一上午,現在寫出來了倒不知道如何解釋了。。算了。。直接上代碼。。 //日曆界面 public IActionResult ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...