(06-01-2024, 01:18 AM)DSMan195276 Wrote: I don't have tons of time at the moment, but to address a couple of the things you mentioned:Just trying to get these definitions right has been making my head spin...
You're correct about the `_OFFSET` type. The member you identified (`hDevice`) is a `HANDLE` type which is the same size as a pointer.
Yes `ASCIIZ * 50` would be a 50 byte string, you'll need to check if the 50 includes the NUL byte at the end or not (if it does, then you can use `STRING * 50` for it, if the NUL byte is extra then it's a `STRING * 51`).
The ` bRawData[1]` thing is hard to explain, but basically it's a C concept where the size of the TYPE/struct is not really defined, instead there's an array of unknown length at the end of it. If you read the specs, it says that the size of the `bRawData` array is `dwSizeHid * dwCount`. I assume you then split the `bRawData` bytes up into `dwSizeHid`-sized chunks and each is a HID report or something.
Also, something to keep in mind is the C padding rules. Each type has a required alignment and the C compiler will insert empty space between the members of the struct to make sure each member hits its required alignment. QB64 does not do this, so you have to manually insert extra members for the padding. The majority of those structures are designed such that they don't need any padding, but maybe not all of them.
If you get a second, does this look remotely like I'm on the right track?
(Above each TYPE defintion, I included the C definition as it appears on Microsoft's site.)
Code: (Select All)
' QB64PE C Libraries
' https://qb64phoenix.com/qb64wiki/index.php/C_Libraries
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RID_DEVICE_INFO_MOUSE structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rid_device_info_mouse
'typedef struct tagRID_DEVICE_INFO_MOUSE {
' DWORD dwId;
' DWORD dwNumberOfButtons;
' DWORD dwSampleRate;
' BOOL fHasHorizontalWheel;
'} RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE;
TYPE RID_DEVICE_INFO_MOUSE
dwId AS _UNSIGNED LONG
dwNumberOfButtons AS _UNSIGNED LONG
dwSampleRate AS _UNSIGNED LONG
fHasHorizontalWheel AS INTEGER
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RID_DEVICE_INFO_KEYBOARD structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rid_device_info_keyboard
'typedef struct tagRID_DEVICE_INFO_KEYBOARD {
' DWORD dwType;
' DWORD dwSubType;
' DWORD dwKeyboardMode;
' DWORD dwNumberOfFunctionKeys;
' DWORD dwNumberOfIndicators;
' DWORD dwNumberOfKeysTotal;
'} RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD;
TYPE RID_DEVICE_INFO_KEYBOARD
dwType AS _UNSIGNED LONG ' DWORD
dwSubType AS _UNSIGNED LONG ' DWORD
dwKeyboardMode AS _UNSIGNED LONG ' DWORD
dwNumberOfFunctionKeys AS _UNSIGNED LONG ' DWORD
dwNumberOfIndicators AS _UNSIGNED LONG ' DWORD
dwNumberOfKeysTotal AS _UNSIGNED LONG ' DWORD
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RID_DEVICE_INFO_HID structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rid_device_info_hid
'typedef struct tagRID_DEVICE_INFO_HID {
' DWORD dwVendorId;
' DWORD dwProductId;
' DWORD dwVersionNumber;
' USHORT usUsagePage;
' USHORT usUsage;
'} RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID;
TYPE RID_DEVICE_INFO_HID
dwVendorId AS _UNSIGNED LONG ' DWORD
dwProductId AS _UNSIGNED LONG ' DWORD
dwVersionNumber AS _UNSIGNED LONG ' DWORD
usUsagePage AS _UNSIGNED INTEGER ' USHORT
usUsage AS _UNSIGNED INTEGER ' USHORT
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RID_DEVICE_INFO structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rid_device_info
'typedef struct tagRID_DEVICE_INFO {
' DWORD cbSize;
' DWORD dwType;
' union {
' RID_DEVICE_INFO_MOUSE mouse;
' RID_DEVICE_INFO_KEYBOARD keyboard;
' RID_DEVICE_INFO_HID hid;
' } DUMMYUNIONNAME1;
'} RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO;
TYPE DUMMYUNIONNAME1
My_RID_DEVICE_INFO_MOUSE AS _OFFSET ' pointer to VAR A1
My_RID_DEVICE_INFO_KEYBOARD AS _OFFSET ' pointer to VAR A2
My_RID_DEVICE_INFO_HID AS _OFFSET ' pointer to VAR A3
END TYPE
TYPE RID_DEVICE_INFO
cbSize AS _UNSIGNED LONG ' DWORD
dwType AS _UNSIGNED LONG ' DWORD
My_DUMMYUNIONNAME1 AS _OFFSET ' pointer to DUMMYUNIONNAME1
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWKEYBOARD structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawkeyboard
'typedef struct tagRAWKEYBOARD {
' USHORT MakeCode;
' USHORT Flags;
' USHORT Reserved;
' USHORT VKey;
' UINT Message;
' ULONG ExtraInformation;
'} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
TYPE RAWKEYBOARD
MakeCode AS _UNSIGNED INTEGER ' USHORT
Flags AS _UNSIGNED INTEGER ' USHORT
Reserved AS _UNSIGNED INTEGER ' USHORT
VKey AS _UNSIGNED INTEGER ' USHORT
Message AS _UNSIGNED LONG ' UINT
ExtraInformation AS _UNSIGNED _OFFSET ' ULONG
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWMOUSE structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse
'typedef struct tagRAWMOUSE {
' USHORT usFlags;
' union {
' ULONG ulButtons;
' struct {
' USHORT usButtonFlags;
' USHORT usButtonData;
' } DUMMYSTRUCTNAME;
' } DUMMYUNIONNAME2;
' ULONG ulRawButtons;
' LONG lLastX;
' LONG lLastY;
' ULONG ulExtraInformation;
'} RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
TYPE DUMMYSTRUCTNAME
usButtonFlags AS _UNSIGNED INTEGER ' USHORT
usButtonData AS _UNSIGNED INTEGER ' USHORT
END TYPE
TYPE DUMMYUNIONNAME2
ulButtons AS _UNSIGNED _OFFSET ' ULONG
My_DUMMYSTRUCTNAME AS _OFFSET ' pointer to DUMMYSTRUCTNAME
END TYPE
TYPE RAWMOUSE
usFlags AS _UNSIGNED INTEGER ' USHORT
My_DUMMYUNIONNAME2 AS _OFFSET ' pointer to DUMMYUNIONNAME2
ulRawButtons AS _UNSIGNED _OFFSET ' ULONG
lLastX AS LONG
lLastY AS LONG
ulExtraInformation AS _UNSIGNED _OFFSET ' ULONG
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWHID structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawhid
'typedef struct tagRAWHID {
' DWORD dwSizeHid;
' DWORD dwCount;
' BYTE bRawData[1];
'} RAWHID, *PRAWHID, *LPRAWHID;
TYPE RAWHID
dwSizeHid AS _UNSIGNED LONG ' DWORD
dwCount AS _UNSIGNED LONG ' DWORD
bRawData AS _UNSIGNED _BYTE ' bRawData[1] AS BYTE
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWINPUTHEADER structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputheader
'typedef struct tagRAWINPUTHEADER {
' DWORD dwType;
' DWORD dwSize;
' HANDLE hDevice;
' WPARAM wParam;
'} RAWINPUTHEADER, *PRAWINPUTHEADER, *LPRAWINPUTHEADER;
TYPE RAWINPUTHEADER
dwType AS _UNSIGNED LONG ' DWORD
dwSize AS _UNSIGNED LONG ' DWORD
hDevice AS _UNSIGNED LONG ' DWORD <- should this be _OFFSET ?
wParam AS LONG
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWINPUT structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinput
'typedef struct tagRAWINPUT {
' RAWINPUTHEADER header;
' union {
' RAWMOUSE mouse;
' RAWKEYBOARD keyboard;
' RAWHID hid;
' } data;
'} RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
TYPE RAWINPUTUNION
mouse AS _OFFSET ' pointer to RAWMOUSE variable
keyboard AS _OFFSET ' pointer to RAWKEYBOARD variable
hid AS _OFFSET ' pointer to RAWHID
END UNION
TYPE RAWINPUT
header AS RAWINPUTHEADER
data AS _OFFSET
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWINPUTDEVICELIST structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevicelist
'typedef struct tagRAWINPUTDEVICELIST {
' HANDLE hDevice;
' DWORD dwType;
'} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
TYPE RAWINPUTDEVICELIST
hDevice AS _UNSIGNED LONG ' DWORD <- should this be _OFFSET ?
dwType AS _UNSIGNED LONG ' DWORD
END TYPE
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
'RAWINPUTDEVICE structure (winuser.h)
'https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevice
'typedef struct tagRAWINPUTDEVICE {
' USHORT usUsagePage;
' USHORT usUsage;
' DWORD dwFlags;
' HWND hwndTarget;
'} RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
TYPE RAWINPUTDEVICE
usUsagePage AS _UNSIGNED INTEGER ' WORD
usUsage AS _UNSIGNED INTEGER ' WORD
dwFlags AS _UNSIGNED LONG ' DWORD
hwndTarget AS _OFFSET ' DWORD
END TYPE
' ================================================================================================================================================================
' BEGIN CONSTANTS
' ================================================================================================================================================================
CONST COLOR_WINDOW = 5
CONST CS_HREDRAW = &H0002
CONST CS_VREDRAW = &H0001
CONST CW_USEDEFAULT = &H80000000
CONST DT_CENTER = &H00000001
CONST Edit = 101
CONST EM_GETSEL = &H00B0
CONST EM_SETSEL = &H00B1
CONST EN_CHANGE = &H0300
CONST EN_KILLFOCUS = &H0200
CONST EN_SETFOCUS = &H0100
CONST GCL_HICON = -14
CONST GCL_HICONSM = -34
CONST Hid_Bottom = 66
CONST Hid_Left = 33
CONST Hid_Right = 34
CONST HWND_DESKTOP = 0
CONST ICON_BIG = 1
CONST ICON_SMALL = 0
CONST IDC_ARROW = 32512
CONST IDI_APPLICATION = 32512
CONST KEYEVENTF_KEYUP = &H0002
CONST KL_NAMELENGTH = 9
CONST LabelInfo = 201
CONST MOUSE_ATTRIBUTES_CHANGED = &H04
CONST MOUSE_MOVE_ABSOLUTE = &H01
CONST MOUSE_MOVE_NOCOALESCE = &H08
CONST MOUSE_MOVE_RELATIVE = &H00
CONST MOUSE_VIRTUAL_DESKTOP = &H02
CONST NULL = 0
CONST RI_KEY_BREAK = 1
CONST RI_KEY_E0 = 2
CONST RI_KEY_E1 = 4
CONST RI_KEY_MAKE = 0
CONST RI_KEY_TERMSRV_SET_LED = 8
CONST RI_KEY_TERMSRV_SHADOW = &H10
CONST RID_INPUT = &H10000003
CONST RIDEV_EXINPUTSINK = &H00001000
CONST RIDI_DEVICEINFO = &H2000000B
CONST RIM_TYPEHID = 2
CONST RIM_TYPEKEYBOARD = 1
CONST RIM_TYPEMOUSE = 0
CONST SIZE_MINIMIZED = 1
CONST SW_SHOW = 5
CONST VK_CONTROL = &H11
CONST VK_DELETE = &H2E
CONST VK_DIVIDE = &H6F
CONST VK_DOWN = &H28
CONST VK_END = &H23
CONST VK_HOME = &H24
CONST VK_INSERT = &H2D
CONST VK_LEFT = &H25
CONST VK_NEXT = &H22
CONST VK_NUMLOCK = &H90
CONST VK_PRIOR = &H21
CONST VK_RIGHT = &H27
CONST VK_SCROLL = &H91
CONST VK_UP = &H26
CONST WM_APP = &H08000
CONST WM_APPCOMMAND = &H0319
CONST WM_CHAR = &H0102
CONST WM_CHAR = &H0102
CONST WM_CHAR = &H0102
CONST WM_COMMAND = &H0111
CONST WM_DEADCHAR = &H0103
CONST WM_DEADCHAR = &H0103
CONST WM_DESTROY = &H0002
CONST WM_INITDIALOG = &H0110
CONST WM_INPUT = &H00FF
CONST WM_KEYDOWN = &H0100
CONST WM_KEYUP = &H0101
CONST WM_KEYUP = &H0101
CONST WM_MOUSEMOVE = &H0200
CONST WM_NCACTIVATE = &H0086
CONST WM_NEXTDLGCTL = &H28
CONST WM_PAINT = &H000F
CONST WM_SETICON = &H0080
CONST WM_SIZE = &H0005
CONST WM_SYSCHAR = &H0106
CONST WM_SYSCHAR = &H0106
CONST WM_SYSDEADCHAR = &H0107
CONST WM_SYSDEADCHAR = &H0107
CONST WM_SYSKEYDOWN = &H0104
CONST WM_SYSKEYDOWN = &H0104
CONST WM_SYSKEYUP = &H0105
CONST WM_SYSKEYUP = &H0105
CONST WM_UNICHAR = &H0109
CONST WS_CAPTION = &H00C00000
CONST WS_CHILD = &H40000000
CONST WS_MAXIMIZEBOX = &H00010000
CONST WS_MINIMIZEBOX = &H00020000
CONST WS_OVERLAPPED = &H00000000
CONST WS_OVERLAPPEDWINDOW = WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
CONST WS_SYSMENU = &H00080000
CONST WS_THICKFRAME = &H00040000
CONST WS_VISIBLE = &H10000000
' ================================================================================================================================================================
' END CONSTANTS
' ================================================================================================================================================================
' Thank to José Roca
DECLARE FUNCTION RegisterRawInputDevices LIB "USER32.DLL" ALIAS "RegisterRawInputDevices"( _
BYREF pRawInputDevices AS RAWINPUTDEVICE, _
BYVAL uiNumDevices AS _UNSIGNED LONG, _ ' DWORD
BYVAL cbSize AS _UNSIGNED LONG _ ' DWORD
) AS LONG
DECLARE FUNCTION GetRawInputDeviceList LIB "USER32.DLL" ALIAS "GetRawInputDeviceList"( _
BYREF pRawInputDeviceList AS RAWINPUTDEVICELIST, _
BYREF puiNumDevices AS _UNSIGNED LONG, _ ' DWORD
BYVAL cbSize AS _UNSIGNED LONG _ ' DWORD
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION GetRawInputDeviceInfo LIB "USER32.DLL" ALIAS "GetRawInputDeviceInfoA"( _
BYVAL hDevice AS _UNSIGNED LONG, _ ' DWORD <- should this be _OFFSET?
BYVAL uiCommand AS _UNSIGNED LONG, _ ' DWORD
BYREF pData AS _OFFSET, _ ' ANY
BYREF pcbSize AS _UNSIGNED LONG _ ' DWORD
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION SendDlgItemMessage LIB "USER32.DLL" ALIAS "SendDlgItemMessageA"( _
BYVAL hWnd AS _OFFSET, _ ' DWORD
BYVAL nIDDlgItem AS LONG, _
BYVAL Msg AS _UNSIGNED LONG, _ ' DWORD
BYVAL wParam AS _UNSIGNED LONG, _ ' DWORD
BYVAL lParam AS LONG _
) AS LONG
DECLARE FUNCTION GetRawInputData LIB "USER32.DLL" ALIAS "GetRawInputData"( _
BYVAL hRawInput AS _UNSIGNED LONG, _ ' DWORD
BYVAL uiCommand AS _UNSIGNED LONG, _ ' DWORD
BYREF pData AS _OFFSET, _ ' ANY
BYREF pcbSize AS _UNSIGNED LONG, _ ' DWORD
BYVAL cbSizeHeader AS _UNSIGNED LONG _ ' DWORD
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION GetKeyNameText LIB "USER32.DLL" ALIAS "GetKeyNameTextA"( _
BYVAL lParam AS LONG, _
BYREF lpString AS STRING, _ ' ASCIIZ = NULL-terminated string
BYVAL cchSize AS _UNSIGNED LONG _ ' DWORD
) AS LONG
DECLARE FUNCTION MapVirtualKey LIB "USER32.DLL" ALIAS "MapVirtualKeyA"( _
BYVAL uCode AS _UNSIGNED LONG, _ ' DWORD
BYVAL uMapType AS _UNSIGNED LONG _ ' DWORD
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION GetFocus LIB "USER32.DLL" ALIAS "GetFocus"( _
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION GetDlgItem LIB "USER32.DLL" ALIAS "GetDlgItem"( _
BYVAL HWND AS _OFFSET, _ ' DWORD
BYVAL nIDDlgItem AS LONG _
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION SendMessage LIB "USER32.DLL" ALIAS "SendMessageA"( _
BYVAL hWnd AS _OFFSET, _ ' DWORD
BYVAL Msg AS _UNSIGNED LONG, _ ' DWORD
BYVAL wParam AS _UNSIGNED LONG, _ ' DWORD
BYVAL lParam AS LONG _
) AS LONG
DECLARE FUNCTION DestroyIcon LIB "USER32.DLL" ALIAS "DestroyIcon"( _
BYVAL hIcon AS _UNSIGNED LONG _ ' DWORD
) AS LONG
DECLARE FUNCTION PostMessage LIB "USER32.DLL" ALIAS "PostMessageA"( _
BYVAL hWnd AS _OFFSET, _ ' DWORD
BYVAL Msg AS _UNSIGNED LONG, _ ' DWORD
BYVAL wParam AS _UNSIGNED LONG, _ ' DWORD
BYVAL lParam AS LONG _
) AS LONG
DECLARE FUNCTION SetClassLong LIB "USER32.DLL" ALIAS "SetClassLongA"( _
BYVAL hWnd AS _OFFSET, _ ' DWORD
BYVAL nIndex AS LONG, _
BYVAL dwNewLong AS _UNSIGNED LONG _ ' DWORD
) AS DWORD
DECLARE FUNCTION ExtractIconEx LIB "SHELL32.DLL" ALIAS "ExtractIconExA"( _
BYREF lpszFile AS STRING, _ ' ASCIIZ = NULL-terminated string
BYVAL nIconIndex AS LONG, _
BYREF phiconLarge AS _UNSIGNED LONG, _ ' DWORD
BYREF phiconSmall AS _UNSIGNED LONG, _ ' DWORD
BYVAL nIcons AS _UNSIGNED LONG _ ' DWORD
) AS _UNSIGNED LONG ' DWORD
DECLARE FUNCTION SetDlgItemText LIB "USER32.DLL" ALIAS "SetDlgItemTextA"( _
BYVAL hDlg AS LONG, _
BYVAL nIDDlgItem AS LONG, _
lpString AS STRING _ ' ASCIIZ = NULL-terminated string
) AS LONG
DECLARE SUB Keybd_event LIB "USER32.DLL" ALIAS "keybd_event"( _
BYVAL bVk AS BYTE, _
BYVAL bScan AS BYTE, _
BYVAL dwFlags AS _UNSIGNED LONG, _ ' DWORD
BYVAL dwExtraInfo AS _UNSIGNED LONG _ ' DWORD
)
GLOBAL hDlg AS _UNSIGNED LONG ' DWORD
CALLBACK FUNCTION DlgProc
LOCAL RidDeviceInfo AS RID_DEVICE_INFO
LOCAL pRawInput AS RAWINPUT POINTER
LOCAL zKeyName AS STRING ' ASCIIZ * 50 = NULL-terminated string
STATIC CtrlClass AS STRING ' ASCIIZ * 50 = NULL-terminated string
LOCAL sRawInput AS STRING
LOCAL sBuffer AS STRING
LOCAL ScanCode AS _UNSIGNED LONG ' DWORD
STATIC hidDevice AS _UNSIGNED LONG ' DWORD
STATIC hFocusBak AS _UNSIGNED LONG ' DWORD
LOCAL RawInputDevCount AS LONG
LOCAL KeyboardTypeCount AS LONG
LOCAL RawInputDeviceIndex AS LONG
STATIC hidF9 AS LONG
LOCAL ByteCount AS LONG
STATIC SelStart AS LONG
STATIC SelEnd AS LONG
SELECT CASE CBMSG
CASE %WM_INITDIALOG
GetRawInputDeviceList(BYVAL %NULL, RawInputDevCount, SIZEOF(RAWINPUTDEVICELIST)) 'Get raw input device count
DIM RawInputDevList(0 TO RawInputDevCount - 1) AS RAWINPUTDEVICELIST 'Prepare raw input device array
GetRawInputDeviceList(RawInputDevList(0), RawInputDevCount, SIZEOF(RAWINPUTDEVICELIST)) 'Get raw input device
DIM RawInputDev(RawInputDevCount) AS RAWINPUTDEVICE 'Prepare raw input device array
FOR RawInputDeviceIndex = 0 TO RawInputDevCount - 1
GetRawInputDeviceInfo(RawInputDevList(RawInputDeviceIndex).hDevice, %RIDI_DEVICEINFO, RidDeviceInfo, SIZEOF(RID_DEVICE_INFO)) 'Get raw input device info
SELECT CASE RidDeviceInfo.dwtype 'Get raw input device type
CASE %RIM_TYPEKEYBOARD 'Keyboard type
RawInputDev(KeyboardTypeCount).usUsagePage = 1
RawInputDev(KeyboardTypeCount).usUsage = 6
RawInputDev(KeyboardTypeCount).dwFlags = %RIDEV_EXINPUTSINK 'Vista+, receive input in the background
RawInputDev(KeyboardTypeCount).hwndTarget = hDlg
INCR KeyboardTypeCount 'Count of raw keyboard input device
CASE %RIM_TYPEMOUSE 'Mouse raw input device
CASE %RIM_TYPEHID 'Other raw input device, game controllers, joysticks, etc.
END SELECT
NEXT
RegisterRawInputDevices(RawInputDev(0), KeyboardTypeCount, SIZEOF(RAWINPUTDEVICE)) 'Register raw input device(s)
PostMessage(hDlg, %WM_APP, 0, 0)
CASE %WM_INPUT 'Sent to the window that is getting raw input
GetRawInputData(CBLPARAM, %RID_INPUT, BYVAL %NULL, ByteCount, SIZEOF(RAWINPUTHEADER)) 'Get size of raw input buffer
sRawInput = NUL$(ByteCount) 'Set string for hid input
GetRawInputData(CBLPARAM, %RID_INPUT, BYVAL STRPTR(sRawInput), ByteCount, SIZEOF(RAWINPUTHEADER))'Get hid input
pRawInput = STRPTR(sRawInput) 'Set RawInput pointer
sBuffer = "RawInput.Header.hDevice = " & HEX$(@pRawInput.header.hDevice, 8) & chr$(13) & chr$(10) ' $CRLF 'Show handle
sBuffer = sBuffer & "RawInput.Header.dwType = " & CHOOSE$(@pRawInput.header.dwType + 1, _
"RIM_TYPEMOUSE", "RIM_TYPEKEYBOARD", "RIM_TYPEHID") & chr$(13) & chr$(10) ' $CRLF 'Show type
sBuffer = sBuffer & chr$(13) & chr$(10) ' $CRLF
sBuffer = sBuffer & "RawInput.data.Keyboard.vKey =" & STR$(@pRawInput.data.Keyboard.vKey) & _ '
", Character is " & $DQ & CHR$(@pRawInput.data.Keyboard.vKey) & $DQ & chr$(13) & chr$(10) & chr$(13) & chr$(10) ' $CRLF & $CRLF 'Show char
ScanCode = MapVirtualKey(@pRawInput.data.Keyboard.vKey, 0) 'Create a scan code from vKey to get GetKeyNameText
SELECT CASE @pRawInput.data.Keyboard.vKey
CASE %VK_LEFT, %VK_UP, %VK_RIGHT, %VK_DOWN, %VK_PRIOR, %VK_NEXT, _
%VK_END, %VK_HOME, %VK_INSERT, %VK_DELETE, %VK_DIVIDE, %VK_NUMLOCK
ScanCode = ScanCode OR &H100 'Set extended bit
END SELECT
SHIFT LEFT ScanCode, 16 'Shift left
GetKeyNameText(ScanCode, BYVAL VARPTR(zKeyName), SIZEOF(zKeyName)) 'Get key name like "Tab" or "Esc"
sBuffer = sBuffer & "KeyName " & $DQ & zKeyName & $DQ & chr$(13) & chr$(10) ' $CRLF
sBuffer = sBuffer & chr$(13) & chr$(10) ' $CRLF
sBuffer = sBuffer & "RawInput.data.Keyboard.Message =" & HEX$(@pRawInput.data.Keyboard.Message, 8) 'Show message
SELECT CASE @pRawInput.data.Keyboard.Message
CASE %WM_KEYDOWN : sBuffer = sBuffer & " WM_KEYDOWN" & chr$(13) & chr$(10) ' $CRLF
CASE %WM_KEYUP : sBuffer = sBuffer & " WM_KEYUP" & chr$(13) & chr$(10) ' $CRLF
CASE %WM_SYSKEYDOWN : sBuffer = sBuffer & " WM_SYSKEYDOWN" & chr$(13) & chr$(10) ' $CRLF
CASE %WM_SYSKEYDOWN : sBuffer = sBuffer & " WM_SYSKEYDOWN" & chr$(13) & chr$(10) ' $CRLF
END SELECT
sBuffer = sBuffer & chr$(13) & chr$(10) ' $CRLF
sBuffer = sBuffer & "RawInput.Keyboard.MakeCode = " & HEX$(@pRawInput.data.Keyboard.MakeCode, 8) & chr$(13) & chr$(10) ' $CRLF 'Show make code
sBuffer = sBuffer & "RawInput.data.Keyboard.ExtraInformation = " & _
HEX$(@pRawInput.data.Keyboard.ExtraInformation, 8) & chr$(13) & chr$(10) ' $CRLF 'Show extra info
IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_BREAK) THEN 'Show flags
sBuffer = sBuffer & "Flag RI_KEY_BREAK" & chr$(13) & chr$(10) ' $CRLF
ELSE
sBuffer = sBuffer & "Flag RI_KEY_MAKE" & chr$(13) & chr$(10) ' $CRLF
END IF
IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_E0) THEN
sBuffer = sBuffer & "Flag RI_KEY_E0" & chr$(13) & chr$(10) ' $CRLF
END IF
IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_E1) THEN
sBuffer = sBuffer & "Flag RI_KEY_E1" & chr$(13) & chr$(10) ' $CRLF
END IF
IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_TERMSRV_SET_LED) THEN
sBuffer = sBuffer & "Flag RI_KEY_TERMSRV_SET_LED" & chr$(13) & chr$(10) ' $CRLF
END IF
IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_TERMSRV_SHADOW) THEN
sBuffer = sBuffer & "Flag RI_KEY_TERMSRV_SHADOW" & chr$(13) & chr$(10) ' $CRLF
END IF
SetDlgItemText(hDlg, %LabelInfo, BYVAL STRPTR(sBuffer))
CASE %WM_CHAR
CASE %WM_MOUSEMOVE
CASE %WM_APPCOMMAND
CASE %WM_APP
SendDlgItemMessage(hDlg, %Edit, %EM_SETSEL, -2, -2) 'Move caret at the end
Keybd_event(%VK_CONTROL, 0, 0, 0) 'Simulate Control key
Keybd_event(%VK_CONTROL, 0, %KEYEVENTF_KEYUP, 0) 'Simulate Control key
CASE %WM_COMMAND
SELECT CASE CBCTL
CASE %Edit
IF HIWRD(CBWPARAM) = %EN_CHANGE THEN
END IF
IF (CBCTLMSG = %EN_KILLFOCUS) THEN
SendMessage(CBLPARAM, %EM_GETSEL, VARPTR(SelStart), VARPTR(SelEnd))
END IF
IF (CBCTLMSG = %EN_SETFOCUS) THEN
SendMessage(CBLPARAM, %EM_SETSEL, SelStart, SelEnd)
END IF
END SELECT
CASE %WM_NCACTIVATE
IF CBWPARAM = 0 THEN 'Application loose focus
hFocusBak = GetFocus()
ELSEIF hFocusBak THEN
SendMessage(hDlg, %WM_NEXTDLGCTL, hFocusBak, 1)
hFocusBak = 0
END IF
END SELECT
END FUNCTION
FUNCTION PBMAIN()
LOCAL hIconBig AS _UNSIGNED LONG
LOCAL hIconSmall AS _UNSIGNED LONG
' Dialog Boxes 03/12/2023
' https://learn.microsoft.com/en-us/windows/win32/api/_dlgbox/
DIALOG FONT "Segoe UI", 9
DIALOG NEW %HWND_DESKTOP, "GetRawInputDevice / GetRawInputData", , , 230, 150, _
%WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
ExtractIconEx("msctf.dll", 15, BYVAL VARPTR(hIconBig), BYVAL VARPTR(hIconSmall), 1)
SetClassLong(hDlg, %GCL_HICONSM, hIconSmall)
SetClassLong(hDlg, %GCL_HICON, hIconBig)
SendMessage(hDlg, %WM_SETICON, %ICON_SMALL, hIconSmall)
SendMessage(hDlg, %WM_SETICON, %ICON_BIG, hIconBig)
CONTROL ADD TEXTBOX, hDlg, %Edit, "Type also in another app...", 5, 5, 220, 12
CONTROL ADD LABEL, hDlg, %LabelInfo, "GetRawInputDevice / GetRawInputData", 5, 20, 220, 125
DIALOG SHOW MODAL hDlg CALL DlgProc
DestroyIcon(hIconSmall)
DestroyIcon(hIconBig)
END FUNCTION ' PBMAIN