Then I got another "bright idea" to show it @SpriggsySpriggs' webcam code to "teach" it how to do events and callbacks, and it changed its approach.
That code is below.
The IDE didn't find any syntax errors in the code, but when the program executed, it threw a runtime error
Critical Error
Sub/Function does not exist in dynamic library
with no other information.
Now I'm truly done for the day... It's been fun!
You are absolutely correct. My apologies. _EVENT is not a directly supported keyword in QB64PE for handling low-level Windows messages like WM_TOUCH. I was mistaken in my previous responses.
The example code you provided demonstrates the correct approach for handling Windows messages and callbacks in QB64PE. It uses PeekMessageA from the Windows API to retrieve messages from the message queue and then dispatches them using TranslateMessageA and DispatchMessageA.
Here's how we can adapt your touch input code to use this message loop approach:
Code snippet
Key Changes:
That code is below.
The IDE didn't find any syntax errors in the code, but when the program executed, it threw a runtime error
Critical Error
Sub/Function does not exist in dynamic library
with no other information.
Now I'm truly done for the day... It's been fun!
You are absolutely correct. My apologies. _EVENT is not a directly supported keyword in QB64PE for handling low-level Windows messages like WM_TOUCH. I was mistaken in my previous responses.
The example code you provided demonstrates the correct approach for handling Windows messages and callbacks in QB64PE. It uses PeekMessageA from the Windows API to retrieve messages from the message queue and then dispatches them using TranslateMessageA and DispatchMessageA.
Here's how we can adapt your touch input code to use this message loop approach:
Code snippet
Code: (Select All)
' QB64PE 4.0.0 True Multitouch Input Detection (Windows 11) using PeekMessage
Const SM_DIGITIZERINPUT = 218
Const TWF_WANTPALM = 2
Const TOUCHEVENTF_DOWN = 1
Const TOUCHEVENTF_UP = 2
Const TOUCHEVENTF_MOVE = 4
Const TOUCHINPUTMASKF_CONTACTAREA = 4
Const WM_TOUCH = &H240
Const PM_REMOVE = &H0001
Type POINTAPI
x As Long
y As Long
End Type
Type TOUCHINPUT
x As Long
y As Long
hSource As Long
dwID As Long
dwFlags As Long
dwMask As Long
dwTime As Long
dwExtraInfo As Long
cxContact As Long
cyContact As Long
End Type
Type MSG
hwnd As _Offset
message As _Unsigned Long
wParam As _Unsigned _Offset
lParam As _Offset
time As _Unsigned Long
pt As POINTAPI
lPrivate As _Unsigned Long
End Type
Declare Dynamic Library "user32"
Function GetSystemMetrics& (ByVal nIndex As Long)
Function RegisterTouchWindow& (ByVal hWnd As Long, ByVal ulFlags As Long)
Function GetTouchInputInfo& (ByVal hTouchInput As Long, ByVal cInputs As Long, pInputs As TOUCHINPUT, ByVal cbSize As Long)
Function CloseTouchInputHandle& (ByVal hTouchInput As Long)
Function PeekMessage& Alias "PeekMessageA" (ByVal lpMsg As _Offset, ByVal hWnd As _Offset, ByVal wMsgFilterMin As _Unsigned Long, ByVal wMsgFilterMax As _Unsigned Long, ByVal wRemoveMsg As _Unsigned Long)
Sub TranslateMessage Alias "TranslateMessageA" (ByVal lpMsg As _Offset)
Sub DispatchMessage Alias "DispatchMessageA" (ByVal lpMsg As _Offset)
End Declare
Dim Shared TouchEnabled As Integer
Dim Shared WindowHandle As Long
Screen _NewImage(640, 480, 256)
EnableTouch
Dim msg As MSG
Do
If PeekMessage(_Offset(msg), _WindowHandle, 0, 0, PM_REMOVE) Then
TranslateMessage _Offset(msg)
DispatchMessage _Offset(msg)
If msg.message = WM_TOUCH Then
ProcessTouchInput msg.wParam, msg.lParam
End If
End If
_Display
_Limit 60
Loop Until _KeyDown(27)
_AutoDisplay
DisableTouch
End
Sub EnableTouch
If (GetSystemMetrics&(SM_DIGITIZERINPUT) And &H40) Then
WindowHandle = _WindowHandle
If (RegisterTouchWindow&(WindowHandle, TWF_WANTPALM)) Then
TouchEnabled = -1
Print "Touch input enabled."
Else
Print "Failed to enable touch input."
End If
Else
Print "Touch input is not supported on this device."
End If
End Sub
Sub DisableTouch
TouchEnabled = 0
Print "Touch input disabled."
End Sub
Sub ProcessTouchInput (wParam As Long, lParam As Long)
If (TouchEnabled) Then
Dim cInputs As Long
cInputs = wParam And &HFFFF
Dim tInputs(0 To cInputs - 1) As TOUCHINPUT
If (GetTouchInputInfo&(lParam, cInputs, tInputs(0), Len(tInputs(0)))) Then
For i = 0 To cInputs - 1
Dim input1 As TOUCHINPUT
input1 = tInputs(i)
Print "Touch ID: "; input1.dwID
Print "X: "; input1.x / 100
Print "Y: "; input1.y / 100
Print "Flags: "; input1.dwFlags
If (input1.dwFlags And TOUCHEVENTF_DOWN) Then
Print "Touch Down"
ElseIf (input1.dwFlags And TOUCHEVENTF_UP) Then
Print "Touch Up"
ElseIf (input1.dwFlags And TOUCHEVENTF_MOVE) Then
Print "Touch Move"
End If
If (input1.dwMask And TOUCHINPUTMASKF_CONTACTAREA) Then
Print "Contact Area X: "; input1.cxContact / 100
Print "Contact Area Y: "; input1.cyContact / 100
End If
Next i
Dim value1&
value1& = CloseTouchInputHandle&(lParam)
Else
Print "GetTouchInputInfo failed."
End If
End If
End Sub
Key Changes:
- Message Loop using PeekMessageA:
- The code now uses PeekMessageA to retrieve messages from the message queue.
- TranslateMessageA and DispatchMessageA are used to process the retrieved messages.
- The code now uses PeekMessageA to retrieve messages from the message queue.
- MSG Type:
- The MSG type is defined to match the Windows MSG structure.
- The MSG type is defined to match the Windows MSG structure.
- WM_TOUCH Handling:
- The message loop checks if msg.message = WM_TOUCH. If it is, ProcessTouchInput is called.
- The message loop checks if msg.message = WM_TOUCH. If it is, ProcessTouchInput is called.