private static RAWINPUTDEVICELIST[] EnumerateDevices(RawInputDeviceType ty) { RAWINPUTDEVICELIST[] retVal = null; uint count = 0; int res = Function.GetRawInputDeviceList(retVal, ref count, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))); retVal = new RAWINPUTDEVICELIST[count]; res = Function.GetRawInputDeviceList(retVal, ref count, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))); return(retVal.Where(x => x.dwType == ty).ToArray()); }
/// <summary> /// /// </summary> /// <param name="hdevice"></param> public void ProcessRawInput(IntPtr hdevice) { var size = 0; // Determine Size to be allocated //var dwSiz = 0; //int ret2 = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref dwSiz, Marshal.SizeOf(typeof(Rawinputheader))); var ret = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref size, Marshal.SizeOf(typeof(Rawinputheader))); if (ret == -1) { Console.WriteLine("error"); return; } int sizeToAllocate = Math.Max(size, Marshal.SizeOf(typeof(RawInput_Marshalling))); IntPtr pData = Marshal.AllocHGlobal(sizeToAllocate); try { //Populate alocated memory ret = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, pData, ref sizeToAllocate, Marshal.SizeOf(typeof(Rawinputheader))); if (ret == -1) { throw new System.ComponentModel.Win32Exception(); } Rawinputheader header = (Rawinputheader)Marshal.PtrToStructure(pData, typeof(Rawinputheader)); //RAWINPUT starts with RAWINPUTHEADER, so we can do this RawInputDeviceType type = (RawInputDeviceType)header.dwType; switch (type) { case RawInputDeviceType.RIM_TYPEHID: { //As described on page of RAWHID, RAWHID needs special treatement RawInput_Marshalling raw = (RawInput_Marshalling)Marshal.PtrToStructure(pData, typeof(RawInput_Marshalling)); //Get marshalling version, it contains information about block size and count RawInput_NonMarshalling raw2 = default(RawInput_NonMarshalling); //Do some copying raw2.header = raw.header; raw2.hid.dwCount = raw.hid.dwCount; raw2.hid.dwSizHid = raw.hid.dwSizHid; var numBytes = raw.hid.dwCount * raw.hid.dwSizHid; byte[] data = new byte[numBytes]; // ERROR: Not supported in C#: ReDimStatement //Allocate array //Populate the array IntPtr rawData = new IntPtr( pData.ToInt64() + Marshal.SizeOf(typeof(Rawinputheader)) + Marshal.SizeOf(typeof(Rawhid_Marshalling))); Marshal.Copy(rawData, data, 0, (int)numBytes); // Extract X & Y byte[] xBytes = new byte[4]; Buffer.BlockCopy(data, 6, xBytes, 0, 4); byte[] yBytes = new byte[4]; Buffer.BlockCopy(data, 10, yBytes, 0, 4); int x = BitConverter.ToInt32(xBytes, 0); int y = BitConverter.ToInt32(yBytes, 0); Console.WriteLine($"X: {x}\tY: {y}"); if (TouchActivated != null) { TouchActivated(this, new RawInputEventArg(x, y)); } //return raw2; break; } default: { //No additional processing is needed var x = (RawInput_Marshalling)Marshal.PtrToStructure(pData, typeof(RawInput_Marshalling)); break; } } } finally { Marshal.FreeHGlobal(pData); } }
/// <summary> /// Constructor, fill as much Hidp_Struct as we can at the creation /// </summary> /// <param name="DeviceHandle">A handle to the raw input device.</param> /// <param name="DeviceType">The type of the raw input device</param> /// <param name="Caller">Caller class so that we can send data back for WriteLogDebug</param> public RawInputController(IntPtr DeviceHandle, RawInputDeviceType DeviceType) { _hDevice = DeviceHandle; _dwType = DeviceType; _DeviceName = String.Empty; _ManufacturerName = String.Empty; _ProductName = String.Empty; _pPreparsedData = IntPtr.Zero; _Hid_NumberofButtons = 0; _Hid_Axis_List = new List <ushort>(); GetDeviceName(); GetDeviceInfo(); //DeviceName is also the path to acces the device with OpenFile GetManufacturerAndProductString(_DeviceName); if (_dwType == RawInputDeviceType.RIM_TYPEHID) { _pPreparsedData = GetPreparsedData(); if (_pPreparsedData != IntPtr.Zero) { if (!GetCapabilities(_pPreparsedData, out _Caps)) { Logger.WriteLog("Error: Impossible to get Capabilities for device " + _DeviceName); return; } if (!GetButtonCapabilities(_pPreparsedData, _Caps, out _pButtonCaps)) { Logger.WriteLog("Error: Impossible to get Button Capabilities for device " + _DeviceName); return; } _Hid_NumberofButtons = GetNumberOfHidDeviceButtons(_pPreparsedData, _pButtonCaps); _Hid_Buttons = new bool[_Hid_NumberofButtons]; if (!GetValueCapabilities(_pPreparsedData, _Caps, out _pValueCaps)) { Logger.WriteLog("Error: Impossible to get Value Capabilities for device " + _DeviceName); return; } if (!GetOutputValueCapabilities(_pPreparsedData, _Caps, out _pOutputValueCaps)) { Logger.WriteLog("Error: Impossible to get Output Value Capabilities for device " + _DeviceName); //return; } //Number of absolute axis for (int i = 0; i < _pValueCaps.Length; i++) { if (_pValueCaps[i].IsAbsolute) { _Hid_NumberofAxis++; _Hid_Axis_List.Add(_pValueCaps[i].Range.UsageMin); } } } } else if (_dwType == RawInputDeviceType.RIM_TYPEMOUSE) { //A mouse only have 1 set of axis : X,Y _Hid_Buttons = new bool[_DeviceInfo.mouse.dwNumberOfButtons]; } }
/// <summary> /// /// </summary> /// <param name="hdevice"></param> public void ProcessRawInput(IntPtr hdevice) { var size = 0; // Determine Size to be allocated //var dwSiz = 0; //int ret2 = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref dwSiz, Marshal.SizeOf(typeof(Rawinputheader))); var ret = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref size, Marshal.SizeOf(typeof(Rawinputheader))); if (ret == -1) { Console.WriteLine("error"); return; } int sizeToAllocate = Math.Max(size, Marshal.SizeOf(typeof(RawInput_Marshalling))); IntPtr pData = Marshal.AllocHGlobal(sizeToAllocate); try { //Populate alocated memory ret = Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, pData, ref sizeToAllocate, Marshal.SizeOf(typeof(Rawinputheader))); if (ret == -1) { throw new System.ComponentModel.Win32Exception(); } Rawinputheader header = (Rawinputheader)Marshal.PtrToStructure(pData, typeof(Rawinputheader)); //RAWINPUT starts with RAWINPUTHEADER, so we can do this RawInputDeviceType type = (RawInputDeviceType)header.dwType; switch (type) { case RawInputDeviceType.RIM_TYPEHID: { //As described on page of RAWHID, RAWHID needs special treatement RawInput_Marshalling raw = (RawInput_Marshalling)Marshal.PtrToStructure(pData, typeof(RawInput_Marshalling)); //Do some copying //raw2.header = raw.header; ReadDeviceInfo(raw.header.hDevice); var numBytes = raw.header.dwSize - (Marshal.SizeOf(typeof(Rawinputheader)) + Marshal.SizeOf(typeof(Rawhid_Marshalling))); // * raw.hid.dwSizHid; byte[] data = new byte[numBytes]; // ERROR: Not supported in C#: ReDimStatement //Allocate array //Populate the array // new pointer - offset by header sizes IntPtr rawData = new IntPtr( pData.ToInt64() + Marshal.SizeOf(typeof(Rawinputheader)) + Marshal.SizeOf(typeof(Rawhid_Marshalling))); Marshal.Copy(rawData, data, 0, (int)numBytes); if (numBytes > 0) { for (int i = 0; i < numBytes; ++i) { Console.Write(String.Format("{0:X2}", data[i])); } Console.WriteLine(); TouchInfo ti = new TouchInfo(data); //Console.WriteLine(ti.X() + " " + ti.Y()); if (TouchActivated != null) { TouchActivated(this, ti); } } else { Console.WriteLine("no bytes..."); } //return raw2; break; } default: { //No additional processing is needed var x = (RawInput_Marshalling)Marshal.PtrToStructure(pData, typeof(RawInput_Marshalling)); break; } } } finally { Marshal.FreeHGlobal(pData); } }