我有一个系统,其中存在几个(物理)小鼠。代码是在Windows 10平台上用C#编写的。在任何给定的时间,我都希望能够过滤除我选择的鼠标之外的所有鼠标的输入。为了做到这一点,我想:
使用字典/散列表来保存系统中的所有鼠标设备,其中键是鼠标设备句柄,值是人类可读的描述。例如,我可以用这些描述填充一个组合框,然后选择我想要使用的鼠标。
此外,当点击鼠标(任何鼠标)时,我想知道它是哪一只鼠标,换句话说我想知道最后一只鼠标的设备句柄。
< / 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)列表,但没有代码引用设备句柄。
谢谢:)