/// <summary> /// Processes WM_INPUT messages to retrieve information about any /// keyboard events that occur. /// </summary> /// <param name="message">The WM_INPUT message to process.</param> public void ProcessInputCommand(Message message) { uint dwSize = 0; // First call to GetRawInputData sets the value of dwSize // dwSize can then be used to allocate the appropriate amount of memory, // storing the pointer in "buffer". GetRawInputData(message.LParam, RID_HEADER, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))); var headerBuffer = Marshal.AllocHGlobal((int)dwSize); try { // Check that buffer points to something, and if so, // call GetRawInputData again to fill the allocated memory // with information about the input if (headerBuffer != IntPtr.Zero && GetRawInputData(message.LParam, RID_HEADER, headerBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) == dwSize) { var header = (RAWINPUTHEADER)Marshal.PtrToStructure(headerBuffer, typeof(RAWINPUTHEADER)); if (header.dwType == RIM_TYPEHID) { DeviceInfo dInfo = null; if (deviceList.Contains(header.hDevice)) { dInfo = (DeviceInfo)deviceList[header.hDevice]; } else { // Device not in list. Reenumerate all of them again. Could warn the code with some sort of Connect/Disconnect event. EnumerateDevices(); dInfo = (DeviceInfo)deviceList[header.hDevice]; } // The header tells us the size of the actual event var eventBuffer = Marshal.AllocHGlobal(header.dwSize); var eventSize = (uint)header.dwSize; if (eventBuffer != IntPtr.Zero && GetRawInputData(message.LParam, RID_INPUT, eventBuffer, ref eventSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) == header.dwSize) { var eventType = (RAW3DMOUSE_EVENTTYPE)Marshal.PtrToStructure(new IntPtr(eventBuffer.ToInt32() + Marshal.SizeOf(typeof(RAWINPUTHEADER))), typeof(RAW3DMOUSE_EVENTTYPE)); switch (eventType.eventType) { case (byte)RAW3DxMouseEventType.TranslationVector: if (header.dwSize == Marshal.SizeOf(typeof(RAWINPUTHEADER)) + SIZEOF_STANDARD_REPORT) // standard length T report { var t = (RAW3DMOUSEMOTION_T)Marshal.PtrToStructure(new IntPtr(eventBuffer.ToInt32() + Marshal.SizeOf(typeof(RAWINPUTHEADER))), typeof(RAW3DMOUSEMOTION_T)); var tv = new TranslationVector(t.X_lb, t.X_hb, t.Y_lb, t.Y_hb, t.Z_lb, t.Z_hb); // Console.Write("Motion Event = {0} {1} {2}", tv.X, tv.Y, tv.Z); MotionEvent(this, new MotionEventArgs(dInfo, tv)); } else // "High Speed" firmware version includes both T and R vector in the same report { var tr = (RAW3DMOUSEMOTION_TR_COMBINED)Marshal.PtrToStructure(new IntPtr(eventBuffer.ToInt32() + Marshal.SizeOf(typeof(RAWINPUTHEADER))), typeof(RAW3DMOUSEMOTION_TR_COMBINED)); var tv = new TranslationVector(tr.X_lb, tr.X_hb, tr.Y_lb, tr.Y_hb, tr.Z_lb, tr.Z_hb); var rv = new RotationVector(tr.RX_lb, tr.RX_hb, tr.RY_lb, tr.RY_hb, tr.RZ_lb, tr.RZ_hb); // Console.WriteLine("6DOF Motion Event = {0} {1} {2} {3} {4} {5}", tv.X, tv.Y, tv.Z, rv.X, rv.Y, rv.Z); MotionEvent(this, new MotionEventArgs(dInfo, tv, rv)); } break; case (byte)RAW3DxMouseEventType.RotationVector: { var r = (RAW3DMOUSEMOTION_R)Marshal.PtrToStructure(new IntPtr(eventBuffer.ToInt32() + Marshal.SizeOf(typeof(RAWINPUTHEADER))), typeof(RAW3DMOUSEMOTION_R)); var rv = new RotationVector(r.X_lb, r.X_hb, r.Y_lb, r.Y_hb, r.Z_lb, r.Z_hb); // Console.WriteLine(" {0} {1} {2}", rv.X, rv.Y, rv.Z); MotionEvent(this, new MotionEventArgs(dInfo, rv)); } break; case (byte)RAW3DxMouseEventType.ButtonReport: var b = (RAW3DMOUSEBUTTONS)Marshal.PtrToStructure(new IntPtr(eventBuffer.ToInt32() + Marshal.SizeOf(typeof(RAWINPUTHEADER))), typeof(RAW3DMOUSEBUTTONS)); var bm = new ButtonMask(b.b1, b.b2, b.b3, b.b4); Console.WriteLine("raw.buttons = {0:X}", bm.Pressed); ButtonEvent(this, new ButtonEventArgs(dInfo, bm)); break; } } } } } finally { Marshal.FreeHGlobal(headerBuffer); } }
public MotionEventArgs(DeviceInfo dInfo, TranslationVector translationVector) { m_deviceInfo = dInfo; m_translationVector = translationVector; }