I’m trying to make a program in C# that reads button inputs from all your connected mice, keyboards and hid devices. So far it’s working without issues on my wired usb mouse, wired and wireless bluetooth gamepad and built in laptop keyboard, however issues arise when I use my built in laptop mousepad.
I receive this the inputs through WM_Input and then determine the device that is being used with this method:
private static void ReceiveRawInput(IntPtr inputMessage)
{
int actualSize = 0;
int dwSize = NativeMethods.GetRawInputData(inputMessage, DataCommand.RID_INPUT, null, ref actualSize, Marshal.SizeOf(typeof(RawInputHeader)));
if (actualSize < 0)
return;
var buffer = new byte[actualSize];
dwSize = NativeMethods.GetRawInputData(inputMessage, DataCommand.RID_INPUT, buffer, ref actualSize, Marshal.SizeOf(typeof(RawInputHeader)));
var header = Unsafe.As<byte, RawInputHeader> (ref buffer[0]);
if (!processedDeviceInputs.TryGetValue(header.hDevice, out KeyValuePair<DeviceInfo, List<UsageConfig>> deviceInputs))
return;
ProcessRawInput(buffer, deviceInputs, actualSize);
}
processedDeviceInputs dictionary stores pointers to the hDevice as keys and some device info about registered devices as value. Again, it works well for every other device i own, but for some reason when using my built in mousepad, the hDevice pointer of the header i get from inputMessage is equal to zero, but when registering devices the hDevice is the actual correct hDevice pointer value. As a result of that, my dictionary doesnt contain the definition for IntPtr.Zero key, and the program doesn’t end up processing the input.
When I enable Steam input for my controller, a different issue arises, because Steam Input sets all my actual raw input values from my gamepad to 0, but doesn’t seem to send out a message that is received by WM_Input, meaning that I now get no input at all when using Steam Input.
I am completely lost on why WM_Input message doesn’t contain a proper raw input header for my mousepad, but does for everything else? Is there any way I could fix that? Instead of storing device info with pointers as keys, i tried using device paths as keys that I would retrieve using this:
bool GetName(IntPtr hDevice, out string name)
{
name = string.Empty;
uint pcbSize = 0;
NativeMethods.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfo.RIDI_DEVICENAME, IntPtr.Zero, ref pcbSize);
if (pcbSize <= 0)
return false;
var pData = Marshal.AllocHGlobal((int)pcbSize);
NativeMethods.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfo.RIDI_DEVICENAME, pData, ref pcbSize);
name = Marshal.PtrToStringAnsi(pData);
Marshal.FreeHGlobal(pData);
return true;
}
but this also doesn’t work, as mousepad return pcbSize of 0.
I’m out of ideas on this one. Does anyone know what might be causing this?