Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
APIs from QB64PE and parameters defined As Any and unions of types ?
#1
Question 
In trying to figure out some Raw Input API stuff to read the keyboard, I found a PowerBASIC thread which has API declarations that I want to try porting to QB64PE.

This includes some strange stuff - "AS ANY" and "UNION":

Code: (Select All)
BYREF pData AS ANY

...

TYPE RID_DEVICE_INFO_KEYBOARD
dwType                 AS DWORD
dwSubType              AS DWORD
dwKeyboardMode         AS DWORD
dwNumberOfFunctionKeys AS DWORD
dwNumberOfIndicators   AS DWORD
dwNumberOfKeysTotal    AS DWORD
END TYPE

UNION RID_DEVICE_INFO_UNION
'mouse   AS RID_DEVICE_INFO_MOUSE
keyboard AS RID_DEVICE_INFO_KEYBOARD
'hid     AS RID_DEVICE_INFO_HID
END UNION

TYPE RID_DEVICE_INFO
cbSize AS DWORD
dwType AS DWORD
RID_DEVICE_INFO_UNION
END TYPE

I did some googling to understand UNION and AS ANY and how those might be translated into QB64PE:

Those are all VB and VB.NET threads and they get pretty deep into it... In the "as any" thread they analyze what's happening down to the assembly level! My brain hurts! 

I just want to know if anyone has any clue how to get the below code working with QB64/PE or could recommend the right syntax to declare a type with a union and what to do about "as any" ? Much appreciated... 


Here's all of it: 


Code: (Select All)
'Raw Keyboard (HID) Input (discussion) - PowerBASIC Peer Support Community
'https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-for-windows/55985-raw-keyboard-hid-input-discussion#post673309
'
'#6
'Pierre Bellisle
'23 Mar 2014, 11:04 AM
'Thank for sharing Jeremy.
'
'Here's an adaption...

TYPE RID_DEVICE_INFO_KEYBOARD
dwType                 AS DWORD
dwSubType              AS DWORD
dwKeyboardMode         AS DWORD
dwNumberOfFunctionKeys AS DWORD
dwNumberOfIndicators   AS DWORD
dwNumberOfKeysTotal    AS DWORD
END TYPE

UNION RID_DEVICE_INFO_UNION
'mouse   AS RID_DEVICE_INFO_MOUSE
keyboard AS RID_DEVICE_INFO_KEYBOARD
'hid     AS RID_DEVICE_INFO_HID
END UNION

TYPE RID_DEVICE_INFO
cbSize AS DWORD
dwType AS DWORD
RID_DEVICE_INFO_UNION
END TYPE

TYPE RAWKEYBOARD
MakeCode         AS WORD
Flags            AS WORD
Reserved         AS WORD
VKey             AS WORD
Message          AS DWORD
ExtraInformation AS DWORD
END TYPE

UNION RAWINPUTUNION
'mouse    AS RAWMOUSE
keyboard  AS RAWKEYBOARD
'hid      AS RAWHID
END UNION

TYPE RAWINPUTHEADER
dwType  AS DWORD
dwSize  AS DWORD
hDevice AS DWORD
wParam  AS LONG
END TYPE

TYPE RAWINPUT
header AS RAWINPUTHEADER
data   AS RAWINPUTUNION
END TYPE

TYPE RAWINPUTDEVICELIST
hDevice AS DWORD
dwType  AS DWORD
END TYPE

TYPE RAWINPUTDEVICE
usUsagePage AS WORD
usUsage     AS WORD
dwFlags     AS DWORD
hwndTarget  AS DWORD
END TYPE

%Edit                    = 101            : %WM_CHAR                 = &H0102???
%LabelInfo               = 201            : %WM_MOUSEMOVE            = &H0200???
                                          : %WM_APPCOMMAND           = &H0319???
%Hid_Left                = 33             : %WM_INPUT                = &H00FF???
%Hid_Right               = 34             : %KL_NAMELENGTH           = 9
%Hid_Bottom              = 66             : %WM_KEYUP                = &H0101???
                                          : %WM_CHAR                 = &H0102???
%RIDEV_EXINPUTSINK       = &H00001000     : %WM_DEADCHAR             = &H0103???
%WM_INITDIALOG           = &H0110???      : %WM_SYSKEYDOWN           = &H0104???
%NULL                    = 0              : %WM_SYSKEYUP             = &H0105???
                                          : %WM_SYSCHAR              = &H0106???
