Cast fix and moving Win32 stuff in a dedicated file.
authorsl
Fri, 07 Nov 2014 20:49:51 +0100
changeset 994850bfc12b5
parent 8 0d0c62b1df48
child 10 17f8421146ba
Cast fix and moving Win32 stuff in a dedicated file.
Form1.cs
RemoteControlDevice.cs
RemoteControlSample.csproj
Win32RawInput.cs
     1.1 --- a/Form1.cs	Thu Nov 06 21:57:53 2014 +0100
     1.2 +++ b/Form1.cs	Fri Nov 07 20:49:51 2014 +0100
     1.3 @@ -132,7 +132,7 @@
     1.4                  //Display MCE button name
     1.5                  label1.Text = e.MceButton.ToString();
     1.6                  //Check if this is an HP extension
     1.7 -                if (Enum.IsDefined(typeof(Hid.UsageTables.HpMceButton), (int)e.MceButton))
     1.8 +                if (Enum.IsDefined(typeof(Hid.UsageTables.HpMceButton), (ushort)e.MceButton))
     1.9                  {
    1.10                      //Also display HP button name
    1.11                      label1.Text += " / HP:" + ((Hid.UsageTables.HpMceButton)e.MceButton).ToString();
     2.1 --- a/RemoteControlDevice.cs	Thu Nov 06 21:57:53 2014 +0100
     2.2 +++ b/RemoteControlDevice.cs	Fri Nov 07 20:49:51 2014 +0100
     2.3 @@ -3,13 +3,11 @@
     2.4  using System.Runtime.InteropServices;
     2.5  using System.Diagnostics;
     2.6  using Hid.UsageTables;
     2.7 +using Win32;
     2.8  
     2.9  namespace Devices.RemoteControl
    2.10  {
    2.11  
    2.12 - 
    2.13 -
    2.14 -
    2.15  	public enum InputDevice
    2.16  	{
    2.17  		Key,
    2.18 @@ -127,159 +125,6 @@
    2.19  
    2.20  	public sealed class RemoteControlDevice
    2.21  	{
    2.22 -
    2.23 -        [StructLayout(LayoutKind.Sequential, Pack = 1)]
    2.24 -		internal struct RAWINPUTDEVICE
    2.25 -		{
    2.26 -			[MarshalAs(UnmanagedType.U2)]
    2.27 -			public ushort usUsagePage;
    2.28 -			[MarshalAs(UnmanagedType.U2)]
    2.29 -			public ushort usUsage;
    2.30 -			[MarshalAs(UnmanagedType.U4)]
    2.31 -			public int	 dwFlags;
    2.32 -			public IntPtr hwndTarget;
    2.33 -		}
    2.34 -
    2.35 -
    2.36 -        [StructLayout(LayoutKind.Sequential, Pack = 1)]
    2.37 -		internal struct RAWINPUTHEADER
    2.38 -		{
    2.39 -			[MarshalAs(UnmanagedType.U4)]
    2.40 -			public int dwType;
    2.41 -			[MarshalAs(UnmanagedType.U4)]
    2.42 -			public int dwSize;
    2.43 -            public IntPtr hDevice;
    2.44 -			[MarshalAs(UnmanagedType.U4)]
    2.45 -			public int wParam;
    2.46 -		}
    2.47 -
    2.48 -
    2.49 -        [StructLayout(LayoutKind.Sequential, Pack = 1)]
    2.50 -		internal struct RAWHID
    2.51 -		{
    2.52 -			[MarshalAs(UnmanagedType.U4)]
    2.53 -			public int dwSizeHid;
    2.54 -			[MarshalAs(UnmanagedType.U4)]
    2.55 -			public int dwCount;
    2.56 -            //
    2.57 -            //BYTE  bRawData[1];
    2.58 -		}
    2.59 -
    2.60 -
    2.61 -        [StructLayout(LayoutKind.Sequential, Pack = 1)]
    2.62 -		internal struct BUTTONSSTR
    2.63 -		{
    2.64 -			[MarshalAs(UnmanagedType.U2)]
    2.65 -			public ushort usButtonFlags;
    2.66 -			[MarshalAs(UnmanagedType.U2)]
    2.67 -			public ushort usButtonData;
    2.68 -		}
    2.69 -
    2.70 -
    2.71 -        [StructLayout(LayoutKind.Explicit, Pack = 1)]
    2.72 -		internal struct RAWMOUSE
    2.73 -		{
    2.74 -			[MarshalAs(UnmanagedType.U2)]
    2.75 -			[FieldOffset (0)] public ushort usFlags;
    2.76 -			[MarshalAs(UnmanagedType.U4)]
    2.77 -			[FieldOffset (4)] public uint ulButtons;
    2.78 -			[FieldOffset (4)] public BUTTONSSTR buttonsStr;
    2.79 -			[MarshalAs(UnmanagedType.U4)]
    2.80 -			[FieldOffset (8)] public uint ulRawButtons;
    2.81 -            [MarshalAs(UnmanagedType.U4)]
    2.82 -            [FieldOffset (12)] public int lLastX;
    2.83 -            [MarshalAs(UnmanagedType.U4)]
    2.84 -            [FieldOffset (16)] public int lLastY;
    2.85 -			[MarshalAs(UnmanagedType.U4)]
    2.86 -			[FieldOffset (20)] public uint ulExtraInformation;
    2.87 -		}
    2.88 -
    2.89 -        [StructLayout(LayoutKind.Sequential, Pack = 1)]
    2.90 -		internal struct RAWKEYBOARD
    2.91 -		{
    2.92 -			[MarshalAs(UnmanagedType.U2)]
    2.93 -			public ushort MakeCode;
    2.94 -			[MarshalAs(UnmanagedType.U2)]
    2.95 -			public ushort Flags;
    2.96 -			[MarshalAs(UnmanagedType.U2)]
    2.97 -			public ushort Reserved;
    2.98 -			[MarshalAs(UnmanagedType.U2)]
    2.99 -			public ushort VKey;
   2.100 -			[MarshalAs(UnmanagedType.U4)]
   2.101 -			public uint Message;
   2.102 -			[MarshalAs(UnmanagedType.U4)]
   2.103 -			public uint ExtraInformation;
   2.104 -		}
   2.105 -
   2.106 -
   2.107 -		[StructLayout(LayoutKind.Explicit, Pack=1)]
   2.108 -		internal struct RAWINPUT
   2.109 -		{
   2.110 -			[FieldOffset  (0)] public RAWINPUTHEADER header;
   2.111 -			[FieldOffset (16)] public RAWMOUSE mouse;
   2.112 -			[FieldOffset (16)] public RAWKEYBOARD keyboard;
   2.113 -			[FieldOffset (16)] public RAWHID hid;
   2.114 -		}
   2.115 -
   2.116 -
   2.117 -        [StructLayout(LayoutKind.Sequential, Pack=1)]
   2.118 -        internal struct RID_DEVICE_INFO_MOUSE
   2.119 -		{
   2.120 -            public uint dwId;
   2.121 -            public uint dwNumberOfButtons;
   2.122 -            public uint dwSampleRate;
   2.123 -            public bool fHasHorizontalWheel;
   2.124 -		}
   2.125 -
   2.126 -
   2.127 -        [StructLayout(LayoutKind.Sequential, Pack=1)]
   2.128 -        internal struct RID_DEVICE_INFO_KEYBOARD
   2.129 -		{
   2.130 -            public uint dwType;
   2.131 -            public uint dwSubType;
   2.132 -            public uint dwKeyboardMode;
   2.133 -            public uint dwNumberOfFunctionKeys;
   2.134 -            public uint dwNumberOfIndicators;
   2.135 -            public uint dwNumberOfKeysTotal;
   2.136 -        }
   2.137 -
   2.138 -        [StructLayout(LayoutKind.Sequential, Pack=1)]
   2.139 -        internal struct RID_DEVICE_INFO_HID
   2.140 -		{
   2.141 -            public uint dwVendorId;
   2.142 -            public uint dwProductId;
   2.143 -            public uint dwVersionNumber;
   2.144 -            public ushort usUsagePage;
   2.145 -            public ushort usUsage;
   2.146 -        }
   2.147 -
   2.148 -        [StructLayout(LayoutKind.Explicit, Pack=1)]
   2.149 -        internal struct RID_DEVICE_INFO
   2.150 -		{
   2.151 -            [FieldOffset(0)]
   2.152 -            public uint cbSize;
   2.153 -            [FieldOffset(4)]
   2.154 -            public uint dwType;
   2.155 -            [FieldOffset(8)]
   2.156 -            public RID_DEVICE_INFO_MOUSE mouse;
   2.157 -            [FieldOffset(8)]
   2.158 -            public RID_DEVICE_INFO_KEYBOARD keyboard;
   2.159 -            [FieldOffset(8)]
   2.160 -            public RID_DEVICE_INFO_HID hid;
   2.161 -		}
   2.162 -
   2.163 -
   2.164 -
   2.165 -		[DllImport("User32.dll")]
   2.166 -		extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
   2.167 -
   2.168 -		[DllImport("User32.dll")]
   2.169 -		extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
   2.170 -
   2.171 -   		[DllImport("User32.dll", SetLastError=true)]
   2.172 -		extern static int GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);
   2.173 -
   2.174 -
   2.175  		private const int WM_KEYDOWN	= 0x0100;
   2.176  		private const int WM_APPCOMMAND	= 0x0319;
   2.177  		private const int WM_INPUT		= 0x00FF;
   2.178 @@ -308,35 +153,6 @@
   2.179  		private const int FAPPCOMMAND_KEY				= 0;
   2.180  		private const int FAPPCOMMAND_OEM				= 0x1000;
   2.181  
   2.182 -        /// <summary>
   2.183 -        /// GetRawInputDeviceInfo pData points to a string that contains the device name.
   2.184 -        /// </summary>
   2.185 -        public const uint RIDI_DEVICENAME = 0x20000007;
   2.186 -        /// <summary>
   2.187 -        /// GetRawInputDeviceInfo For this uiCommand only, the value in pcbSize is the character count (not the byte count).
   2.188 -        /// </summary>
   2.189 -        public const uint RIDI_DEVICEINFO = 0x2000000b;
   2.190 -        /// <summary>
   2.191 -        /// GetRawInputDeviceInfo pData points to an RID_DEVICE_INFO structure.
   2.192 -        /// </summary>
   2.193 -        public const uint RIDI_PREPARSEDDATA = 0x20000005;
   2.194 -
   2.195 -
   2.196 -        /// <summary>
   2.197 -        /// Data comes from a mouse.
   2.198 -        /// </summary>
   2.199 -        public const uint RIM_TYPEMOUSE = 0;
   2.200 -        /// <summary>
   2.201 -        /// Data comes from a keyboard.
   2.202 -        /// </summary>
   2.203 -        public const uint RIM_TYPEKEYBOARD = 1;
   2.204 -        /// <summary>
   2.205 -        /// Data comes from an HID that is not a keyboard or a mouse.
   2.206 -        /// </summary>
   2.207 -        public const uint RIM_TYPEHID = 2;
   2.208 -
   2.209 -
   2.210 -
   2.211  
   2.212  
   2.213  		public delegate void RemoteControlDeviceEventHandler(object sender, RemoteControlEventArgs e);
   2.214 @@ -367,7 +183,7 @@
   2.215  			rid[2].usUsage = 0x80;
   2.216  			rid[2].dwFlags = 0;
   2.217  
   2.218 -			if (!RegisterRawInputDevices(rid,
   2.219 +			if (!Function.RegisterRawInputDevices(rid,
   2.220  				(uint) rid.Length,
   2.221  				(uint) Marshal.SizeOf(rid[0]))
   2.222  				)
   2.223 @@ -538,7 +354,7 @@
   2.224              uint sizeOfHeader=(uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
   2.225  
   2.226              //Get the size of our raw input data.
   2.227 -			GetRawInputData(message.LParam,	RID_INPUT, IntPtr.Zero,	ref dwSize,	sizeOfHeader);
   2.228 +			Win32.Function.GetRawInputData(message.LParam,	RID_INPUT, IntPtr.Zero,	ref dwSize,	sizeOfHeader);
   2.229  
   2.230              //Allocate a large enough buffer
   2.231  			IntPtr rawInputBuffer = Marshal.AllocHGlobal((int) dwSize);
   2.232 @@ -548,7 +364,7 @@
   2.233  					return;
   2.234  
   2.235                  //Now read our RAWINPUT data
   2.236 -				if (GetRawInputData(message.LParam,	RID_INPUT, rawInputBuffer, ref dwSize, (uint) Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
   2.237 +                if (Win32.Function.GetRawInputData(message.LParam, RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
   2.238  				{
   2.239  					return;
   2.240  				}
   2.241 @@ -560,7 +376,7 @@
   2.242                  uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
   2.243                  IntPtr deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
   2.244  
   2.245 -                int res = GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
   2.246 +                int res = Win32.Function.GetRawInputDeviceInfo(raw.header.hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
   2.247                  if (res <= 0)
   2.248                  {
   2.249                      Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
   2.250 @@ -573,13 +389,13 @@
   2.251                  //Check type of input device and quite if we don't like it
   2.252                  switch (deviceInfo.dwType)
   2.253                  {
   2.254 -                    case RIM_TYPEHID:
   2.255 +                    case Const.RIM_TYPEHID:
   2.256                          Debug.WriteLine("WM_INPUT source device is HID.");
   2.257                          break;
   2.258 -                    case RIM_TYPEMOUSE:
   2.259 +                    case Const.RIM_TYPEMOUSE:
   2.260                          Debug.WriteLine("WM_INPUT source device is Mouse.");
   2.261                          return;
   2.262 -                    case RIM_TYPEKEYBOARD:
   2.263 +                    case Const.RIM_TYPEKEYBOARD:
   2.264                          Debug.WriteLine("WM_INPUT source device is Keyboard.");
   2.265                          return;
   2.266                      default:
   2.267 @@ -591,7 +407,7 @@
   2.268                  Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
   2.269  
   2.270                  //Check that our raw input is HID
   2.271 -                if (raw.header.dwType == RIM_TYPEHID && raw.hid.dwSizeHid>0)
   2.272 +                if (raw.header.dwType == Const.RIM_TYPEHID && raw.hid.dwSizeHid>0)
   2.273  				{
   2.274                      //Allocate a buffer for one HID message
   2.275  					byte[] bRawData = new byte[raw.hid.dwSizeHid];
   2.276 @@ -633,11 +449,11 @@
   2.277                          }
   2.278                      }
   2.279  				}
   2.280 -				else if(raw.header.dwType == RIM_TYPEMOUSE)
   2.281 +				else if(raw.header.dwType == Const.RIM_TYPEMOUSE)
   2.282  				{
   2.283  					// do mouse handling...
   2.284  				}
   2.285 -				else if(raw.header.dwType == RIM_TYPEKEYBOARD)
   2.286 +				else if(raw.header.dwType == Const.RIM_TYPEKEYBOARD)
   2.287  				{
   2.288  					// do keyboard handling...
   2.289  				}
     3.1 --- a/RemoteControlSample.csproj	Thu Nov 06 21:57:53 2014 +0100
     3.2 +++ b/RemoteControlSample.csproj	Fri Nov 07 20:49:51 2014 +0100
     3.3 @@ -131,6 +131,7 @@
     3.4      <Compile Include="RemoteControlDevice.cs">
     3.5        <SubType>Code</SubType>
     3.6      </Compile>
     3.7 +    <Compile Include="Win32RawInput.cs" />
     3.8      <Content Include="App.ico" />
     3.9      <EmbeddedResource Include="Form1.resx">
    3.10        <DependentUpon>Form1.cs</DependentUpon>
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Win32RawInput.cs	Fri Nov 07 20:49:51 2014 +0100
     4.3 @@ -0,0 +1,203 @@
     4.4 +using System;
     4.5 +using System.Runtime.InteropServices;
     4.6 +
     4.7 +namespace Win32
     4.8 +{
     4.9 +
    4.10 +    static partial class Function
    4.11 +    {
    4.12 +        [DllImport("User32.dll", SetLastError = true)]
    4.13 +		public extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
    4.14 +
    4.15 +        [DllImport("User32.dll", SetLastError = true)]
    4.16 +		public extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
    4.17 +
    4.18 +   		[DllImport("User32.dll", SetLastError=true)]
    4.19 +		public extern static int GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);
    4.20 +    }
    4.21 +
    4.22 +    static partial class Const
    4.23 +    {
    4.24 +        /// <summary>
    4.25 +        /// GetRawInputDeviceInfo pData points to a string that contains the device name.
    4.26 +        /// </summary>
    4.27 +        public const uint RIDI_DEVICENAME = 0x20000007;
    4.28 +        /// <summary>
    4.29 +        /// GetRawInputDeviceInfo For this uiCommand only, the value in pcbSize is the character count (not the byte count).
    4.30 +        /// </summary>
    4.31 +        public const uint RIDI_DEVICEINFO = 0x2000000b;
    4.32 +        /// <summary>
    4.33 +        /// GetRawInputDeviceInfo pData points to an RID_DEVICE_INFO structure.
    4.34 +        /// </summary>
    4.35 +        public const uint RIDI_PREPARSEDDATA = 0x20000005;
    4.36 +
    4.37 +
    4.38 +        /// <summary>
    4.39 +        /// Data comes from a mouse.
    4.40 +        /// </summary>
    4.41 +        public const uint RIM_TYPEMOUSE = 0;
    4.42 +        /// <summary>
    4.43 +        /// Data comes from a keyboard.
    4.44 +        /// </summary>
    4.45 +        public const uint RIM_TYPEKEYBOARD = 1;
    4.46 +        /// <summary>
    4.47 +        /// Data comes from an HID that is not a keyboard or a mouse.
    4.48 +        /// </summary>
    4.49 +        public const uint RIM_TYPEHID = 2;
    4.50 +
    4.51 +    }
    4.52 +
    4.53 +
    4.54 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    4.55 +    internal struct RAWINPUTDEVICE
    4.56 +    {
    4.57 +        [MarshalAs(UnmanagedType.U2)]
    4.58 +        public ushort usUsagePage;
    4.59 +        [MarshalAs(UnmanagedType.U2)]
    4.60 +        public ushort usUsage;
    4.61 +        [MarshalAs(UnmanagedType.U4)]
    4.62 +        public int dwFlags;
    4.63 +        public IntPtr hwndTarget;
    4.64 +    }
    4.65 +
    4.66 +
    4.67 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    4.68 +    internal struct RAWINPUTHEADER
    4.69 +    {
    4.70 +        [MarshalAs(UnmanagedType.U4)]
    4.71 +        public int dwType;
    4.72 +        [MarshalAs(UnmanagedType.U4)]
    4.73 +        public int dwSize;
    4.74 +        public IntPtr hDevice;
    4.75 +        [MarshalAs(UnmanagedType.U4)]
    4.76 +        public int wParam;
    4.77 +    }
    4.78 +
    4.79 +
    4.80 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    4.81 +    internal struct RAWHID
    4.82 +    {
    4.83 +        [MarshalAs(UnmanagedType.U4)]
    4.84 +        public int dwSizeHid;
    4.85 +        [MarshalAs(UnmanagedType.U4)]
    4.86 +        public int dwCount;
    4.87 +        //
    4.88 +        //BYTE  bRawData[1];
    4.89 +    }
    4.90 +
    4.91 +
    4.92 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    4.93 +    internal struct BUTTONSSTR
    4.94 +    {
    4.95 +        [MarshalAs(UnmanagedType.U2)]
    4.96 +        public ushort usButtonFlags;
    4.97 +        [MarshalAs(UnmanagedType.U2)]
    4.98 +        public ushort usButtonData;
    4.99 +    }
   4.100 +
   4.101 +
   4.102 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
   4.103 +    internal struct RAWMOUSE
   4.104 +    {
   4.105 +        [MarshalAs(UnmanagedType.U2)]
   4.106 +        [FieldOffset(0)]
   4.107 +        public ushort usFlags;
   4.108 +        [MarshalAs(UnmanagedType.U4)]
   4.109 +        [FieldOffset(4)]
   4.110 +        public uint ulButtons;
   4.111 +        [FieldOffset(4)]
   4.112 +        public BUTTONSSTR buttonsStr;
   4.113 +        [MarshalAs(UnmanagedType.U4)]
   4.114 +        [FieldOffset(8)]
   4.115 +        public uint ulRawButtons;
   4.116 +        [MarshalAs(UnmanagedType.U4)]
   4.117 +        [FieldOffset(12)]
   4.118 +        public int lLastX;
   4.119 +        [MarshalAs(UnmanagedType.U4)]
   4.120 +        [FieldOffset(16)]
   4.121 +        public int lLastY;
   4.122 +        [MarshalAs(UnmanagedType.U4)]
   4.123 +        [FieldOffset(20)]
   4.124 +        public uint ulExtraInformation;
   4.125 +    }
   4.126 +
   4.127 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   4.128 +    internal struct RAWKEYBOARD
   4.129 +    {
   4.130 +        [MarshalAs(UnmanagedType.U2)]
   4.131 +        public ushort MakeCode;
   4.132 +        [MarshalAs(UnmanagedType.U2)]
   4.133 +        public ushort Flags;
   4.134 +        [MarshalAs(UnmanagedType.U2)]
   4.135 +        public ushort Reserved;
   4.136 +        [MarshalAs(UnmanagedType.U2)]
   4.137 +        public ushort VKey;
   4.138 +        [MarshalAs(UnmanagedType.U4)]
   4.139 +        public uint Message;
   4.140 +        [MarshalAs(UnmanagedType.U4)]
   4.141 +        public uint ExtraInformation;
   4.142 +    }
   4.143 +
   4.144 +
   4.145 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
   4.146 +    internal struct RAWINPUT
   4.147 +    {
   4.148 +        [FieldOffset(0)]
   4.149 +        public RAWINPUTHEADER header;
   4.150 +        [FieldOffset(16)]
   4.151 +        public RAWMOUSE mouse;
   4.152 +        [FieldOffset(16)]
   4.153 +        public RAWKEYBOARD keyboard;
   4.154 +        [FieldOffset(16)]
   4.155 +        public RAWHID hid;
   4.156 +    }
   4.157 +
   4.158 +
   4.159 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   4.160 +    internal struct RID_DEVICE_INFO_MOUSE
   4.161 +    {
   4.162 +        public uint dwId;
   4.163 +        public uint dwNumberOfButtons;
   4.164 +        public uint dwSampleRate;
   4.165 +        public bool fHasHorizontalWheel;
   4.166 +    }
   4.167 +
   4.168 +
   4.169 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   4.170 +    internal struct RID_DEVICE_INFO_KEYBOARD
   4.171 +    {
   4.172 +        public uint dwType;
   4.173 +        public uint dwSubType;
   4.174 +        public uint dwKeyboardMode;
   4.175 +        public uint dwNumberOfFunctionKeys;
   4.176 +        public uint dwNumberOfIndicators;
   4.177 +        public uint dwNumberOfKeysTotal;
   4.178 +    }
   4.179 +
   4.180 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
   4.181 +    internal struct RID_DEVICE_INFO_HID
   4.182 +    {
   4.183 +        public uint dwVendorId;
   4.184 +        public uint dwProductId;
   4.185 +        public uint dwVersionNumber;
   4.186 +        public ushort usUsagePage;
   4.187 +        public ushort usUsage;
   4.188 +    }
   4.189 +
   4.190 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
   4.191 +    internal struct RID_DEVICE_INFO
   4.192 +    {
   4.193 +        [FieldOffset(0)]
   4.194 +        public uint cbSize;
   4.195 +        [FieldOffset(4)]
   4.196 +        public uint dwType;
   4.197 +        [FieldOffset(8)]
   4.198 +        public RID_DEVICE_INFO_MOUSE mouse;
   4.199 +        [FieldOffset(8)]
   4.200 +        public RID_DEVICE_INFO_KEYBOARD keyboard;
   4.201 +        [FieldOffset(8)]
   4.202 +        public RID_DEVICE_INFO_HID hid;
   4.203 +    }
   4.204 +
   4.205 +
   4.206 +}
   4.207 \ No newline at end of file