WPF 從鍵盤事件 KeyEventArgs 裏獲取 Scan Code 的方法

本文將告訴大家如何在 WPF 裏面,從鍵盤事件 KeyEventArgs 參數裏獲取到 Scan Code 鍵盤按鍵的設備獨立標識符的方法

概念:

以下來自 bing 的答案

鍵盤的 Scan Code 是按鍵的設備獨立標識符,對應於按鍵在硬件上的實際標識。每個按鍵都有一個唯一的掃描碼,用於表示該按鍵。當用戶按下一個鍵時,鍵盤會生成兩個掃描碼:通碼(Make Code)斷碼(Break Code)。通碼錶示按鍵被按下,而斷碼錶示按鍵被釋放。這些掃描碼由鍵盤設備驅動解釋並映射爲虛擬鍵碼(Virtual Key Code),這是系統定義的設備獨立值,用於標識鍵盤的按鍵²³.

虛擬鍵碼與掃描碼之間的區別在於,虛擬鍵碼是系統定義的值,而掃描碼是硬件上的實際標識符。虛擬鍵碼通常用於處理鍵盤輸入的應用程序,而掃描碼更接近鍵盤的底層硬件表示。 。

總結一下:

  • Scan Code:鍵盤按鍵的設備獨立標識符,由硬件生成。
  • Virtual Key Code:系統定義的設備獨立值,用於標識鍵盤的按鍵,由鍵盤設備驅動解釋掃描碼並映射而來。

方法1: 推薦的方法,通過 Win32 函數獲取,代碼實現如下

          KeyDown += MainWindow_KeyDown;

    private void MainWindow_KeyDown(object sender, KeyEventArgs e)
    {
        var key = e.Key;
        var virtualKey = KeyInterop.VirtualKeyFromKey(key);

        // MAPVK_VK_TO_VSC 0
        var scanCode = MapVirtualKeyW((uint) virtualKey, 0 /*MAPVK_VK_TO_VSC*/);
    }

    [DllImport("User32.dll")]
    private static extern uint MapVirtualKeyW(uint code, uint mapType);

方法2: 通過反射方式獲取,不推薦,且 API 可能被變更

    private void MainWindow_KeyDown(object sender, KeyEventArgs e)
    {
        var scanCodeFromWpf = typeof(KeyEventArgs).GetProperty("ScanCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(e);
    }

這兩個方法獲取到的值是相同的,如使用下面代碼,判斷相等成立

        Debug.Assert(scanCode == (int) scanCodeFromWpf!);

但如 MapVirtualKeyW 函數所述,確實存在一些情況下,獲取不到相同的結果

本文代碼放在 githubgitee 上,可以使用如下命令行拉取代碼

先創建一個空文件夾,接着使用命令行 cd 命令進入此空文件夾,在命令行裏面輸入以下代碼,即可獲取到本文的代碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 1806c3b45f5f10242da97a2fc1e3fa433fca783d

以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換爲 github 的源。請在命令行繼續輸入以下代碼,將 gitee 源換成 github 源進行拉取代碼

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 1806c3b45f5f10242da97a2fc1e3fa433fca783d

獲取代碼之後,進入 LaykechererolelQemyukilee 文件夾,即可獲取到源代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章