%RIDI_DEVICEINFO         = &H2000000B???  : %WM_SYSDEADCHAR          = &H0107???
%RIM_TYPEKEYBOARD        = 1&             : %WM_KEYDOWN              = &H0100???
%RIM_TYPEMOUSE           = 0&             : %WM_KEYUP                = &H0101???
%RIM_TYPEHID             = 2&             : %WM_CHAR                 = &H0102???
%RID_INPUT               = &H10000003???  : %WM_DEADCHAR             = &H0103???
%RI_KEY_MAKE             = 0??            : %WM_SYSKEYDOWN           = &H0104???
%RI_KEY_BREAK            = 1??            : %WM_SYSKEYUP             = &H0105???
%RI_KEY_E0               = 2??            : %WM_SYSCHAR              = &H0106???
%RI_KEY_E1               = 4??            : %WM_SYSDEADCHAR          = &H0107???
%RI_KEY_TERMSRV_SET_LED  = 8??            : %WM_UNICHAR              = &H0109???
%RI_KEY_TERMSRV_SHADOW   = &H10??         : %WM_NCACTIVATE           = &H0086???
                                          : %WM_COMMAND              = &H0111???
%VK_LEFT                 = &H25&          : %WM_SIZE                 = &H0005???
%VK_UP                   = &H26&          : %WM_DESTROY              = &H0002???
%VK_RIGHT                = &H27&          : %WM_NEXTDLGCTL           = &H28
%VK_DOWN                 = &H28&          : %WM_SETICON              = &H0080???
%VK_PRIOR                = &H21&          : %WM_APP                  = &H08000
%VK_NEXT                 = &H22&          : %WS_CAPTION              = &H00C00000&
%VK_END                  = &H23&          : %WS_MINIMIZEBOX          = &H00020000&
%VK_HOME                 = &H24&          : %WS_SYSMENU              = &H00080000&
%VK_INSERT               = &H2D&          : %HWND_DESKTOP            = 0???
%VK_DELETE               = &H2E&          : %GCL_HICONSM             = -34&
%VK_DIVIDE               = &H6F&          : %GCL_HICON               = -14&
%VK_NUMLOCK              = &H90&          : %ICON_SMALL              = 0&
%VK_SCROLL               = &H91&          : %ICON_BIG                = 1&
%VK_CONTROL              = &H11&          : %SIZE_MINIMIZED          = 1
%KEYEVENTF_KEYUP         = &H0002???
%EN_CHANGE               = &H0300???
%EN_KILLFOCUS            = &H0200???
%EN_SETFOCUS             = &H0100???
%EM_GETSEL               = &H00B0???
%EM_SETSEL               = &H00B1???

