/// <summary> /// Gets the address of the unmanaged (native) memory block containing the raw data. /// </summary> /// <remarks> /// Each RawInput event can indicate several inputs from the same device. /// <para> /// The size of the memory block is DataSize * DataCount. /// </para> /// </remarks> /// <param name="dataSize">Size, in bytes, of each raw input.</param> /// <param name="dataCount">Number of raw inputs.</param> /// <returns></returns> public unsafe IntPtr GetDataPtr(out int dataSize, out int dataCount) { if (hGlobal == IntPtr.Zero) { throw new ObjectDisposedException("DeviceData"); } RAWINPUT *pInput = (RAWINPUT *)hGlobal; dataSize = (int)pInput->hid.dwSizeHid; dataCount = (int)pInput->hid.dwCount; return((IntPtr)(&pInput->hid.bRawData)); }
private unsafe IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { Message m; m.hWnd = hWnd; m.msg = msg; m.wParam = wParam; m.lParam = lParam; switch (msg) { case WM.INPUT: int sizeOfRawInputData = 0; User32.GetRawInputData( lParam, RID_INPUT, (byte *)0, ref sizeOfRawInputData, s_size_of_rawinputheader); if (sizeOfRawInputData == 0) { return(IntPtr.Zero); } byte *rawInputDataPtr = stackalloc byte[sizeOfRawInputData]; if (User32.GetRawInputData( lParam, RID_INPUT, rawInputDataPtr, ref sizeOfRawInputData, s_size_of_rawinputheader) != RID_ERROR) { RAWINPUT *rawInput = (RAWINPUT *)rawInputDataPtr; switch (rawInput->Header.Type) { case RID_INPUT_TYPE_MOUSE: RawMouseInput(in rawInput->Data.Mouse); break; // not supported/needed atm. case RID_INPUT_TYPE_KEYBOARD: case RID_INPUT_TYPE_HID: case RID_INPUT_TYPE_OTHER: break; } } return(IntPtr.Zero); case WM.MOUSELEAVE: _state &= ~MOUSE_LE_STATE; MouseLeave?.Invoke(_hWnd); return(IntPtr.Zero); case WM.SIZE: _size.X = LowWord(lParam); _size.Y = HighWord(lParam); return(IntPtr.Zero); case WM.CLOSE: bool cancel = false; FormClosing?.Invoke(ref cancel); if (!cancel) { FormClosed?.Invoke(); User32.DestroyWindow(_hWnd); } return(IntPtr.Zero); case WM.DESTROY: MouseLeave?.Invoke(_hWnd); User32.PostQuitMessage(0); return(IntPtr.Zero); case WM.KEYDOWN: case WM.KEYUP: case WM.CHAR: case WM.UNICHAR: case WM.SYSKEYDOWN: case WM.SYSKEYUP: RawKeyMessage(ref m); return(IntPtr.Zero); case WM.LBUTTONDOWN: RawMouseDown(ref m, MouseButtons.Left); return(IntPtr.Zero); case WM.MBUTTONDOWN: RawMouseDown(ref m, MouseButtons.Middle); return(IntPtr.Zero); case WM.RBUTTONDOWN: RawMouseDown(ref m, MouseButtons.Right); return(IntPtr.Zero); case WM.XBUTTONDOWN: RawMouseDown( ref m, HighWord(m.wParam) == 1 ? MouseButtons.XButton1 : MouseButtons.XButton2); return(IntPtr.Zero); case WM.LBUTTONUP: RawMouseUp(ref m, MouseButtons.Left); return(IntPtr.Zero); case WM.MBUTTONUP: RawMouseUp(ref m, MouseButtons.Middle); return(IntPtr.Zero); case WM.RBUTTONUP: RawMouseUp(ref m, MouseButtons.Right); return(IntPtr.Zero); case WM.XBUTTONUP: RawMouseUp( ref m, HighWord(m.wParam) == 1 ? MouseButtons.XButton1 : MouseButtons.XButton2); return(IntPtr.Zero); case WM.MOUSEMOVE: { if ((_state & MOUSE_LE_STATE) != MOUSE_LE_STATE) { _state |= MOUSE_LE_STATE; MouseEnter?.Invoke(_hWnd); TRACKMOUSEEVENT trackMouseEvent = new TRACKMOUSEEVENT(TME.LEAVE, _hWnd, 0); if (!User32.TrackMouseEvent(ref trackMouseEvent)) { throw new Win32Exception( Kernel32.GetLastError(), $"{nameof(User32.TrackMouseEvent)} failed!"); } } MouseEventArgs args = new MouseEventArgs( LowWord(m.lParam), HighWord(m.lParam), (MouseButtons)LowWord(m.wParam), 0, 0); for (int i = 0; i < _mouseMovePipe.Count; i++) { if (_mouseMovePipe[i].Invoke(args) == EventAction.StopPropagation) { break; } } return(IntPtr.Zero); } case WM.MOUSEWHEEL: { MouseEventArgs args = new MouseEventArgs( LowWord(m.lParam), HighWord(m.lParam), (MouseButtons)LowWord(m.wParam), 0, HighWord(m.wParam)); for (int i = 0; i < _mouseWheelPipe.Count; i++) { if (_mouseWheelPipe[i].Invoke(args) == EventAction.StopPropagation) { break; } } } return(IntPtr.Zero); case WM.LBUTTONDBLCLK: case WM.MBUTTONDBLCLK: case WM.RBUTTONDBLCLK: case WM.XBUTTONDBLCLK: { _state |= 0xC000000; MouseEventArgs args = new MouseEventArgs( LowWord(m.lParam), HighWord(m.lParam), (MouseButtons)LowWord(m.wParam), 2, 0); for (int i = 0; i < _mouseClickPipe.Count; i++) { if (_mouseClickPipe[i].Invoke(args) == EventAction.StopPropagation) { break; } } return(IntPtr.Zero); } } return(User32.DefWindowProc(hWnd, msg, wParam, lParam)); }
/// <summary> /// Retrieves the location of the next structure in an array of <see cref="RAWINPUT"/> structures. /// </summary> /// <remarks>This macro is called repeatedly to traverse an array of <see cref="RAWINPUT"/> structures.</remarks> /// <param name="ptr">A pointer to a structure in an array of <see cref="RAWINPUT"/> structures.</param> /// <returns>The return value is a pointer to the next structure in the array of <see cref="RAWINPUT"/> structures.</returns> public static unsafe RAWINPUT *NEXTRAWINPUTBLOCK(RAWINPUT *ptr) { return((RAWINPUT *)RAWINPUT_ALIGN((IntPtr)ptr + (int)ptr->header.dwSize)); }