Esempio n. 1
0
        /// <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));
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
 /// <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));
 }