Author Topic: issue with sending type _OFFSET to an API function  (Read 3461 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
issue with sending type _OFFSET to an API function
« on: April 06, 2021, 10:17:31 am »
(This came out of https://www.qb64.org/forum/index.php?topic=3766.0
which was about events and malloc. Now I am having a different issue so I am starting this new thread.)

I'm trying to convert this C program to QB64
https://jstookey.com/arcade/rawmouse/HelloRawInput.c

and am stuck on this error:
Code: [Select]
Cannot convert _OFFSET type to other types on line 118.
Caused by (or after): IF ( GETRAWINPUTDEVICELIST ( MYLIST , MYADDR , MEM . SIZE ) <> 0 ) THEN

The values being sent in seem to match the parameter types.
_OFFSET is a pointer, right?
What am I missing?

Code: QB64: [Select]
  1. ' ****************************************************************************************************************************************************************
  2. ' testmouse.c: A demonstration of how to use Rawinput to access multiple mice in Windows XP.
  3. ' https://jstookey.com/arcade/rawmouse/HelloRawInput.c
  4. ' ****************************************************************************************************************************************************************
  5.  
  6. ' #define _WIN32_WINNT 0x0501   // Identify this as a Windows XP application.
  7. '                               // This is necessary so we can access rawinput
  8. ' #include <stdio.h>
  9. ' #include <conio.h>            //  Provides getch()
  10. ' #include <windows.h>          //  Provides rawinput
  11.  
  12. ' =============================================================================
  13. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  14.  
  15. ' -----------------------------------------------------------------------------
  16. ' BOOLEAN CONSTANTS
  17. Const FALSE = 0
  18. Const TRUE = Not FALSE
  19.  
  20. ' -----------------------------------------------------------------------------
  21. ' USER DEFINED TYPES
  22.  
  23. ' What is PRAWINPUTDEVICELIST?
  24. '     PRAWINPUTDEVICELIST:
  25. '     typedef struct tagRAWINPUTDEVICELIST {
  26. '       HANDLE hDevice;
  27. '       DWORD  dwType;
  28. '     } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
  29.  
  30. Type RAWINPUTDEVICELIST
  31.     hDevice As _Offset ' a handle will always be _OFFSET
  32.     dwType As Long ' DWORD corresponds to LONG
  33.  
  34. ' -----------------------------------------------------------------------------
  35. ' API FUNCTIONS
  36.  
  37. ' What is GetRawInputDeviceList?
  38. '     UINT GetRawInputDeviceList(
  39. '       PRAWINPUTDEVICELIST pRawInputDeviceList,
  40. '       PUINT               puiNumDevices,        <---- what is a aPUINT?
  41. '       UINT                cbSize
  42. '     );
  43.  
  44. ' what is a aPUINT? According to
  45. '     WIN32 API Data Types
  46. '     https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  47. ' PUINT Pointer to a UINT.
  48. ' Q: What QB64 type is equivalent to a pointer?
  49. ' A: is it _OFFSET ?
  50.  
  51.     ' COMPILER ERROR HERE: Expected &H... or &O...
  52.     ' THEN WHEN I TRY CHANGING & TO &H OR &O, COMPILER SAYS MISSING )
  53.     Function GetRawInputDeviceList& (pRawInputDeviceList As RAWINPUTDEVICELIST, puiNumDevices As _Offset, cbSize As _Unsigned Long)
  54.  
  55. ' =============================================================================
  56. ' GLOBAL VARIABLES
  57. Dim ProgramPath$
  58. Dim ProgramName$
  59.  
  60. ' =============================================================================
  61. ' INITIALIZE
  62. ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  63. ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  64.  
  65. ' =============================================================================
  66. ' START
  67. main ProgramName$
  68.  
  69. ' =============================================================================
  70. ' FINISH
  71. System ' return control to the operating system
  72. Print ProgramName$ + " finished."
  73.  
  74. ' /////////////////////////////////////////////////////////////////////////////
  75.  
  76. Sub main (ProgName$)
  77.     Print "MinimalRawInputTest% RETURNS: " + cstr$(MinimalRawInputTest%)
  78. End Sub ' main
  79.  
  80. Function MinimalRawInputTest%
  81.     Dim iResult%
  82.     'UINT nInputDevices;
  83.     Dim nInputDevices As _Unsigned Long
  84.     Dim MEM As _MEM
  85.     Dim MyList As RAWINPUTDEVICELIST
  86.     Dim MyAddr As _Offset
  87.  
  88.     ' 1st call to GetRawInputDeviceList: Pass NULL to get the size of the list.
  89.     'if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) return 0;
  90.  
  91.     ' **********
  92.     ' UNKNOWNS:
  93.     ' Q1: how do you pass NULL in QB64?
  94.     ' A1: ?
  95.  
  96.     ' Q2: what is &nInputDevices vs nInputDevices and what is the QB64 equivalent?
  97.     ' A2: is it the pointer to the variable? in QB64, The _OFFSET function returns the memory offset of/within a given variable.
  98.  
  99.     ' Q3: what is the QB64 equivalent of sizeof?
  100.     ' A3: maybe _MEM and _MEM.SIZE ?
  101.  
  102.     ' _MEM
  103.     ' http://www.qb64.org/wiki/MEM
  104.     ' The _MEM variable type can be used when working with memory blocks. It has no variable type suffix.
  105.     ' The _MEM type contains the following read-only elements where name is the _MEM variable name:
  106.     '    name.OFFSET is the current start position in the memory block AS _OFFSET. Add bytes to change position.
  107.     '    name.SIZE is the remaining size of the block at current position in bytes AS _OFFSET
  108.     '    name.TYPE is the type (represented as bits combined to form a value) AS _OFFSET:
  109.  
  110.     MyAddr = _Offset(nInputDevices)
  111.     MEM = _Mem(RAWINPUTDEVICELIST)
  112.  
  113.     'IF (GetRawInputDeviceList(NULL, _OFFSET(nInputDevices), sizeof(RAWINPUTDEVICELIST)) <> 0) THEN
  114.     IF (GetRawInputDeviceList(MyList, MyAddr, MEM.SIZE) <> 0) THEN
  115.         iResult% = 0
  116.     ELSE
  117.         PRINT "Number of raw input devices: " + cstr$(nInputDevices)
  118.         PRINT "Press any key..."
  119.         SLEEP ' SLEEP without an argument waits until a keypress.)
  120.         iResult% = 1
  121.     END IF
  122.  
  123.     ' RETURN RESULT (ONE EXIT POINT!)
  124.     MinimalRawInputTest% = iResult%
  125. END FUNCTION ' MinimalRawInputTest%
  126.  
  127. ' /////////////////////////////////////////////////////////////////////////////
  128. ' Equivalent to vbscript / VBA / VB6 cstr
  129.  
  130. FUNCTION cstr$ (myValue)
  131.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  132.     cstr$ = _TRIM$(STR$(myValue))
  133. END FUNCTION ' cstr$
  134.  
  135. ' /////////////////////////////////////////////////////////////////////////////
  136. ' Converting C to QB64 notes:
  137.  
  138. ' PUINT?
  139. ' https://www.daniweb.com/programming/software-development/threads/1767/c-data-types
  140.  
  141. ' Platform SDK: Win32 API Data Types
  142. ' https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  143.  
  144. ' Pointers? sizeof?
  145. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_10328-0/
  146. ' https://qb64.org/wiki/OFFSET_(function)
  147. ' https://www.qb64.org/wiki/Using_OFFSET
  148.  
  149. ' sizeof?
  150. ' https://www.qb64.org/forum/index.php?topic=2427.0
  151. ' https://www.qb64.org/wiki/MEMELEMENT
  152.  
  153. ' NULL values?
  154. ' Google passing null value to api function in qb64
  155. ' https://www.google.com/search?q=passing+null+value+to+api+function+in+qb64
  156.  
  157. ' _UNSIGNED equivalent of UINT
  158. ' QB64 _UNSIGNED
  159. ' http://www.qb64.org/wiki/UNSIGNED#:~:text=Explanation%3A%20In%20QB64%20an%20unsigned,by%20the%20value%20minus%2065536.&text=Explanation%3A%20The%20maximum%20value%20can,the%20FOR%20loop%20repeats%20itself.
  160.  
  161. ' declaring API libraries
  162. ' https://www.qb64.org/wiki/DECLARE_LIBRARY
  163. ' https://www.qb64.org/forum/index.php?topic=2930.60
  164.  
  165. ' Other QB64
  166. ' QB64 Keyword Reference - By usage
  167. ' https://www.qb64.org/wiki/Keyword_Reference_-_By_usage
  168.  
  169. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  170. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  171.  
  172. ' RAWINPUTDEVICELIST structure (winuser.h) 12/05/2018
  173. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevicelist
  174.  
  175. ' About Raw Input 05/31/2018
  176. ' https://docs.microsoft.com/en-us/windows/win32/inputdev/about-raw-input
  177.  
  178. ' winuser.h -- USER procedure declarations, constant definitions and macros
  179. ' https://ecs.syr.edu/faculty/fawcett/Handouts/coreTechnologies/windowsprogramming/WinUser.h
  180.  
  181. ' RawInput example: luluco250/MouseRaw.cpp
  182. ' https://gist.github.com/luluco250/ac79d72a734295f167851ffdb36d77ee
  183.  
  184. ' -----------------------------------------------------------------------------
  185. ' What is getch?
  186. ' -----------------------------------------------------------------------------
  187. '     getch() is a nonstandard function and is present in conio.h header file
  188. '     which is mostly used by MS-DOS compilers like Turbo C. It is not part of
  189. '     the C standard library or ISO C, nor is it defined by POSIX.
  190. '     Like these functions, getch() also reads a single character from the
  191. '     keyboard. But it does not use any buffer, so the entered character is
  192. '     immediately returned without waiting for the enter key.
  193. '     Syntax: int getch(void);
  194. '     Parameters: This method does not accept any parameters.
  195. '     Return value: This method returns the ASCII value of the key pressed.
  196.  
  197. ' -----------------------------------------------------------------------------
  198. ' QB64 alternate to getch
  199. ' -----------------------------------------------------------------------------
  200. '
  201. ' SLEEP ' SLEEP without an argument waits until a keypress.)
  202. '
  203. ' or
  204. '
  205. ' DO
  206. '   x = _KEYHIT
  207. '   IF x THEN
  208. '       EXIT DO
  209. '   END IF
  210. ' LOOP
  211.  
  212. ' -----------------------------------------------------------------------------
  213. ' windows api definitions, RawInput, Windows C headers, etc.
  214. ' -----------------------------------------------------------------------------
  215. ' Winuser.h header - Win32 apps | Microsoft Docs
  216. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/
  217.  
  218. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  219. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  220.  
  221. ' GetRawInputDeviceInfoA function (winuser.h) 12/05/2018
  222. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdeviceinfoa
  223.  
  224. ' GetRawInputDeviceList and GetRawInputDeviceInfo APIs in PowerBuilder.
  225. ' https://community.appeon.com/index.php/qna/q-a/getrawinputdevicelist-and-getrawinputdeviceinfo-apis-in-powerbuilder
  226.  
  227.  