'Thank to José Roca
DECLARE FUNCTION RegisterRawInputDevices LIB "USER32.DLL" ALIAS "RegisterRawInputDevices"(BYREF pRawInputDevices AS RAWINPUTDEVICE, BYVAL uiNumDevices AS DWORD, BYVAL cbSize AS DWORD) AS LONG
DECLARE FUNCTION GetRawInputDeviceList LIB "USER32.DLL" ALIAS "GetRawInputDeviceList"(BYREF pRawInputDeviceList AS RAWINPUTDEVICELIST, BYREF puiNumDevices AS DWORD, BYVAL cbSize AS DWORD) AS DWORD
DECLARE FUNCTION GetRawInputDeviceInfo LIB "USER32.DLL" ALIAS "GetRawInputDeviceInfoA"(BYVAL hDevice AS DWORD, BYVAL uiCommand AS DWORD, BYREF pData AS ANY, BYREF pcbSize AS  DWORD) AS DWORD
DECLARE FUNCTION SendDlgItemMessage LIB "USER32.DLL" ALIAS "SendDlgItemMessageA"(BYVAL hWnd AS DWORD, BYVAL nIDDlgItem AS LONG, BYVAL Msg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION GetRawInputData LIB "USER32.DLL" ALIAS "GetRawInputData"(BYVAL hRawInput AS DWORD, BYVAL uiCommand AS DWORD, BYREF pData AS ANY, BYREF pcbSize AS DWORD, BYVAL cbSizeHeader AS DWORD) AS DWORD
DECLARE FUNCTION GetKeyNameText LIB "USER32.DLL" ALIAS "GetKeyNameTextA"(BYVAL lParam AS LONG, BYREF lpString AS ASCIIZ, BYVAL cchSize AS DWORD) AS LONG
DECLARE FUNCTION MapVirtualKey LIB "USER32.DLL" ALIAS "MapVirtualKeyA"(BYVAL uCode AS DWORD, BYVAL uMapType AS DWORD) AS DWORD
DECLARE FUNCTION GetFocus LIB "USER32.DLL" ALIAS "GetFocus"() AS DWORD
DECLARE FUNCTION GetDlgItem LIB "USER32.DLL" ALIAS "GetDlgItem"(BYVAL HWND AS DWORD, BYVAL nIDDlgItem AS LONG) AS DWORD
DECLARE FUNCTION SendMessage LIB "USER32.DLL" ALIAS "SendMessageA"(BYVAL hWnd AS DWORD, BYVAL Msg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION DestroyIcon LIB "USER32.DLL" ALIAS "DestroyIcon"(BYVAL hIcon AS DWORD) AS LONG
DECLARE FUNCTION PostMessage LIB "USER32.DLL" ALIAS "PostMessageA"(BYVAL hWnd AS DWORD, BYVAL Msg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION SetClassLong LIB "USER32.DLL" ALIAS "SetClassLongA"(BYVAL hWnd AS DWORD, BYVAL nIndex AS LONG, BYVAL dwNewLong AS DWORD) AS DWORD
DECLARE FUNCTION ExtractIconEx LIB "SHELL32.DLL" ALIAS "ExtractIconExA"(BYREF lpszFile AS ASCIIZ, BYVAL nIconIndex AS LONG, BYREF phiconLarge AS DWORD, BYREF phiconSmall AS DWORD, BYVAL nIcons AS DWORD) AS DWORD
DECLARE FUNCTION SetDlgItemText LIB "USER32.DLL" ALIAS "SetDlgItemTextA"(BYVAL hDlg AS LONG, BYVAL nIDDlgItem AS LONG, lpString AS ASCIIZ) AS LONG
DECLARE SUB      Keybd_event LIB "USER32.DLL" ALIAS "keybd_event"(BYVAL bVk AS BYTE, BYVAL bScan AS BYTE, BYVAL dwFlags AS DWORD, BYVAL dwExtraInfo AS DWORD)

GLOBAL hDlg AS DWORD
'______________________________________________________________________________

CALLBACK FUNCTION DlgProc
LOCAL  RidDeviceInfo       AS RID_DEVICE_INFO
LOCAL  pRawInput           AS RAWINPUT POINTER
LOCAL  zKeyName            AS ASCIIZ * 50
STATIC CtrlClass           AS ASCIIZ * 50
LOCAL  sRawInput           AS STRING
LOCAL  sBuffer             AS STRING
LOCAL  ScanCode            AS DWORD
STATIC hidDevice           AS DWORD
STATIC hFocusBak           AS 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) & $CRLF 'Show handle
     sBuffer = sBuffer & "RawInput.Header.dwType = " & CHOOSE$(@pRawInput.header.dwType + 1, _
     "RIM_TYPEMOUSE", "RIM_TYPEKEYBOARD", "RIM_TYPEHID") & $CRLF 'Show type

     sBuffer = sBuffer & $CRLF
     sBuffer = sBuffer & "RawInput.data.Keyboard.vKey =" & STR$(@pRawInput.data.Keyboard.vKey) & _ '
                         ", Character is " & $DQ & CHR$(@pRawInput.data.Keyboard.vKey) & $DQ & $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 & $CRLF

     sBuffer = sBuffer & $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"    & $CRLF
       CASE %WM_KEYUP      : sBuffer = sBuffer & " WM_KEYUP"      & $CRLF
       CASE %WM_SYSKEYDOWN : sBuffer = sBuffer & " WM_SYSKEYDOWN" & $CRLF
       CASE %WM_SYSKEYDOWN : sBuffer = sBuffer & " WM_SYSKEYDOWN" & $CRLF
     END SELECT

     sBuffer = sBuffer & $CRLF
     sBuffer = sBuffer & "RawInput.Keyboard.MakeCode = " & HEX$(@pRawInput.data.Keyboard.MakeCode, 8) & $CRLF 'Show make code
     sBuffer = sBuffer & "RawInput.data.Keyboard.ExtraInformation = " & _
               HEX$(@pRawInput.data.Keyboard.ExtraInformation, 8) & $CRLF 'Show extra info
     IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_BREAK) THEN 'Show flags
       sBuffer = sBuffer & "Flag RI_KEY_BREAK" & $CRLF
     ELSE
       sBuffer = sBuffer & "Flag RI_KEY_MAKE" & $CRLF
     END IF
     IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_E0) THEN
       sBuffer = sBuffer & "Flag RI_KEY_E0" & $CRLF
     END IF
     IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_E1) THEN
       sBuffer = sBuffer & "Flag RI_KEY_E1" & $CRLF
     END IF
     IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_TERMSRV_SET_LED) THEN
       sBuffer = sBuffer & "Flag RI_KEY_TERMSRV_SET_LED" & $CRLF
     END IF
     IF (@pRawInput.data.Keyboard.Flags AND %RI_KEY_TERMSRV_SHADOW) THEN
       sBuffer = sBuffer & "Flag RI_KEY_TERMSRV_SHADOW" & $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 DWORD
LOCAL hIconSmall AS DWORD

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
Reply


Messages In This Thread
APIs from QB64PE and parameters defined As Any and unions of types ? - by madscijr - 05-30-2024, 07:37 PM



Users browsing this thread: 1 Guest(s)