コード例 #1
0
        /// <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>
        private void ProcessInputCommand(Message message)
        {
            uint dwSize = (uint)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"
            GetRawInputData(message.LParam, (uint)RID_INPUT, IntPtr.Zero, ref dwSize, System.Convert.ToUInt32((uint)(Marshal.SizeOf(typeof(RAWINPUTHEADER)))));

            IntPtr buffer = 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 (buffer != IntPtr.Zero && GetRawInputData(message.LParam, (uint)RID_INPUT, buffer, ref dwSize, System.Convert.ToUInt32((uint)(Marshal.SizeOf(new RAWINPUTHEADER())))) == dwSize)
                {
                    //Store the message information in "raw", then check that the input comes from a keyboard device before processing it to raise an appropriate KeyPressed event
                    RAWINPUT raw = (RAWINPUT)(Marshal.PtrToStructure(buffer, typeof(RAWINPUT)));

                    if (raw.header.dwType == RIM_TYPEKEYBOARD)
                    {
                        //Filter for Key Down events and then retrieve information about the keystroke
                        if (raw.keyboard.Message == WM_KEYDOWN || raw.keyboard.Message == WM_SYSKEYDOWN)
                        {
                            ushort key = raw.keyboard.VKey;

                            //On most keyboards, "extended" keys such as the arrow or page keys return two codes - the key's own code, and an
                            //"extended key" flag, which translates to 255. This flag isn't useful to us, so it can be disregarded
                            if (key > VK_LAST_KEY)
                            {
                                return;
                            }

                            //Retrieve information about the device and the key that was pressed
                            CDeviceInfo dInfo = null;

                            m_mutexDeviceList.WaitOne();
                            if (m_deviceList.Contains(raw.header.hDevice))
                            {
                                Keys myKey = System.Windows.Forms.Keys.A;

                                dInfo      = (CDeviceInfo)(m_deviceList[raw.header.hDevice]);
                                myKey      = (Keys)(Enum.Parse(typeof(Keys), Enum.GetName(typeof(Keys), key)));
                                dInfo.vKey = myKey.ToString();
                                dInfo.key  = key;
                            }
                            else
                            {
                                string errMessage = string.Format("Handle :{0} was not in hashtable. The device may support more than one handle or usage page, and is probably not a standard keyboard.", raw.header.hDevice);
                                throw (new ApplicationException(errMessage));
                            }
                            m_mutexDeviceList.Release();

                            //If the key that was pressed is valid and there was no problem retrieving information on the device, raise the KeyPressed event
                            if (dInfo != null)
                            {
                                if (KeyPressedEvent != null)
                                {
                                    KeyPressedEvent(this, new CKeyControlEventArgs(dInfo, GetDevice(message.LParam.ToInt32())));
                                }
                            }
                            else
                            {
                                string errMessage = string.Format("Received Unknown Key: {0}. Possibly an unknown device", key);
                                throw (new ApplicationException(errMessage));
                            }
                        }
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
コード例 #2
0
 public CKeyControlEventArgs(CDeviceInfo dInfo, InputDeviceType device)
 {
     m_deviceInfo = dInfo;
     m_device     = device;
 }
コード例 #3
0
        /// <summary>
        /// Iterates through the list provided by GetRawInputDeviceList, counting keyboard devices and adding them to deviceList
        /// </summary>
        /// <returns>The number of keyboard devices found</returns>
        public int EnumerateDevices()
        {
            int  NumberOfDevices = 0;
            uint deviceCount     = (uint)0;
            int  dwSize          = Marshal.SizeOf(typeof(RAWINPUTDEVICELIST));

            //Get the number of raw input devices in the list, then allocate sufficient memory and get the entire list
            if (GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, (uint)dwSize) == 0)
            {
                IntPtr pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount));
                GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, (uint)dwSize);

                m_mutexDeviceList.WaitOne();
                m_deviceList.Clear();

                //Iterate through the list, discarding undesired items and retrieving further information on keyboard devices
                for (var i = 0; i <= deviceCount - 1; i++)
                {
                    CDeviceInfo dInfo      = default(CDeviceInfo);
                    string      deviceName = "";
                    uint        pcbSize    = (uint)0;

                    RAWINPUTDEVICELIST rid = (RAWINPUTDEVICELIST)(Marshal.PtrToStructure(new IntPtr(pRawInputDeviceList.ToInt32() + (dwSize * i)), typeof(RAWINPUTDEVICELIST)));

                    GetRawInputDeviceInfo(rid.hDevice, (uint)RIDI_DEVICENAME, IntPtr.Zero, ref pcbSize);

                    if (pcbSize > 0)
                    {
                        IntPtr pData = Marshal.AllocHGlobal((int)pcbSize);
                        GetRawInputDeviceInfo(rid.hDevice, (uint)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 == RIM_TYPEKEYBOARD | rid.dwType == RIM_TYPEHID)
                        {
                            dInfo = new CDeviceInfo();

                            dInfo.deviceName   = Marshal.PtrToStringAnsi(pData);
                            dInfo.deviceHandle = rid.hDevice;
                            dInfo.deviceType   = GetDeviceType(rid.dwType);

                            //Check the Registry to retrieve a more friendly description.
                            string DeviceDesc = ReadReg(deviceName);
                            dInfo.Name = DeviceDesc;

                            //If it isn't already in the list, add it to the deviceList hashtable and increase the NumberOfDevices count
                            if (!m_deviceList.Contains(rid.hDevice))
                            {
                                NumberOfDevices++;
                                m_deviceList.Add(rid.hDevice, dInfo);
                            }
                        }

                        Marshal.FreeHGlobal(pData);
                    }
                }
                m_mutexDeviceList.Release();

                Marshal.FreeHGlobal(pRawInputDeviceList);

                return(NumberOfDevices);
            }
            else
            {
                throw (new ApplicationException("An error occurred while retrieving the list of devices."));
            }
        }