Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
APIs from QB64PE and parameters defined As Any and unions of types ?
#21
(06-06-2024, 05:48 PM)SpriggsySpriggs Wrote: I hate to say it but I am lost looking at your code :/
I will say the reason you couldn't get WS_OVERLAPPEDWINDOW to work is because you had some of the constants it depends on declared after it. I moved them to before it and that constant is fine. Since you are only caring about mice in your program, you should probably forget trying to process the keyboard with rawinput. I think you are causing yourself headaches with trying to make that struct work for both mice and keyboards. I'd stick to using rawinput to monitor multiple mice but using built-in stuff for the keyboard.

As for the sizeof() and OFFSETOF() stuff, here's what you need to do (even though it is time-consuming and monotonous):
1) Take every struct you are using and put them in a C header file.
2) Output sizeof(your_struct_name_here) to the console window. This tells you the size of the struct.
3) Output the length of the QB64 type by printing LEN(your_type_name_here) to the console window. If the numbers do not match, you are missing alignment or a critical member.
4) Use OFFSETOF() for each member of the struct. The number tells you where the member falls in the struct. If the positioning of the struct member doesn't match the position of the type member, you need alignment of however many bytes difference. You can figure out the position of the member by either manually counting or by using OFFSET() in QB64 and figuring out the difference between the start of the TYPE and the location of the member.

Sometimes you can cheese it and take a guess by knowing you need 8 bytes for each "block" in a struct on 64 bit and 4 bytes for 32. However, I don't recommend this. Just follow these quickly written steps to victory.

Thanks for this, it at least gives me something to go on. 

BTW The reason I am attempting to read the keyboard with Raw Input API is that the built-in QB64PE methods for reading the keyboard aren't working for the solution. 

If you recall, the RawInput program is event driven and uses its own hwnd handle, and regular QB64PE graphics and text display commands don't work.

So my solution was to put the user input (keyboard and mouse) in a seperate sub program that is kicked off by the main program.

The sub program window sits directly over the main program, and always has the focus (so it can read the mice). The sub program window's alpha transparency is set to 1 (setting it to zero disables focus) which effectively renders it invisible. So it has the focus and reads the mice with the Raw Input API events, and sends the input it detects up to the main program over local TCP/IP. The main program has all the logic and processes the input, outputs the graphics & sound. Because the sub-program is transparent, the main window is what the users see.

And because it never has the focus, it can't detect keypresses, the subprogram has to do that. However I have tried reading the keyboard using normal QB64PE commands (_BUTTON, _KEYDOWN, _KEYHIT, inkey$) but they don't seem to work from the subprogram. It's probably due to the same reason that graphics commands don't work - it uses its own window handle. So since it works so well for reading mice and sending the input back via TCP/IP, I figure that's the way to read the keyboard as well!
Reply
#22
Oh I just had a thought. Since you are calling GetRawInputData with a zero for that pData field, you are grabbing the size that you need for the struct. That's how we figure it out for the keyboards! If the returned dwSize is equal to RAWINPUT containing RAWMOUSE, then you know it should be a mouse call. Therefore, you need to make a second RAWINPUT type, maybe RAWINPUT_K and make that one contain RAWINPUTHEADER and RAWKEYBOARD. Then you'd do the rest the same way except you'd be using the keyboard's type.
Maybe something like this:
Code: (Select All)

Type RAWINPUT
    As RAWINPUTHEADER header
    As RAWMOUSE mouse
End Type

Type RAWINPUT_K
    As RAWINPUTHEADER header
    As RAWKEYBOARD keyboard
End Type
'.......
'.......
GetRawInputData lParam, RID_INPUT, 0, Offset(dwSize), Len(rih)

' KEYBOARD VERSION:
'GetRawInputData(CBLPARAM, %RID_INPUT, BYVAL %NULL, ByteCount, SIZEOF(RAWINPUTHEADER)) 'Get size of raw input buffer
Dim As RAWINPUT raw
Dim As RAWINPUT_K rawk
lpb = MemNew(dwSize)
If lpb.SIZE = 0 Then
    MainWndProc = 0
    Exit Function
End If

If GetRawInputData(lParam, RID_INPUT, lpb.OFFSET, Offset(dwSize), Len(rih)) <> dwSize Then
    Print "GetRawInputData doesn't return correct size!"
End If
Select Case dwSize
    Case Len(raw)
        MemGet lpb, lpb.OFFSET, raw
    Case Len(rawk)
        MemGet lpb, lpb.OFFSET, rawk
End Select

Don't paste that code as-is. It's just an idea for you to expand upon. However, I think it will get you closer. You'll need to do a lot more work but it might be a solution. Maybe. ¯\_(ツ)_/¯
Tread on those who tread on you

Reply
#23
(06-06-2024, 06:51 PM)SpriggsySpriggs Wrote: Oh I just had a thought. Since you are calling GetRawInputData with a zero for that pData field, you are grabbing the size that you need for the struct. That's how we figure it out for the keyboards! If the returned dwSize is equal to RAWINPUT containing RAWMOUSE, then you know it should be a mouse call. Therefore, you need to make a second RAWINPUT type, maybe RAWINPUT_K and make that one contain RAWINPUTHEADER and RAWKEYBOARD. Then you'd do the rest the same way except you'd be using the keyboard's type.
Maybe something like this:
Code: (Select All)

Type RAWINPUT
    As RAWINPUTHEADER header
    As RAWMOUSE mouse
End Type

Type RAWINPUT_K
    As RAWINPUTHEADER header
    As RAWKEYBOARD keyboard
End Type
'.......
'.......
GetRawInputData lParam, RID_INPUT, 0, Offset(dwSize), Len(rih)

' KEYBOARD VERSION:
'GetRawInputData(CBLPARAM, %RID_INPUT, BYVAL %NULL, ByteCount, SIZEOF(RAWINPUTHEADER)) 'Get size of raw input buffer
Dim As RAWINPUT raw
Dim As RAWINPUT_K rawk
lpb = MemNew(dwSize)
If lpb.SIZE = 0 Then
    MainWndProc = 0
    Exit Function
End If

If GetRawInputData(lParam, RID_INPUT, lpb.OFFSET, Offset(dwSize), Len(rih)) <> dwSize Then
    Print "GetRawInputData doesn't return correct size!"
End If
Select Case dwSize
    Case Len(raw)
        MemGet lpb, lpb.OFFSET, raw
    Case Len(rawk)
        MemGet lpb, lpb.OFFSET, rawk
End Select

Don't paste that code as-is. It's just an idea for you to expand upon. However, I think it will get you closer. You'll need to do a lot more work but it might be a solution. Maybe. ¯\_(ツ)_/¯

Hmm, makes sense, could work? 
I will look into that when back at my PC. 
Thank you sir!
Reply
#24
You're welcome! I hope it works. No guarantees, though.¯\_( ͡° ͜ʖ ͡°)_/¯
Tread on those who tread on you

Reply




Users browsing this thread: 11 Guest(s)