From b0ff515b29613cc9011eda0840d9f02446c76fb5 Mon Sep 17 00:00:00 2001 From: Herwin Date: Wed, 28 Jul 2021 08:02:28 +0200 Subject: [PATCH] Added undocumented constants and finished example --- Examples/ListingRawInputDevices.pb | 156 ++++++++++++++++++++++++++++- Includes/RawInput.pbi | 22 ++-- 2 files changed, 169 insertions(+), 9 deletions(-) diff --git a/Examples/ListingRawInputDevices.pb b/Examples/ListingRawInputDevices.pb index c49753e..566168d 100644 --- a/Examples/ListingRawInputDevices.pb +++ b/Examples/ListingRawInputDevices.pb @@ -36,14 +36,166 @@ XIncludeFile "../Includes/RawInput.pbi" ;- Code -; Counting RawInput devices... +;-> Counting RawInput devices Define RawInputDeviceCount.i = 0 If RawInput::GetRawInputDeviceList(#Null, @RawInputDeviceCount, SizeOf(RawInput::RAWINPUTDEVICELIST)) <> -1 Debug "Found "+Str(RawInputDeviceCount)+" RawInput devices !" Else - Debug "Error while listing RawInput devices: "+Str(GetLastError_())+" !" + Debug "Error while counting RawInput devices: "+Str(GetLastError_())+" !" End 1 EndIf +;-> Listing RawInput devices + +; A memory buffer is used since we can't dynamically declare C-style arrays in PB. +Define *RawInputDeviceListBuffer = AllocateMemory(SizeOf(RawInput::RAWINPUTDEVICELIST) * RawInputDeviceCount) + +If Not *RawInputDeviceListBuffer + Debug "Failed to allocate memory for *RawInputDeviceListBuffer !" + End 2 +EndIf + +Define ReturnedValue.WinTypes::UINT = RawInput::GetRawInputDeviceList(*RawInputDeviceListBuffer, @RawInputDeviceCount, SizeOf(RawInput::RAWINPUTDEVICELIST)) +If ReturnedValue <> -1 + Debug "Successfully got the list of RawInput devices ! (Received "+Str(ReturnedValue)+" in the buffer)" +Else + Debug "Error while listing RawInput devices: "+Str(GetLastError_())+" !" + FreeMemory(*RawInputDeviceListBuffer) + End 3 +EndIf + +Define i.i +For i=0 To RawInputDeviceCount - 1 + ;-> > Getting an element from the buffer + ; From *RawInputDeviceListBuffer as a RAWINPUTDEVICELIST[] C-type array and type-casting it. + ; tagRAWINPUTDEVICELIST is used instead of RAWINPUTDEVICELIST for the auto-completion. (Same end result !) + Define *RawInputDevice.RawInput::tagRAWINPUTDEVICELIST = *RawInputDeviceListBuffer + (SizeOf(RawInput::RAWINPUTDEVICELIST) * i) + + Debug #CRLF$+"Device #"+Str(i) + + ; Printing the device's type + Select *RawInputDevice\dwType + Case RawInput::#RIM_TYPEHID + Debug "> Device type: HID" + Case RawInput::#RIM_TYPEKEYBOARD + Debug "> Device type: Keyboard" + Case RawInput::#RIM_TYPEMOUSE + Debug "> Device type: Mouse" + Default + ; Can happen due to off-by-one errors in loops ! + Debug "> Device type: Unknown (undocumented behaviour !)" + Debug " > "+Str(*RawInputDevice\dwType) + Debug " > 0x"+RSet(Hex(*RawInputDevice\dwType), 16, "0") + Continue + EndSelect + + ;-> > Querying and printing the device's info + ; tagRID_DEVICE_INFO is used instead of RID_DEVICE_INFO for the auto-completion. (Same end result !) + ; GetRawInputDeviceInfoA or GetRawInputDeviceInfoW is automatically selected behing the scene. + Debug "> Device info:" + Define HasEncounteredAnError.b = #False + + ; Getting the device's interface name (\\?\...) + Define RawInputDeviceInterfaceName.s{#MAX_PATH} + Define RawInputDeviceInterfaceNameSize = #MAX_PATH + + If RawInput::GetRawInputDeviceInfo(*RawInputDevice\hDevice, RawInput::#RIDI_DEVICENAME, + @RawInputDeviceInterfaceName, @RawInputDeviceInterfaceNameSize) < 0 + Debug " > Error: Failed to properly query the device's interface name !" + HasEncounteredAnError = #True + EndIf + + ; Getting the device's info + Define RawInputDeviceInfo.RawInput::tagRID_DEVICE_INFO + Define RawInputDeviceInfoSize = SizeOf(RawInput::tagRID_DEVICE_INFO) + + If RawInput::GetRawInputDeviceInfo(*RawInputDevice\hDevice, RawInput::#RIDI_DEVICEINFO, + @RawInputDeviceInfo, @RawInputDeviceInfoSize) < 0 + Debug " > Error: Failed to properly query the device's info !" + HasEncounteredAnError = #True + EndIf + + ; #RIDI_PREPARSEDDATA is not tested here. + + If HasEncounteredAnError + ; Data received is "unsafe" to process. + Debug " > Error: Unable to continue with this device !" + Continue + EndIf + + ; Printing the device's info + Debug " > Interface name: "+RawInputDeviceInterfaceName + + Select RawInputDeviceInfo\dwType + Case RawInput::#RIM_TYPEHID + Debug " > Device type: HID" + Debug " > Vendor ID: 0x"+RSet(Hex(RawInputDeviceInfo\hid\dwProductId), 4, "0") + Debug " > Product ID: 0x"+RSet(Hex(RawInputDeviceInfo\hid\dwVendorId), 4, "0") + Debug " > Version Nbr: 0x"+RSet(Hex(RawInputDeviceInfo\hid\dwVersionNumber), 4, "0")+ + " | 0d"+Str(RawInputDeviceInfo\hid\dwVersionNumber) + + ;usUsagePage and usUsage are not covered here ! + Case RawInput::#RIM_TYPEKEYBOARD + Debug " > Device type: Keyboard" + + Select RawInputDeviceInfo\keyboard\dwType + Case RawInput::#RI_KEYBOARDTYPE_101 + ; Same as #RI_KEYBOARDTYPE_102 + Debug " > Keyboard type: Enhanced 101- or 102-key keyboards (and compatibles)" + Case RawInput::#RI_KEYBOARDTYPE_JAPANESE + Debug " > Keyboard type: Japanese Keyboard" + Case RawInput::#RI_KEYBOARDTYPE_KOREAN + Debug " > Keyboard type: Korean Keyboard" + Case RawInput::#RI_KEYBOARDTYPE_UNKNOWN + Debug " > Keyboard type: Unknown type or HID keyboard" + Default + ; Can easily be encountered with the "\\?\Microsoft Keyboard RID\..." devices ! + Debug " > Keyboard type: Error (undocumented value/behaviour !)" + Debug " > 0d"+Str(RawInputDeviceInfo\keyboard\dwType) + Debug " > 0x"+RSet(Hex(RawInputDeviceInfo\keyboard\dwType), 8, "0") + EndSelect + + Debug " > Vendor sub-type: 0x"+RSet(Hex(RawInputDeviceInfo\keyboard\dwSubType), 8, "0")+ + " | 0d"+Str(RawInputDeviceInfo\keyboard\dwSubType) + + Debug " > Scan code Mode: "+Str(RawInputDeviceInfo\keyboard\dwKeyboardMode) + Debug " > Function key count: "+Str(RawInputDeviceInfo\keyboard\dwNumberOfFunctionKeys) + Debug " > LED indicator count: "+Str(RawInputDeviceInfo\keyboard\dwNumberOfIndicators) + Debug " > Total Key count: "+Str(RawInputDeviceInfo\keyboard\dwNumberOfKeysTotal) + Case RawInput::#RIM_TYPEMOUSE + Debug " > Device type: Mouse" + + ; May not properly reflect the mouse's abilities ! + Debug " > Device ID properties: 0b"+RSet(Bin(RawInputDeviceInfo\mouse\dwId, #PB_Long), 4*8, "0") + If RawInputDeviceInfo\mouse\dwId & RawInput::#MOUSE_HID_HARDWARE + Debug " > HID mouse" + EndIf + If RawInputDeviceInfo\mouse\dwId & RawInput::#WHEELMOUSE_HID_HARDWARE + Debug " > HID wheel mouse" + EndIf + If RawInputDeviceInfo\mouse\dwId & RawInput::#HORIZONTAL_WHEEL_PRESENT + Debug " > Mouse with horizontal wheel" + EndIf + ; Ignoring some of the "undocumented" bit fields from: https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntddmou.h + + Debug " > Button count: "+Str(RawInputDeviceInfo\mouse\dwNumberOfButtons) + + ; This information may not be applicable for every mouse device. + Debug " > Data points per second: "+Str(RawInputDeviceInfo\mouse\dwSampleRate) + + If RawInputDeviceInfo\mouse\fHasHorizontalWheel + Debug " > Has horizontal wheel: True" + Else + Debug " > Has horizontal wheel: False" + EndIf + Default + Debug " > Error: Unknown device type (undocumented behaviour !)" + Debug " > "+Str(RawInputDeviceInfo\dwType) + Debug " > 0x"+RSet(Hex(RawInputDeviceInfo\dwType), 16, "0") + Continue + EndSelect +Next + +FreeMemory(*RawInputDeviceListBuffer) diff --git a/Includes/RawInput.pbi b/Includes/RawInput.pbi index 3adb117..61b0afc 100644 --- a/Includes/RawInput.pbi +++ b/Includes/RawInput.pbi @@ -1,7 +1,7 @@ ;{- Code Header ; ==- Basic Info -================================ ; Name: RawInput.pbi -; Version: 1.0.0 +; Version: 1.0.1 ; Author: Herwin Bozet ; ; ==- Compatibility -============================= @@ -41,9 +41,9 @@ DeclareModule RawInput #Version_Major = 1 #Version_Minor = 0 - #Version_Patch = 0 + #Version_Patch = 1 #Version_Label$ = "" - #Version$ = "1.0.0";+"-"+#Version_Label$ + #Version$ = "1.0.1";+"-"+#Version_Label$ ;-> Library Path Declaration @@ -177,7 +177,7 @@ DeclareModule RawInput ; https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rid_device_info_keyboard Structure tagRID_DEVICE_INFO_KEYBOARD Align #PB_Structure_AlignC - dwTyp.WinTypes::DWORD + dwType.WinTypes::DWORD dwSubType.WinTypes::DWORD dwKeyboardMode.WinTypes::DWORD dwNumberOfFunctionKeys.WinTypes::DWORD @@ -298,9 +298,17 @@ DeclareModule RawInput ; see the documentation in kbd.h, ntdd8042.h and ntddkbd.h headers in Windows SDK, and the Keyboard Layout Samples. ; The bitfield of the mouse device identification properties (tagRID_DEVICE_INFO_MOUSE\dwId) - #MOUSE_HID_HARDWARE = $0080 ; HID mouse - #WHEELMOUSE_HID_HARDWARE = $0100 ; HID wheel mouse - #HORIZONTAL_WHEEL_PRESENT = $8000; Mouse with horizontal wheel + ; Some "undocummented" constants were gotten from: https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntddmou.h + #MOUSE_INPORT_HARDWARE = $0001 + #MOUSE_I8042_HARDWARE = $0002 + #MOUSE_SERIAL_HARDWARE = $0004 + #BALLPOINT_I8042_HARDWARE = $0008 + #BALLPOINT_SERIAL_HARDWARE = $0010 + #WHEELMOUSE_I8042_HARDWARE = $0020 + #WHEELMOUSE_SERIAL_HARDWARE = $0040 + #MOUSE_HID_HARDWARE = $0080 ; HID mouse + #WHEELMOUSE_HID_HARDWARE = $0100 ; HID wheel mouse + #HORIZONTAL_WHEEL_PRESENT = $8000 ; Mouse with horizontal wheel ;-> Remaining Type Macros