1. 程式人生 > 其它 >WindowsAPI-C#版_原始裝置輸入常用API

WindowsAPI-C#版_原始裝置輸入常用API

WindowsAPI-C#版_原始裝置輸入常用API:

/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:WindowsAPI_鍵鼠、遊戲杆、觸控式螢幕和麥克風等輸入裝置                                     
*│ 作    者:執筆小白                                              
*│ 版    本:1.0                                       
*│ 建立時間:2022-11-13 15:40:56                            
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 名稱空間: WindowAPIHelper.API                     
*│ 類    名:WindowsAPI_KeyboardAndMouseInput                                     
*└──────────────────────────────────────────────────────────────┘
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace WindowAPIHelper.API
{
    /// <summary>
    /// WindowsAPI_鍵鼠、遊戲杆、觸控式螢幕和麥克風等輸入裝置
    /// </summary>
    public class WindowsAPI_KeyboardAndMouseInput
    {
        #region 常用
        /// <summary>
        /// 註冊提供原始輸入資料的裝置
        /// 若要接收 WM_INPUT 訊息,應用程式必須先使用 RegisterRawInputDevices 註冊原始輸入裝置。 預設情況下,應用程式不會接收原始輸入。
        /// </summary>
        /// <param name="pRawInputDevice">表示提供原始輸入的裝置,RAWINPUTDEVICE[]陣列</param>
        /// <param name="uiNumDevices">pRawInputDevices 指向的 RAWINPUTDEVICE 結構數。</param>
        /// <param name="cbSize">RAWINPUTDEVICE 結構的大小(以位元組為單位)</param>
        /// <returns>如果函式成功,則為 TRUE;否則為 FALSE。 如果函式失敗,請呼叫 GetLastError 以獲取詳細資訊。</returns>
        [DllImport("User32.dll")]
        public extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);

        /// <summary>
        /// 檢索有關原始輸入裝置的資訊
        /// </summary>
        /// <param name="hDevice">原始輸入裝置的控制代碼</param>
        /// <param name="uiCommand">指定將在 pData 中返回哪些資料 (uint)</param>
        /// <param name="pData">指向包含 uiCommand 指定的資訊的緩衝區的指標(如果 uiCommandRIDI_DEVICEINFO,請將RID_DEVICE_INFO的cbSize 成員設定為sizeof(RID_DEVICE_INFO)呼叫 GetRawInputDeviceInfo 之前。)</param>
        /// <param name="pcbSize">如果成功,此函式將返回一個非負數,指示覆制到 pData 的位元組數。如果 pData 不足以容納資料,則函式返回 -1。 如果 pData 為 NULL,則函式返回值為零。</param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public extern static uint GetRawInputDeviceInfo(IntPtr hDevice, UiCommand uiCommand, IntPtr pData, ref uint pcbSize);

        /// <summary>
        /// 從指定裝置檢索原始輸入
        /// </summary>
        /// <param name="hRawInput">控制代碼</param>
        /// <param name="uiCommand">指定將在 pData 中返回哪些資料 (uint)</param>
        /// <param name="pData">指向 來自 RAWINPUT 結構的資料的指標。 這取決於 uiCommand 的值。 如果 pData 為 NULL,則緩衝區的所需大小在 *mbSize 中返回。</param>
        /// <param name="pcbSize">pData 中資料的大小(以位元組為單位)。</param>
        /// <param name="cbSizeHeader">RAWINPUTHEADER 結構的大小(以位元組為單位)。</param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public extern static uint GetRawInputData(IntPtr hRawInput, UiCommand uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);

        /// <summary>
        /// 從指定裝置檢索原始輸入資料組
        /// </summary>
        /// <param name="pData">指向 來自 RAWINPUT 結構的資料的指標。 這取決於 uiCommand 的值。 如果 pData 為 NULL,則緩衝區的所需大小在 *mbSize 中返回。</param>
        /// <param name="pcbSize">pData 中資料的大小(以位元組為單位)。</param>
        /// <param name="cbSizeHeader">RAWINPUTHEADER 結構的大小(以位元組為單位)。</param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public extern static uint GetRawInputBuffer(IntPtr pData, ref uint pcbSize, uint cbSizeHeader);

        // tagRAWINPUTHEADER(包含原始輸入資料的一部分的標頭資訊) 略:可以使用GetRawInputData
        // RAWINPUT函式(原始輸入) 略:可以使用GetRawInputData
        #endregion 常用

        #region 列舉、結構等資料型別
        /// <summary>
        /// 指定將在 pData 中返回哪些資料 (uint)
        /// </summary>
        public enum UiCommand
        {
            #region getRawInputData 函式(從指定裝置檢索原始輸入)
            RID_INPUT = 0x10000003,   // 從 RAWINPUT 結構獲取標頭資訊。
            RID_HEADER = 0x10000005,  // 從 RAWINPUT 結構獲取原始資料。
            #endregion getRawInputData 函式

            #region GetRawInputDeviceInfo 函式(檢索有關原始輸入裝置的資訊)
            RIDI_PREPARSEDDATA = 0x20000005,  // pData 指向 頂級集合預分析資料的緩衝區的PHIDP_PREPARSED_DATA指標。
            RIDI_DEVICENAME = 0x20000007,     // pData 指向包含 裝置介面名稱的字串。
            RIDI_DEVICEINFO = 0x2000000b,     // pData 指向 RID_DEVICE_INFO結構。
            #endregion GetRawInputDeviceInfo 函式
        }

        /// <summary>
        /// RAWINPUTDEVICE(原始輸入裝置的資訊_與儲存裝置資訊有關聯的資訊)
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RAWINPUTDEVICE
        {
            /// <summary>
            /// 原始輸入裝置的頂級集合使用情況頁。
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsagePage;
            /// <summary>
            /// 原始輸入裝置的頂級集合使用情況 ID
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsage;
            /// <summary>
            /// 指定如何解釋 usUsagePage 和 usUsage 提供的資訊的模式標誌。 
            /// 預設情況下,只要具有視窗焦點,作業系統就會從具有指定 頂級集合 的裝置傳送原始輸入, (TLC) 到已註冊的應用程式。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public DwFlags dwFlags;
            /// <summary>
            /// 目標視窗的控制代碼。 如果 為 NULL ,則它遵循鍵盤焦點。
            /// </summary>
            public IntPtr hwndTarget;
        }
        
        /// <summary>
        /// 原始輸入裝置的資訊_裝置有關的資訊
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RAWINPUTHEADER
        {
            /// <summary>
            /// 輸入裝置的型別(滑鼠、鍵盤、不是鍵盤或滑鼠的某些裝置)
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public DwType dwType;   // 輸入裝置的型別(滑鼠、鍵盤、不是鍵盤或滑鼠的某些裝置)
            /// <summary>
            /// 整個輸入資料包的大小(以位元組為單位)。 這包括 RAWINPUT 加上 RAWHID 可變長度陣列中可能的額外輸入報告。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwSize;      // 整個輸入資料包的大小(以位元組為單位)。 這包括 RAWINPUT 加上 RAWHID 可變長度陣列中可能的額外輸入報告。
            /// <summary>
            /// 生成原始輸入資料的裝置的控制代碼。
            /// </summary>
            public IntPtr hDevice;  // 生成原始輸入資料的裝置的控制代碼。
            /// <summary>
            /// 在WM_INPUT訊息的 wParam 引數中傳遞的值。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int wParam;      // 在WM_INPUT訊息的 wParam 引數中傳遞的值。
        }

        /// <summary>
        /// 原始輸入資訊的結構
        /// </summary>
        [StructLayout(LayoutKind.Explicit)]
        public struct RAWINPUT
        {
            /// <summary>
            /// 標頭資訊
            /// </summary>
            [FieldOffset(0)]
            public RAWINPUTHEADER header;

            /// <summary>
            /// 滑鼠資訊
            /// </summary>
            [FieldOffset(16)]
            public RAWMOUSE mouse;

            /// <summary>
            /// 鍵盤資訊
            /// </summary>
            [FieldOffset(16)]
            public RAWKEYBOARD keyboard;

            /// <summary>
            /// 不是鍵盤或滑鼠的某些裝置
            /// </summary>
            [FieldOffset(16)]
            public RAWHID hid;
        }

        #region 定義來自任何裝置的原始輸入資料
        /// <summary>
        /// 定義來自任何裝置的原始輸入資料
        /// </summary>
        [StructLayout(LayoutKind.Explicit)]
        public struct RID_DEVICE_INFO
        {
            /// <summary>
            /// RID_DEVICE_INFO結構的大小(以位元組為單位)
            /// </summary>
            [FieldOffset(0)]
            public int cbSize;

            /// <summary>
            /// 原始輸入資料的型別
            /// </summary>
            [FieldOffset(4)]
            public DwType dwType;

            /// <summary>
            /// 定義滑鼠 的RID_DEVICE_INFO_MOUSE 結構;dwType=RIM_TYPEMOUSE時有值
            /// </summary>
            [FieldOffset(8)]
            public RID_DEVICE_INFO_MOUSE mouse;

            /// <summary>
            /// 定義鍵盤 的RID_DEVICE_INFO_KEYBOARD 結構;dwType=RIM_TYPEKEYBOARD時有值
            /// </summary>
            [FieldOffset(8)]
            public RID_DEVICE_INFO_KEYBOARD keyboard;

            /// <summary>
            /// 定義 HID 裝置的 RID_DEVICE_INFO_HID 結構;dwType=RIM_TYPEHID時有值
            /// </summary>
            [FieldOffset(8)]
            public RID_DEVICE_INFO_HID hid;
        }

        /// <summary>
        /// 定義來自指定滑鼠的原始輸入資料(備註,對於滑鼠,“使用情況”頁為 1,使用情況為 2)
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RID_DEVICE_INFO_MOUSE
        {
            /// <summary>
            /// 滑鼠裝置標識屬性的位欄位
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public DwId dwId;

            /// <summary>
            /// 滑鼠的按鈕數
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfButtons;

            /// <summary>
            /// 每秒資料點數。 此資訊可能不適用於每個滑鼠裝置。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwSampleRate;

            /// <summary>
            /// 如果滑鼠具有用於水平滾動的滾輪,則為 TRUE;否則為 FALSE。Windowsxp: 僅從 Windows Vista 開始支援此成員。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int fHasHorizontalWheel;  // true存為int,用bool可能有bug
        }

        /// <summary>
        /// 定義來自指定鍵盤的原始輸入資料
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RID_DEVICE_INFO_KEYBOARD
        {
            /// <summary>
            /// 鍵盤的型別
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public DwType dwType;
            /// <summary>
            /// 鍵盤的特定於供應商的子型別
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwSubType;
            /// <summary>
            /// 掃描程式碼模式。通常為1,這意味著使用“掃描程式碼集1”
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwKeyboardMode;
            /// <summary>
            /// 鍵盤上的函式鍵數
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfFunctionKeys;
            /// <summary>
            /// 鍵盤上的 LED 指示器數
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfIndicators;
            /// <summary>
            /// 鍵盤上的鍵總數
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfKeysTotal;
        }

        /// <summary>
        /// 定義來自指定人機介面裝置 (HID) 的原始輸入資料
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RID_DEVICE_INFO_HID
        {
            /// <summary>
            /// HID 的供應商識別符號
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwVendorId;
            /// <summary>
            /// HID 的產品識別符號
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwProductId;
            /// <summary>
            /// HID 的版本號
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwVersionNumber;
            /// <summary>
            /// 裝置的頂級集合使用情況頁
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsagePage;
            /// <summary>
            /// 裝置的頂級集合使用情況
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsage;
        }
        #endregion 定義來自任何裝置的原始輸入資料

        #region 原始輸入資訊的結構
        /// <summary>
        /// 原始輸入來自滑鼠資訊
        /// </summary>
        [StructLayout(LayoutKind.Explicit)]
        public struct RAWMOUSE
        {
            /// <summary>
            /// 設定獲取滑鼠的相對移動還是絕對移動
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            [FieldOffset(0)]
            public UsFlags usFlags;

            #region DUMMYUNIONNAME 結構
            /// <summary>
            /// 按鈕標識
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(4)]
            public ulong ulButtons;

            /// <summary>
            /// 按鈕資訊
            /// </summary>
            [FieldOffset(4)]
            public DUMMYSTRUCTNAME buttonsStr;
            #endregion DUMMYUNIONNAME 結構

            /// <summary>
            /// 滑鼠按鈕的原始狀態。Win32子系統不使用此成員。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(8)]
            public ulong ulRawButtons;

            /// <summary>
            /// X方向的運動。相對運動或絕對運動取決於usFlags的值。
            /// </summary>
            [FieldOffset(12)]
            public long lLastX;

            /// <summary>
            /// Y方向的運動。相對運動或絕對運動取決於usFlags的值。
            /// </summary>
            [FieldOffset(16)]
            public long lLastY;

            /// <summary>
            /// 事件裝置的特定附加資訊。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(20)]
            public ulong ulExtraInformation;
        }

        /// <summary>
        /// 原始輸入來自鍵盤資訊
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RAWKEYBOARD
        {
            /// <summary>
            /// 指定與按鍵關聯的掃描程式碼。見部落格補充-鍵值Key
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort MakeCode;

            /// <summary>
            /// 掃描程式碼資訊的標誌
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public RAWKEYBOARD_Flags Flags;

            /// <summary>
            /// 保留;必須為零
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort Reserved;

            /// <summary>
            /// 相應的 舊虛擬金鑰程式碼
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort VKey;

            /// <summary>
            /// 相應的 舊式鍵盤視窗訊息,例如 WM_KEYDOWN、 WM_SYSKEYDOWN等
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public uint Message;

            /// <summary>
            /// 事件特定於裝置的其他資訊
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public ulong ExtraInformation;
        }

        /// <summary>
        /// 原始輸入來自不是鍵盤或滑鼠的某些裝置
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RAWHID
        {
            /// <summary>
            /// bRawData中每個HID輸入的大小(以位元組為單位)。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwSizHid;

            /// <summary>
            /// bRawData中HID輸入的數量。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public int dwCount;

            /// <summary>
            /// 原始輸入資料,作為位元組陣列。
            /// </summary>
            [MarshalAs(UnmanagedType.U4)]
            public byte bRawData;
        }
        #endregion 原始輸入資訊的結構

        /// <summary>
        /// WM_INPUT:輸入裝置的型別(滑鼠、鍵盤、不是鍵盤或滑鼠的某些裝置)
        /// 輸入裝置的型別(再細分型別)
        /// </summary>
        public enum DwType
        {
            #region 原始輸入來自哪個裝置
            /// <summary>
            /// 原始輸入來自滑鼠
            /// </summary>
            RIM_TYPEMOUSE = 0,     // 原始輸入來自滑鼠
            /// <summary>
            /// 原始輸入來自鍵盤
            /// </summary>
            RIM_TYPEKEYBOARD = 1,  // 原始輸入來自鍵盤
            /// <summary>
            /// 原始輸入來自不是鍵盤或滑鼠的某些裝置
            /// </summary>
            RIM_TYPEHID = 2,       // 原始輸入來自不是鍵盤或滑鼠的某些裝置
            #endregion 原始輸入來自哪個裝置

            #region 鍵盤型別
            增強型101或102鍵鍵盤 = 0x4,
            日語鍵盤 = 0x7,
            朝鮮語鍵盤 = 0x8,
            未知型別或HID鍵盤= 0x51
            #endregion 鍵盤型別
        }

        /// <summary>
        /// 指定如何解釋 usUsagePage 和 usUsage 提供的資訊的模式標誌。 
        /// </summary>
        public enum DwFlags
        {
            Default = 0x00000000,             // 預設
            RIDEV_REMOVE = 0x00000001,        // 從包含列表中刪除頂級集合。 這會告知作業系統停止從與頂級集合匹配的裝置讀取。
            RIDEV_EXCLUDE = 0x00000010,       // 指定讀取完整使用情況頁時要排除的頂級集合。 此標誌僅影響已使用 RIDEV_PAGEONLY 指定的 TLC。
            RIDEV_PAGEONLY = 0x00000020,      // 指定其頂級集合來自指定 usUsagePage 的所有裝置。 請注意, usUsage 必須為零。 若要排除特定的頂級集合,請使用 RIDEV_EXCLUDE。
            RIDEV_NOLEGACY = 0x00000030,      // 阻止 usUsagePage 或 usUsage 指定的任何裝置生成 舊訊息。 這僅適用於滑鼠和鍵盤。
            RIDEV_INPUTSINK = 0x00000100,     // 如果已設定,則即使呼叫方不在前臺,呼叫方也能夠接收輸入。 請注意,必須指定 hwndTarget 。
            RIDEV_CAPTUREMOUSE = 0x00000200,  // 滑鼠按鈕單擊不會啟用另一個視窗。 僅當為滑鼠裝置指定了RIDEV_NOLEGACY時,才能指定RIDEV_CAPTUREMOUSE。
            RIDEV_NOHOTKEYS = 0x00000200,     // 不會處理應用程式定義的鍵盤裝置熱鍵。 但是,系統熱鍵;例如,仍處理 Alt+TAB 和 Ctrl+ALT+DEL。 預設情況下,將處理所有鍵盤熱鍵。 即使未指定RIDEV_NOLEGACY且 hwndTarget 為 NULL,也可以指定RIDEV_NOHOTKEYS。
            RIDEV_APPKEYS = 0x00000400,       // 處理應用程式命令金鑰。 僅當為鍵盤裝置指定了RIDEV_NOLEGACY時,才能指定RIDEV_APPKEYS。
            RIDEV_EXINPUTSINK = 0x00001000,   // 僅當前臺應用程式未處理它時,呼叫方才能在後臺接收輸入。 換句話說,如果未為原始輸入註冊前臺應用程式,則註冊的後臺應用程式將收到輸入。在 Windows Vista 之前不支援此標誌
            RIDEV_DEVNOTIFY = 0x00002000      // 允許呼叫方接收裝置到達和裝置刪除 WM_INPUT_DEVICE_CHANGE 通知。在 Windows Vista 之前不支援此標誌
        }

        #region 滑鼠原始輸入有關型別
        /// <summary>
        /// 設定獲取滑鼠的相對移動還是絕對移動
        /// </summary>
        public enum UsFlags
        {
            MOUSE_MOVE_RELATIVE = 0x00,       // 相對於最後一個滑鼠位置的滑鼠移動資料。
            MOUSE_MOVE_ABSOLUTE = 0x01,       // 基於絕對位置的滑鼠移動資料。
            MOUSE_VIRTUAL_DESKTOP = 0x02,     // 滑鼠座標對映到虛擬桌面(對於多監視器系統)。
            MOUSE_ATTRIBUTES_CHANGED = 0x04,  // 滑鼠屬性已更改;應用程式需要查詢滑鼠屬性。
            MOUSE_MOVE_NOCOALESCE = 0x08,     // 此滑鼠移動事件未合併。預設情況下,可以合併滑鼠移動事件。Windows XP/2000:不支援此值。
        }

        /// <summary>
        /// 標識按鈕觸發事件(標識了哪個鍵發生了什麼事件)
        /// </summary>
        public enum UsButtonFlags
        {
            RI_MOUSE_BUTTON_1_DOWN = 0x0001,  // RI_MOUSE_LEFT_BUTTON_DOWN
            RI_MOUSE_BUTTON_1_UP = 0x0002,    // RI_MOUSE_LEFT_BUTTON_UP
            RI_MOUSE_BUTTON_2_DOWN = 0x0004,  // RI_MOUSE_RIGHT_BUTTON_DOWN
            RI_MOUSE_BUTTON_2_UP = 0x0008,    // RI_MOUSE_RIGHT_BUTTON_UP
            RI_MOUSE_BUTTON_3_DOWN = 0x0010,  // RI_MOUSE_MIDDLE_BUTTON_DOWN
            RI_MOUSE_BUTTON_3_UP = 0x0020,    // RI_MOUSE_MIDDLE_BUTTON_UP
            RI_MOUSE_BUTTON_4_DOWN = 0x0040,  // X_BUTTON1 changed to down.
            RI_MOUSE_BUTTON_4_UP = 0x0080,    // X_BUTTON1 changed to up.
            RI_MOUSE_BUTTON_5_DOWN = 0x0100,  // X_BUTTON2 changed to down.
            RI_MOUSE_BUTTON_5_UP = 0x0200,    // X_BUTTON2 changed to up.
            RI_MOUSE_WHEEL = 0x0400,          // 滑鼠滾輪,值儲存在inusButtonData中;正值表示車輪向前滾動,遠離使用者;負值表示車輪向後滾動。
            RI_MOUSE_HWHEEL = 0x0800,         // 滑鼠水平滾輪,值儲存在inusButtonData中;正值表示車輪向右旋轉;負值表示車輪向左旋轉。
        }
        #endregion 滑鼠原始輸入有關型別

        #region 鍵盤原始輸入有關型別
        /// <summary>
        /// 按鍵掃描程式碼資訊的標誌
        /// </summary>
        public enum RAWKEYBOARD_Flags
        {
            RI_KEY_MAKE = 0,    // 金鑰關閉
            RI_KEY_BREAK = 1,  // 金鑰已啟動
            RI_KEY_E0 = 2,     // 掃描程式碼具有 E0 字首
            RI_KEY_E1 = 4,    // 掃描程式碼具有 E1 字首
        }
        #endregion 鍵盤原始輸入有關型別

        /// <summary>
        /// 按鈕資訊
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct DUMMYSTRUCTNAME
        {
            /// <summary>
            /// 標識按鈕觸發事件(標識了哪個鍵發生了什麼事件)
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public UsButtonFlags usButtonFlags;

            /// <summary>
            /// 按鈕事件資訊資料
            /// </summary>
            [MarshalAs(UnmanagedType.U2)]
            public ushort usButtonData;
        }

        /// <summary>
        /// 滑鼠裝置標識屬性的位欄位
        /// </summary>
        public enum DwId
        {
            MOUSE_HID_HARDWARE = 0x0080,        // HID 滑鼠
            WHEELMOUSE_HID_HARDWARE = 0x0100,   // HID 滾輪滑鼠
            HORIZONTAL_WHEEL_PRESENT = 0x8000,  // 帶有水平滾輪的滑鼠
        }
        #endregion 列舉、結構等資料型別
    }
}