从设备界面获取鼠标设备句柄

时间:2016-03-20 14:58:18

标签: c# winapi windows-10

我有一个系统,其中存在几个(物理)小鼠。代码是在Windows 10平台上用C#编写的。在任何给定的时间,我都希望能够过滤除我选择的鼠标之外的所有鼠标的输入。为了做到这一点,我想:

  1. 使用字典/散列表来保存系统中的所有鼠标设备,其中键是鼠标设备句柄,值是人类可读的描述。例如,我可以用这些描述填充一个组合框,然后选择我想要使用的鼠标。

  2. 此外,当点击鼠标(任何鼠标)时,我想知道它是哪一只鼠标,换句话说我想知道最后一只鼠标的设备句柄。

    < / LI>

    我使用http://www.pinvoke.net上给出的精彩示例略有不同。

    我可以做(2),我几乎可以做(1),但似乎缺少某些东西。 这就是我的做法(2):

        public int GetDeviceID(Message message, out ushort button, out ushort data)
        {
            uint dwSize = 0;
    
            GetRawInputData(
                message.LParam,
                RID_INPUT,
                IntPtr.Zero,
                ref dwSize,
                (uint)Marshal.SizeOf(typeof(RawInputHeader))
            );
    
            IntPtr buffer = Marshal.AllocHGlobal((int)dwSize);
    
            GetRawInputData(
                message.LParam,
                RID_INPUT,
                buffer,
                ref dwSize,
                (uint)Marshal.SizeOf(typeof(RawInputHeader))
            );
    
            RawInput raw = (RawInput)Marshal.PtrToStructure(buffer, typeof(RawInput));
            Marshal.FreeHGlobal(buffer);
            button = (ushort)raw.Mouse.ButtonFlags;
            data = raw.Mouse.ButtonData;
            if (raw.Header.dwType == (int)RawInputType.Mouse)
            {
                return (int)raw.Header.hDevice;
            }
    
            return 0;
        }
    

    这是我试图做的事情(1):

        private void GetDevices()
        {
            Guid MouseGUID = GUID_DEVINTERFACE_MOUSE;
    
            // We start at the "root" of the device tree and look for all
            // devices that match the interface GUID of a mouse
            IntPtr h = SetupDiGetClassDevs(ref MouseGUID, IntPtr.Zero, IntPtr.Zero, (int)(DIGCF.DIGCF_PRESENT | DIGCF.DIGCF_DEVICEINTERFACE));
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                bool Success = true;
                uint i = 0;
                while (Success)
                {
                    // create a Device Interface Data structure
                    SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
                    dia.cbSize = Marshal.SizeOf(dia);
    
                    // start the enumeration
                    Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref MouseGUID, i++, ref dia);
                    if (Success)
                    {
                        // build a DevInfo Data structure
                        SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                        da.cbSize = (uint)Marshal.SizeOf(da);
    
                        // build a Device Interface Detail Data structure
                        SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
                        didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :)
    
                        // now we can get some more detailed information
                        uint nRequiredSize = 0;
                        uint nBytes = BUFFER_SIZE;
                        if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
                        {
                            // get the Device Description and DriverKeyName.
                            // what i actually want is the device handle...
                            uint RequiredSize;
                            uint RegType;
                            byte[] ptrBuf = new byte[BUFFER_SIZE];
                            IntPtr intPtrBuf = Marshal.AllocHGlobal(ptrBuf.Length);
    
                            if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, out RegType, ptrBuf, BUFFER_SIZE, out RequiredSize))
                            {
                                Marshal.Copy(ptrBuf, 0, intPtrBuf, (int)RequiredSize);
                                string ControllerDeviceDesc = Marshal.PtrToStringAuto(intPtrBuf);
                                //...
    
                            }
                            if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, out RegType, ptrBuf, BUFFER_SIZE, out RequiredSize))
                            {
                                Marshal.Copy(ptrBuf, 0, intPtrBuf, (int)RequiredSize);
                                string ControllerDriverKeyName = Marshal.PtrToStringAuto(intPtrBuf);
                                //...
                            }
    
                            Marshal.FreeHGlobal(intPtrBuf);
                        }
                    }
                }
            }
            SetupDiDestroyDeviceInfoList(h);
        }
    

    我找不到任何方法从SetupDiXXX函数及其输出到设备句柄。我能看到的最接近的是SP_DEVINFO_DATA.devInst,但这只是设备实例的一个不透明句柄,所以不太有用。 我还查看了设备注册表属性代码(SPDRP)列表,但没有代码引用设备句柄。

    谢谢:)

0 个答案:

没有答案