PS More info here

Info on Windows data types & converting from C:


More on what this code is supposed to do:



Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: issue with sending type _OFFSET to an API function
« Reply #1 on: April 06, 2021, 10:49:18 am »
Hi. I try using Steve McNeill's function for offset converting, so program is now compiled and run, but wrote, that this function not exists in kernel32.dll:

Code: QB64: [Select]
  1. ' ****************************************************************************************************************************************************************
  2. ' testmouse.c: A demonstration of how to use Rawinput to access multiple mice in Windows XP.
  3. ' https://jstookey.com/arcade/rawmouse/HelloRawInput.c
  4. ' ****************************************************************************************************************************************************************
  5.  
  6. ' #define _WIN32_WINNT 0x0501   // Identify this as a Windows XP application.
  7. '                               // This is necessary so we can access rawinput
  8. ' #include <stdio.h>
  9. ' #include <conio.h>            //  Provides getch()
  10. ' #include <windows.h>          //  Provides rawinput
  11.  
  12. ' =============================================================================
  13. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  14.  
  15. ' -----------------------------------------------------------------------------
  16. ' BOOLEAN CONSTANTS
  17. CONST FALSE = 0
  18. CONST TRUE = NOT FALSE
  19.  
  20. ' -----------------------------------------------------------------------------
  21. ' USER DEFINED TYPES
  22.  
  23. ' What is PRAWINPUTDEVICELIST?
  24. '     PRAWINPUTDEVICELIST:
  25. '     typedef struct tagRAWINPUTDEVICELIST {
  26. '       HANDLE hDevice;
  27. '       DWORD  dwType;
  28. '     } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
  29.  
  30. TYPE RAWINPUTDEVICELIST
  31.     hDevice AS _OFFSET ' a handle will always be _OFFSET
  32.     dwType AS LONG ' DWORD corresponds to LONG
  33.  
  34. ' -----------------------------------------------------------------------------
  35. ' API FUNCTIONS
  36.  
  37. ' What is GetRawInputDeviceList?
  38. '     UINT GetRawInputDeviceList(
  39. '       PRAWINPUTDEVICELIST pRawInputDeviceList,
  40. '       PUINT               puiNumDevices,        <---- what is a aPUINT?
  41. '       UINT                cbSize
  42. '     );
  43.  
  44. ' what is a aPUINT? According to
  45. '     WIN32 API Data Types
  46. '     https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  47. ' PUINT Pointer to a UINT.
  48. ' Q: What QB64 type is equivalent to a pointer?
  49. ' A: is it _OFFSET ?
  50.  
  51.     ' COMPILER ERROR HERE: Expected &H... or &O...
  52.     ' THEN WHEN I TRY CHANGING & TO &H OR &O, COMPILER SAYS MISSING )
  53.     FUNCTION GetRawInputDeviceList& (pRawInputDeviceList AS RAWINPUTDEVICELIST, puiNumDevices AS _OFFSET, cbSize AS _UNSIGNED LONG)
  54.  
  55. ' =============================================================================
  56. ' GLOBAL VARIABLES
  57. DIM ProgramPath$
  58. DIM ProgramName$
  59.  
  60. ' =============================================================================
  61. ' INITIALIZE
  62. ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  63. ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  64.  
  65. ' =============================================================================
  66. ' START
  67. main ProgramName$
  68.  
  69. ' =============================================================================
  70. ' FINISH
  71. SYSTEM ' return control to the operating system
  72. PRINT ProgramName$ + " finished."
  73.  
  74. ' /////////////////////////////////////////////////////////////////////////////
  75.  
  76. SUB main (ProgName$)
  77.     PRINT "MinimalRawInputTest% RETURNS: " + cstr$(MinimalRawInputTest%)
  78. END SUB ' main
  79.  
  80. FUNCTION MinimalRawInputTest%
  81.     DIM iResult%
  82.     'UINT nInputDevices;
  83.     DIM nInputDevices AS _UNSIGNED LONG
  84.     DIM MEM AS _MEM
  85.     DIM MyList AS RAWINPUTDEVICELIST
  86.     DIM MyAddr AS _OFFSET
  87.  
  88.     ' 1st call to GetRawInputDeviceList: Pass NULL to get the size of the list.
  89.     'if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) return 0;
  90.  
  91.     ' **********
  92.     ' UNKNOWNS:
  93.     ' Q1: how do you pass NULL in QB64?
  94.     ' A1: ?
  95.  
  96.     ' Q2: what is &nInputDevices vs nInputDevices and what is the QB64 equivalent?
  97.     ' A2: is it the pointer to the variable? in QB64, The _OFFSET function returns the memory offset of/within a given variable.
  98.  
  99.     ' Q3: what is the QB64 equivalent of sizeof?
  100.     ' A3: maybe _MEM and _MEM.SIZE ?
  101.  
  102.     ' _MEM
  103.     ' http://www.qb64.org/wiki/MEM
  104.     ' The _MEM variable type can be used when working with memory blocks. It has no variable type suffix.
  105.     ' The _MEM type contains the following read-only elements where name is the _MEM variable name:
  106.     '    name.OFFSET is the current start position in the memory block AS _OFFSET. Add bytes to change position.
  107.     '    name.SIZE is the remaining size of the block at current position in bytes AS _OFFSET
  108.     '    name.TYPE is the type (represented as bits combined to form a value) AS _OFFSET:
  109.  
  110.     MyAddr = _OFFSET(nInputDevices)
  111.     MEM = _MEM(RAWINPUTDEVICELIST)
  112.     size&& = ConvertOffset(MEM.SIZE)
  113.  
  114.     'IF (GetRawInputDeviceList(NULL, _OFFSET(nInputDevices), sizeof(RAWINPUTDEVICELIST)) <> 0) THEN
  115.     IF (GetRawInputDeviceList(MyList, MyAddr, size&&) <> 0) THEN
  116.         iResult% = 0
  117.     ELSE
  118.         PRINT "Number of raw input devices: " + cstr$(nInputDevices)
  119.         PRINT "Press any key..."
  120.         SLEEP ' SLEEP without an argument waits until a keypress.)
  121.         iResult% = 1
  122.     END IF
  123.  
  124.     ' RETURN RESULT (ONE EXIT POINT!)
  125.     MinimalRawInputTest% = iResult%
  126. END FUNCTION ' MinimalRawInputTest%
  127.  
  128. ' /////////////////////////////////////////////////////////////////////////////
  129. ' Equivalent to vbscript / VBA / VB6 cstr
  130.  
  131. FUNCTION cstr$ (myValue)
  132.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  133.     cstr$ = _TRIM$(STR$(myValue))
  134. END FUNCTION ' cstr$
  135.  
  136. ' /////////////////////////////////////////////////////////////////////////////
  137. ' Converting C to QB64 notes:
  138.  
  139. ' PUINT?
  140. ' https://www.daniweb.com/programming/software-development/threads/1767/c-data-types
  141.  
  142. ' Platform SDK: Win32 API Data Types
  143. ' https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  144.  
  145. ' Pointers? sizeof?
  146. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_10328-0/
  147. ' https://qb64.org/wiki/OFFSET_(function)
  148. ' https://www.qb64.org/wiki/Using_OFFSET
  149.  
  150. ' sizeof?
  151. ' https://www.qb64.org/forum/index.php?topic=2427.0
  152. ' https://www.qb64.org/wiki/MEMELEMENT
  153.  
  154. ' NULL values?
  155. ' Google passing null value to api function in qb64
  156. ' https://www.google.com/search?q=passing+null+value+to+api+function+in+qb64
  157.  
  158. ' _UNSIGNED equivalent of UINT
  159. ' QB64 _UNSIGNED
  160. ' http://www.qb64.org/wiki/UNSIGNED#:~:text=Explanation%3A%20In%20QB64%20an%20unsigned,by%20the%20value%20minus%2065536.&text=Explanation%3A%20The%20maximum%20value%20can,the%20FOR%20loop%20repeats%20itself.
  161.  
  162. ' declaring API libraries
  163. ' https://www.qb64.org/wiki/DECLARE_LIBRARY
  164. ' https://www.qb64.org/forum/index.php?topic=2930.60
  165.  
  166. ' Other QB64
  167. ' QB64 Keyword Reference - By usage
  168. ' https://www.qb64.org/wiki/Keyword_Reference_-_By_usage
  169.  
  170. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  171. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  172.  
  173. ' RAWINPUTDEVICELIST structure (winuser.h) 12/05/2018
  174. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevicelist
  175.  
  176. ' About Raw Input 05/31/2018
  177. ' https://docs.microsoft.com/en-us/windows/win32/inputdev/about-raw-input
  178.  
  179. ' winuser.h -- USER procedure declarations, constant definitions and macros
  180. ' https://ecs.syr.edu/faculty/fawcett/Handouts/coreTechnologies/windowsprogramming/WinUser.h
  181.  
  182. ' RawInput example: luluco250/MouseRaw.cpp
  183. ' https://gist.github.com/luluco250/ac79d72a734295f167851ffdb36d77ee
  184.  
  185. ' -----------------------------------------------------------------------------
  186. ' What is getch?
  187. ' -----------------------------------------------------------------------------
  188. '     getch() is a nonstandard function and is present in conio.h header file
  189. '     which is mostly used by MS-DOS compilers like Turbo C. It is not part of
  190. '     the C standard library or ISO C, nor is it defined by POSIX.
  191. '     Like these functions, getch() also reads a single character from the
  192. '     keyboard. But it does not use any buffer, so the entered character is
  193. '     immediately returned without waiting for the enter key.
  194. '     Syntax: int getch(void);
  195. '     Parameters: This method does not accept any parameters.
  196. '     Return value: This method returns the ASCII value of the key pressed.
  197.  
  198. ' -----------------------------------------------------------------------------
  199. ' QB64 alternate to getch
  200. ' -----------------------------------------------------------------------------
  201. '
  202. ' SLEEP ' SLEEP without an argument waits until a keypress.)
  203. '
  204. ' or
  205. '
  206. ' DO
  207. '   x = _KEYHIT
  208. '   IF x THEN
  209. '       EXIT DO
  210. '   END IF
  211. ' LOOP
  212.  
  213. ' -----------------------------------------------------------------------------
  214. ' windows api definitions, RawInput, Windows C headers, etc.
  215. ' -----------------------------------------------------------------------------
  216. ' Winuser.h header - Win32 apps | Microsoft Docs
  217. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/
  218.  
  219. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  220. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  221.  
  222. ' GetRawInputDeviceInfoA function (winuser.h) 12/05/2018
  223. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdeviceinfoa
  224.  
  225. ' GetRawInputDeviceList and GetRawInputDeviceInfo APIs in PowerBuilder.
  226. ' https://community.appeon.com/index.php/qna/q-a/getrawinputdevicelist-and-getrawinputdeviceinfo-apis-in-powerbuilder
  227.  
  228.  
  229. FUNCTION ConvertOffset&& (value AS _OFFSET)
  230.     DIM m AS _MEM 'Define a memblock
  231.     m = _MEM(value) 'Point it to use value
  232.     $IF 64BIT THEN
  233.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  234.         _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  235.     $ELSE
  236.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  237.         _MEMGET m, m.OFFSET, temp& 'Like this
  238.         ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
  239.     $END IF
  240.     _MEMFREE m 'Free the memblock
  241.  
  242.  

