public RawInput(IntPtr handle) { this.handle = handle; mice = new List <DeviceInfo>(); keyboards = new List <DeviceInfo>(); otherDevices = new List <DeviceInfo>(); RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1]; rid[0].usUsagePage = Win32RawInput.HID_HWIND.HidMouse.UsagePage; rid[0].usUsage = Win32RawInput.HID_HWIND.HidMouse.UsageId; rid[0].dwFlags = (int)RIDEV.INPUTSINK; rid[0].hwndTarget = handle; if (!Win32RawInput.RegisterRawInputDevices(rid, rid.Length, Marshal.SizeOf(rid[0]))) { throw new Win32Exception("Failed to register raw input device(s)."); } int loadedDevices = LoadDevices(); if (mice.Count <= 0) { throw new Win32Exception("Unable to detect an attached mouse"); } }
public void ProcessInput(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (mice.Count <= 0) { return; } RAWINPUT raw = Win32RawInput.GetInputData(lParam); if (raw.header.dwType == (int)RIM.TYPEMOUSE) { RawInputEvent(this, new RawInputEventArgs(RawInputAction.MouseMove)); } /* * uint dwSize = 0; * uint result = 0; * * // First call to GetRawInputData sets the value of dwSize, which can then be used to allocate the appropriate * // amount of memory, storing the pointer in "buffer". * result = Win32RawInput.GetRawInputData(lParam, RID.INPUT, IntPtr.Zero, ref dwSize, Marshal.SizeOf(typeof(RAWINPUTHEADER))); * if (result == 0) * { * IntPtr buffer = Marshal.AllocHGlobal((int)dwSize); * try * { * result = Win32RawInput.GetRawInputData(lParam, RID.INPUT, buffer, ref dwSize, Marshal.SizeOf(typeof(RAWINPUTHEADER))); * if (buffer != IntPtr.Zero && result == dwSize) * { * RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT)); * * // Only listening for mouse move events at the moment. * if (raw.header.dwType == (int)RIM.TYPEMOUSE) * { * DeviceInfo mouse = mice[0]; * * //if ((raw.mouse.usFlags & (ushort)MouseEventFlags.MOVE) != 0 || * // (raw.mouse.usFlags & (ushort)MouseEventFlags.ABSOLUTE) != 0) * //{ * // Debug.WriteLine("MouseMove"); * // RawInputEvent(this, new RawInputEventArgs(RawInputAction.MouseMove)); * //} * //RawInputEvent(this, new RawInputEventArgs(RawInputAction.MouseMove)); * } * } * } * finally * { * Marshal.FreeHGlobal(buffer); * } * } */ }
public const float DEFAULT_CAMERA_POSITION_Z = -2.415f; // matches a 2-unit height rectangle in origin at 45 degree FOV #region RAW-MouseData /** * Because MouseMove event is not triggered if CompositionTarget.Render * gets too complex, this method uses raw input from user32 as a workaround * to provide interactive mouse rotation. * * Because MouseDown/MouseUp events are also not triggered, we have to * rely on the virtual key for the left mouse button to check if a dragging * is currently happening. * * Read more at https://streber.framefield.com/5381 */ private void UpdateRawMouseData() { Win32RawInput.POINT screenSpacePoint; Win32RawInput.GetCursorPos(out screenSpacePoint); // note that screenSpacePoint is in screen-space pixel coordinates, // not the same WPF Units you get from the MouseMove event. // You may want to convert to WPF units when using GetCursorPos. var currentMousePosition = new Point(screenSpacePoint.X, screenSpacePoint.Y); const int LEFT_BUTTON_VIRTUAL_KEY_CODE = 0x01; const int RIGHT_BUTTON_VIRTUAL_KEY_CODE = 0x02; const int MIDDLE_BUTTON_VIRTUAL_KEY_CODE = 0x04; /** * sadly, we can't use this flags for anything more that determing with "something" was dragged with * "some" mouseButton. We can't assign this flags to the members controlled by the MouseDown/Up handlers * because this would interfer with the focus-state can the window's mouse capute and thus cause camera * manipulation even if the mouse is no longer inside the window. I know, that this is a mindfuck. */ var leftMousePressed = Convert.ToInt32(Win32RawInput.GetAsyncKeyState(LEFT_BUTTON_VIRTUAL_KEY_CODE)) != 0; var rightMousePressed = Convert.ToInt32(Win32RawInput.GetAsyncKeyState(RIGHT_BUTTON_VIRTUAL_KEY_CODE)) != 0; var middleMousePressed = Convert.ToInt32(Win32RawInput.GetAsyncKeyState(MIDDLE_BUTTON_VIRTUAL_KEY_CODE)) != 0; var mousePressed = leftMousePressed || rightMousePressed || middleMousePressed; if (_showSceneControl.IsFocused && mousePressed) { if (_mouseWasReleased) { _mouseDragDelta = new Vector(); _mouseWasReleased = false; } else { _mouseDragDelta = currentMousePosition - _mousePos; } } else { _mouseDragDelta = new Vector(); _mouseWasReleased = true; } _mouseMoveDelta = currentMousePosition - _mousePos; _mousePos = currentMousePosition; }
protected virtual void Dispose(bool disposing) { if (!_disposed) { _disposed = true; if (disposing) { // Dispose managed resources // N/A } // Dispose unmanaged resources. RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1]; rid[0].usUsagePage = Win32RawInput.HID_HWIND.HidMouse.UsagePage; rid[0].usUsage = Win32RawInput.HID_HWIND.HidMouse.UsageId; rid[0].dwFlags = (int)RIDEV.REMOVE; rid[0].hwndTarget = this.handle; Win32RawInput.RegisterRawInputDevices(rid, rid.Length, Marshal.SizeOf(rid[0])); } }
public int LoadDevices() { uint deviceCount = 0; int dwSize = (Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))); uint result = Win32RawInput.GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, dwSize); if (result != 0) { throw new Win32Exception("Failed to get raw input devices"); } IntPtr pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount)); Win32RawInput.GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, dwSize); for (int i = 0; i < deviceCount; i++) { //DeviceInfo dInfo; //string deviceName; //uint pcbSize = 0; IntPtr ptr = new IntPtr(pRawInputDeviceList.ToInt64() + (dwSize * i)); RAWINPUTDEVICELIST rid = (RAWINPUTDEVICELIST)Marshal.PtrToStructure(ptr, typeof(RAWINPUTDEVICELIST)); string deviceName = Win32RawInput.GetDeviceName(rid.hDevice); // Drop the "root" keyboard and mouse devices used for Terminal Services and the Remote Desktop. if (!String.IsNullOrEmpty(deviceName) && !deviceName.ToUpper().Contains("ROOT")) { switch ((RIM)rid.dwType) { case RIM.TYPEMOUSE: case RIM.TYPEKEYBOARD: case RIM.TYPEHID: DeviceInfo dInfo = new DeviceInfo() { DeviceName = deviceName, DeviceHandle = rid.hDevice, DeviceType = (RIM)rid.dwType, }; var additionalInfo = ReadRegisty(deviceName); if (additionalInfo.ContainsKey("DeviceDesc")) { dInfo.Name = additionalInfo["DeviceDesc"]; } if (additionalInfo.ContainsKey("Class")) { string deviceClass = additionalInfo["Class"] ?? ""; switch (deviceClass.ToUpper()) { case "KEYBOARD": if (!keyboards.Contains(dInfo)) { keyboards.Add(dInfo); deviceCount++; } break; case "MOUSE": if (!mice.Contains(dInfo)) { mice.Add(dInfo); deviceCount++; } break; default: if (!otherDevices.Contains(dInfo)) { otherDevices.Add(dInfo); deviceCount++; } break; } } deviceCount++; break; } } /* * if (!String.IsNullOrEmpty(deviceName) && !deviceName.ToUpper().Contains("ROOT")) * { * switch ((RIM)rid.dwType) * { * case RIM.TYPEMOUSE: * case RIM.TYPEKEYBOARD: * case RIM.TYPEHID: * DeviceInfo dInfo = new DeviceInfo(); * * dInfo.DeviceName = deviceName; * dInfo.DeviceHandle = rid.hDevice; * dInfo.DeviceType = GetDeviceType(rid.dwType); * * var additionalInfo = ReadRegisty(deviceName); * dInfo.Name = additionalInfo["DeviceDesc"]; * * switch (additionalInfo["Class"].ToUpper()) * { * case "KEYBOARD": * if (!keyboards.Contains(dInfo)) * { * keyboards.Add(dInfo); * deviceCount++; * } * break; * case "MOUSE": * if (!mice.Contains(dInfo)) * { * mice.Add(dInfo); * deviceCount++; * } * break; * default: * if (!otherDevices.Contains(dInfo)) * { * otherDevices.Add(dInfo); * deviceCount++; * } * break; * } * deviceCount++; * break; * } * } */ /* * * Win32RawInput.GetRawInputDeviceInfo(rid.hDevice, RIDI.DEVICENAME, IntPtr.Zero, ref pcbSize); * if (pcbSize > 0) * { * * Win32RawInput.GetRawInputDeviceInfo(rid.hDevice, RIDI.DEVICENAME, pData, ref pcbSize); * deviceName = (string)Marshal.PtrToStringAnsi(pData); * * // Drop the "root" keyboard and mouse devices used for Terminal * // Services and the Remote Desktop * if (deviceName.ToUpper().Contains("ROOT")) * { * continue; * } * * // If the device is identified in the list as a keyboard or * // HID device, create a DeviceInfo object to store information * // about it * if (rid.dwType == (int)RIM.TYPEMOUSE || rid.dwType == (int)RIM.TYPEKEYBOARD || rid.dwType == (int)RIM.TYPEHID) * { * dInfo = new DeviceInfo(); * * dInfo.DeviceName = (string)Marshal.PtrToStringAnsi(pData); * dInfo.DeviceHandle = rid.hDevice; * dInfo.DeviceType = GetDeviceType(rid.dwType); * * var additionalInfo = ReadRegisty(deviceName); * dInfo.Name = additionalInfo["DeviceDesc"]; * * switch (additionalInfo["Class"].ToUpper()) * { * case "KEYBOARD": * if (!keyboards.Contains(dInfo)) * { * keyboards.Add(dInfo); * deviceCount++; * } * break; * case "MOUSE": * if (!mice.Contains(dInfo)) * { * mice.Add(dInfo); * deviceCount++; * } * break; * default: * if (!otherDevices.Contains(dInfo)) * { * otherDevices.Add(dInfo); * deviceCount++; * } * break; * } * deviceCount++; * } * Marshal.FreeHGlobal(pData); * } */ } Marshal.FreeHGlobal(pRawInputDeviceList); return((int)deviceCount); }