예제 #1
0
        public static bool GetRawInputData(IntPtr hRawInput,
                                           ref RAWINPUTHEADER header,
                                           ref RAWMOUSE mouse,
                                           ref RAWKEYBOARD keyboard,
                                           ref RAWHID hid)
        {
            int iSize = 0;

            GetRawInputData(hRawInput, 0x10000003, IntPtr.Zero, ref iSize, Marshal.SizeOf <RAWINPUTHEADER>()); // RID_INPUT
            if (iSize == 0)
            {
                return(false);
            }

            IntPtr mem = Marshal.AllocHGlobal(iSize);

            if (mem == IntPtr.Zero)
            {
                return(false);
            }

            if (GetRawInputData(hRawInput, 0x10000003, mem, ref iSize, Marshal.SizeOf <RAWINPUTHEADER>()) != iSize)
            {
                Marshal.FreeHGlobal(mem);
                return(false);
            }

            if (Environment.Is64BitProcess)
            {
                var str = Marshal.PtrToStructure <RAWINPUT64>(mem);
                header   = str.header;
                mouse    = str.mouse;
                keyboard = str.keyboard;
                hid      = str.hid;
            }
            else
            {
                var str = Marshal.PtrToStructure <RAWINPUT32>(mem);
                header   = str.header;
                mouse    = str.mouse;
                keyboard = str.keyboard;
                hid      = str.hid;
            }

            Marshal.FreeHGlobal(mem);
            return(true);
        }
예제 #2
0
        // Raw input message
        private void _ProcessInput(ref IntPtr lResult, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            lResult = IntPtr.Zero;

            // Get data packet
            uint size = 0;

            if (0 > GetRawInputData(lParam, RID_INPUT, null, ref size, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))))
            {
                throw new Exception("Bad return value from Win32 function");
            }
            if (size <= 0)
            {
                return;
            }
            var bytes = new byte[size];

            if (0 >= GetRawInputData(lParam, RID_INPUT, bytes, ref size, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))))
            {
                throw new Exception("Bad return value from Win32 function");
            }

            // Extract the header and raw data portions
            var header = ToStruct <RAWINPUTHEADER>(bytes);

            if (header.dwSize != size)
            {
                throw new Exception("Size field mismatch");
            }
            int hdrSize = Marshal.SizeOf(typeof(RAWINPUTHEADER));
            var data    = new byte[size - hdrSize];

            Array.Copy(bytes, hdrSize, data, 0, data.Length);

            // Parse data bytes
            object obj = null;

            if (header.dwType == RIM_TYPEMOUSE)
            {
                var raw = ToStruct <RAWMOUSE>(data);
                obj = new MouseData {
                    flags = raw.usFlags, buttons = raw.ulButtons, rawButtons = raw.ulRawButtons, lastX = raw.lLastX, lastY = raw.lLastY, extraInformation = raw.ulExtraInformation
                };
            }
            if (header.dwType == RIM_TYPEKEYBOARD)
            {
                var raw = ToStruct <RAWKEYBOARD>(data);
                obj = new KeyboardData {
                    makecode = raw.usMakecode, flags = raw.usFlags, reserved = raw.usReserved, vKey = raw.usVKey, message = raw.dwMessage, extraInformation = raw.ulExtraInformation
                };
            }
            if (header.dwType == RIM_TYPEHID)
            {
                // Hid data contains 2x DWORD header plus variable-length stream of bytes
                var raw = new RAWHID();
                raw.dwSizeHid = BitConverter.ToUInt32(data, 0);
                raw.dwCount   = BitConverter.ToUInt32(data, 4);
                int len = (int)(raw.dwSizeHid * raw.dwCount);
                if (len < data.Length - 8)
                {
                    throw new Exception("RawData array length too small to fit requested elements count");
                }
                raw.bRawData = new byte[len];
                Array.Copy(data, 8, raw.bRawData, 0, raw.bRawData.Length);

                var arrays = new byte[raw.dwCount][];
                for (int i = 0; i < arrays.Length; i++)
                {
                    arrays[i] = new byte[raw.dwSizeHid];
                    Array.Copy(raw.bRawData, i * raw.dwSizeHid, arrays[i], 0, arrays[i].Length);
                }
                obj = new HidData {
                    rawData = arrays
                };
            }

            // IntPtr.Zero means there is no associated device
            if (header.hDevice == IntPtr.Zero)
            {
                // Trigger universal event & null device's event
                if (header.dwType >= 0 && header.dwType <= 2)
                {
                    Device.DeviceType tp = 0;
                    if (header.dwType == RIM_TYPEMOUSE)
                    {
                        tp = Device.DeviceType.Mouse;
                    }
                    if (header.dwType == RIM_TYPEKEYBOARD)
                    {
                        tp = Device.DeviceType.Keyboard;
                    }
                    if (header.dwType == RIM_TYPEHID)
                    {
                        tp = Device.DeviceType.Hid;
                    }
                    var dev = _nullDevices[tp];
                    InputReceived?.Invoke(this, new RawInputEventArgs(dev, obj));
                    dev.RaiseInputReceived(obj);
                }
            }
            // Data does have an associated device
            else
            {
                // Lookup device in dictionary
                if (_devices.ContainsKey(header.hDevice))
                {
                    // Trigger universal event & device object's event
                    var dev = _devices[header.hDevice];
                    InputReceived?.Invoke(this, new RawInputEventArgs(dev, obj));
                    dev.RaiseInputReceived(obj);
                }
            }
        }