Edit:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist

try it using User32.dll, it compile, but none output is done.
« Last Edit: April 06, 2021, 10:54:10 am by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: issue with sending type _OFFSET to an API function
« Reply #2 on: April 06, 2021, 11:07:42 am »
Just information for you, if you use User32.dll and then rewrite GetRawInputDeviceList& as GetRawInputDeviceList, then it start (maybe badly?) working, it returns zero Raw devices for me.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: issue with sending type _OFFSET to an API function
« Reply #3 on: April 06, 2021, 06:00:27 pm »
Just information for you, if you use User32.dll and then rewrite GetRawInputDeviceList& as GetRawInputDeviceList, then it start (maybe badly?) working, it returns zero Raw devices for me.

Thanks Petr, I tried what you suggested, and it runs, but also returns zero raw devices.

Below is the current code - any suggestions, anyone?

Code: QB64: [Select]
  1. ' ****************************************************************************************************************************************************************
  2. ' testmouse.c: A demonstration of how to use Rawinput to access multiple mice in Windows XP.
  3. ' https://jstookey.com/arcade/rawmouse/HelloRawInput.c
  4. ' ****************************************************************************************************************************************************************
  5.  
  6. ' #define _WIN32_WINNT 0x0501   // Identify this as a Windows XP application.
  7. '                               // This is necessary so we can access rawinput
  8. ' #include <stdio.h>
  9. ' #include <conio.h>            //  Provides getch()
  10. ' #include <windows.h>          //  Provides rawinput
  11.  
  12. ' =============================================================================
  13. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  14.  
  15. ' -----------------------------------------------------------------------------
  16. ' BOOLEAN CONSTANTS
  17. CONST FALSE = 0
  18. CONST TRUE = NOT FALSE
  19.  
  20. ' -----------------------------------------------------------------------------
  21. ' USER DEFINED TYPES
  22.  
  23. ' What is PRAWINPUTDEVICELIST?
  24. '     PRAWINPUTDEVICELIST:
  25. '     typedef struct tagRAWINPUTDEVICELIST {
  26. '       HANDLE hDevice;
  27. '       DWORD  dwType;
  28. '     } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
  29.  
  30. TYPE RAWINPUTDEVICELIST
  31.     hDevice AS _OFFSET ' a handle will always be _OFFSET
  32.     dwType AS LONG ' DWORD corresponds to LONG
  33.  
  34. ' -----------------------------------------------------------------------------
  35. ' API FUNCTIONS
  36.  
  37. ' What is GetRawInputDeviceList?
  38. '     UINT GetRawInputDeviceList(
  39. '       PRAWINPUTDEVICELIST pRawInputDeviceList,
  40. '       PUINT               puiNumDevices,        <---- what is a aPUINT?
  41. '       UINT                cbSize
  42. '     );
  43.  
  44. ' what is a aPUINT? According to
  45. '     WIN32 API Data Types
  46. '     https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  47. ' PUINT Pointer to a UINT.
  48. ' Q: What QB64 type is equivalent to a pointer?
  49. ' A: is it _OFFSET ?
  50.  
  51. ' Petr: Just information for you, if you use User32.dll
  52. '       and then rewrite GetRawInputDeviceList& as GetRawInputDeviceList,
  53. '       then it start (maybe badly?) working, it returns zero Raw devices for me.
  54.  
  55. 'DECLARE DYNAMIC LIBRARY "kernel32"
  56.     ' COMPILER ERROR HERE: Expected &H... or &O...
  57.     ' THEN WHEN I TRY CHANGING & TO &H OR &O, COMPILER SAYS MISSING )
  58.     FUNCTION GetRawInputDeviceList& (pRawInputDeviceList AS RAWINPUTDEVICELIST, puiNumDevices AS _OFFSET, cbSize AS _UNSIGNED LONG)
  59.  
  60. ' =============================================================================
  61. ' GLOBAL VARIABLES
  62. DIM ProgramPath$
  63. DIM ProgramName$
  64.  
  65. ' =============================================================================
  66. ' INITIALIZE
  67. ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  68. ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  69.  
  70. ' =============================================================================
  71. ' START
  72. main ProgramName$
  73.  
  74. ' =============================================================================
  75. ' FINISH
  76. SYSTEM ' return control to the operating system
  77. PRINT ProgramName$ + " finished."
  78.  
  79. ' /////////////////////////////////////////////////////////////////////////////
  80.  
  81. SUB main (ProgName$)
  82.     DIM in$
  83.        
  84.         PRINT "MinimalRawInputTest% RETURNS: " + cstr$(MinimalRawInputTest%)
  85.     PRINT
  86.     INPUT "PRESS <ENTER> TO CONTINUE", in$
  87. END SUB ' main
  88.  
  89. FUNCTION MinimalRawInputTest%
  90.     DIM iResult%
  91.     'UINT nInputDevices;
  92.     DIM nInputDevices AS _UNSIGNED LONG
  93.     DIM MEM AS _MEM
  94.     DIM MyList AS RAWINPUTDEVICELIST
  95.     DIM MyAddr AS _OFFSET
  96.  
  97.     ' 1st call to GetRawInputDeviceList: Pass NULL to get the size of the list.
  98.     'if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) return 0;
  99.  
  100.     ' **********
  101.     ' UNKNOWNS:
  102.     ' Q1: how do you pass NULL in QB64?
  103.     ' A1: ?
  104.  
  105.     ' Q2: what is &nInputDevices vs nInputDevices and what is the QB64 equivalent?
  106.     ' A2: is it the pointer to the variable? in QB64, The _OFFSET function returns the memory offset of/within a given variable.
  107.  
  108.     ' Q3: what is the QB64 equivalent of sizeof?
  109.     ' A3: maybe _MEM and _MEM.SIZE ?
  110.  
  111.     ' _MEM
  112.     ' http://www.qb64.org/wiki/MEM
  113.     ' The _MEM variable type can be used when working with memory blocks. It has no variable type suffix.
  114.     ' The _MEM type contains the following read-only elements where name is the _MEM variable name:
  115.     '    name.OFFSET is the current start position in the memory block AS _OFFSET. Add bytes to change position.
  116.     '    name.SIZE is the remaining size of the block at current position in bytes AS _OFFSET
  117.     '    name.TYPE is the type (represented as bits combined to form a value) AS _OFFSET:
  118.  
  119.     MyAddr = _OFFSET(nInputDevices)
  120.     MEM = _MEM(RAWINPUTDEVICELIST)
  121.     size&& = ConvertOffset(MEM.SIZE)
  122.  
  123.     'IF (GetRawInputDeviceList(NULL, _OFFSET(nInputDevices), sizeof(RAWINPUTDEVICELIST)) <> 0) THEN
  124.     IF (GetRawInputDeviceList(MyList, MyAddr, size&&) <> 0) THEN
  125.         iResult% = 0
  126.     ELSE
  127.         PRINT "Number of raw input devices: " + cstr$(nInputDevices)
  128.         PRINT "Press any key..."
  129.         SLEEP ' SLEEP without an argument waits until a keypress.)
  130.         iResult% = 1
  131.     END IF
  132.  
  133.     ' RETURN RESULT (ONE EXIT POINT!)
  134.     MinimalRawInputTest% = iResult%
  135. END FUNCTION ' MinimalRawInputTest%
  136.  
  137. ' /////////////////////////////////////////////////////////////////////////////
  138. ' Hi. I try using Steve McNeill's function for offset converting,
  139. ' so program is now compiled and run, but wrote,
  140. ' that this function not exists in kernel32.dll:
  141.  
  142. FUNCTION ConvertOffset&& (value AS _OFFSET)
  143.     DIM m AS _MEM 'Define a memblock
  144.     m = _MEM(value) 'Point it to use value
  145.     $IF 64BIT THEN
  146.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  147.         _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  148.     $ELSE
  149.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  150.         _MEMGET m, m.OFFSET, temp& 'Like this
  151.         ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
  152.     $END IF
  153.     _MEMFREE m 'Free the memblock
  154.  
  155. ' /////////////////////////////////////////////////////////////////////////////
  156. ' Equivalent to vbscript / VBA / VB6 cstr
  157.  
  158. FUNCTION cstr$ (myValue)
  159.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  160.     cstr$ = _TRIM$(STR$(myValue))
  161. END FUNCTION ' cstr$
  162.  
  163. ' /////////////////////////////////////////////////////////////////////////////
  164. ' Converting C to QB64 notes:
  165.  
  166. ' PUINT?
  167. ' https://www.daniweb.com/programming/software-development/threads/1767/c-data-types
  168.  
  169. ' Platform SDK: Win32 API Data Types
  170. ' https://www.csie.ntu.edu.tw/~r92094/c++/w32api_data_type.html
  171.  
  172. ' Pointers? sizeof?
  173. ' https://qb64.org/wiki/OFFSET_(function)
  174. ' https://www.qb64.org/wiki/Using_OFFSET
  175.  
  176. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_10328-0/
  177. ' ^^^
  178. ' cached version: http://webcache.googleusercontent.com/search?q=cache:y5SVJL1obEQJ:www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_10328-0/+&cd=1&hl=en&ct=clnk&gl=us
  179.  
  180. ' sizeof?
  181. ' https://www.qb64.org/forum/index.php?topic=2427.0
  182. ' https://www.qb64.org/wiki/MEMELEMENT
  183.  
  184. ' NULL values?
  185. ' Google passing null value to api function in qb64
  186. ' https://www.google.com/search?q=passing+null+value+to+api+function+in+qb64
  187.  
  188. ' _UNSIGNED equivalent of UINT
  189. ' QB64 _UNSIGNED
  190. ' http://www.qb64.org/wiki/UNSIGNED#:~:text=Explanation%3A%20In%20QB64%20an%20unsigned,by%20the%20value%20minus%2065536.&text=Explanation%3A%20The%20maximum%20value%20can,the%20FOR%20loop%20repeats%20itself.
  191.  
  192. ' declaring API libraries
  193. ' https://www.qb64.org/wiki/DECLARE_LIBRARY
  194. ' https://www.qb64.org/forum/index.php?topic=2930.60
  195.  
  196. ' Other QB64
  197. ' QB64 Keyword Reference - By usage
  198. ' https://www.qb64.org/wiki/Keyword_Reference_-_By_usage
  199.  
  200. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  201. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  202.  
  203. ' RAWINPUTDEVICELIST structure (winuser.h) 12/05/2018
  204. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevicelist
  205.  
  206. ' About Raw Input 05/31/2018
  207. ' https://docs.microsoft.com/en-us/windows/win32/inputdev/about-raw-input
  208.  
  209. ' winuser.h -- USER procedure declarations, constant definitions and macros
  210. ' https://ecs.syr.edu/faculty/fawcett/Handouts/coreTechnologies/windowsprogramming/WinUser.h
  211.  
  212. ' RawInput example: luluco250/MouseRaw.cpp
  213. ' https://gist.github.com/luluco250/ac79d72a734295f167851ffdb36d77ee
  214.  
  215. ' -----------------------------------------------------------------------------
  216. ' What is getch?
  217. ' -----------------------------------------------------------------------------
  218. '     getch() is a nonstandard function and is present in conio.h header file
  219. '     which is mostly used by MS-DOS compilers like Turbo C. It is not part of
  220. '     the C standard library or ISO C, nor is it defined by POSIX.
  221. '     Like these functions, getch() also reads a single character from the
  222. '     keyboard. But it does not use any buffer, so the entered character is
  223. '     immediately returned without waiting for the enter key.
  224. '     Syntax: int getch(void);
  225. '     Parameters: This method does not accept any parameters.
  226. '     Return value: This method returns the ASCII value of the key pressed.
  227.  
  228. ' -----------------------------------------------------------------------------
  229. ' QB64 alternate to getch
  230. ' -----------------------------------------------------------------------------
  231. '
  232. ' SLEEP ' SLEEP without an argument waits until a keypress.)
  233. '
  234. ' or
  235. '
  236. ' DO
  237. '   x = _KEYHIT
  238. '   IF x THEN
  239. '       EXIT DO
  240. '   END IF
  241. ' LOOP
  242.  
  243. ' -----------------------------------------------------------------------------
  244. ' windows api definitions, RawInput, Windows C headers, etc.
  245. ' -----------------------------------------------------------------------------
  246. ' Winuser.h header - Win32 apps | Microsoft Docs
  247. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/
  248.  
  249. ' GetRawInputDeviceList function (winuser.h) 12/05/2018
  250. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdevicelist
  251.  
  252. ' GetRawInputDeviceInfoA function (winuser.h) 12/05/2018
  253. ' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdeviceinfoa
  254.  
  255. ' GetRawInputDeviceList and GetRawInputDeviceInfo APIs in PowerBuilder.
  256. ' https://community.appeon.com/index.php/qna/q-a/getrawinputdevicelist-and-getrawinputdeviceinfo-apis-in-powerbuilder
  257.  
  258.  

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: issue with sending type _OFFSET to an API function
« Reply #4 on: April 09, 2021, 09:23:26 am »
Just information for you, if you use User32.dll and then rewrite GetRawInputDeviceList& as GetRawInputDeviceList, then it start (maybe badly?) working, it returns zero Raw devices for me.

I could try running the original C code
https://jstookey.com/multiple-mice-raw-input/

but I'm not sure what tools to use for Windows.
I downloaded Visual Studio 2019 community edition,
and tried importing the code, but it seems that the IDE supports C++ and not C.
I tried investigating further, and people say that Visual Studio can compile C (files with .c extension) but it only understands C89 (older version of the language). I can't figure out how to get it to work.

Could anyone recommend a C compiler for Windows 10, that would work with the code, and requires minimal knowledge to install & use? (For one thing I would like to avoid having to install Java on my PC!)

Or is there some way to "tap into" QB64's C compiler, to use that to compile C code into an executable?
« Last Edit: April 09, 2021, 09:25:27 am by madscijr »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: issue with sending type _OFFSET to an API function
« Reply #5 on: April 09, 2021, 09:37:06 am »
I was able to compile one of his samples using our gcc. It worked, but it was ugly as heck.
Shuwatch!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: issue with sending type _OFFSET to an API function
« Reply #6 on: April 10, 2021, 01:18:37 pm »
I was able to compile one of his samples using our gcc. It worked, but it was ugly as heck.

Can you recommend a C compiler or IDE for Windows 10 that would do the job?