c4s wrote:...The main event loop already gives me what I want, why?
Hi c4s. You're right; PureBasic's window event loop does process almost all the windows' messages, but not all. This example will illustrate how the WM_PAINT event and the parameters of the WM_SIZE event cannot be effectively handled by PureBasic's window event loop:
Code: Select all
Procedure WinCallback(WindowID, Message, WParam, LParam)
Select Message
Case #WM_SIZE
Select WParam
Case #SIZE_MINIMIZED
Debug "Callback: Minimized"
EndSelect
Case #WM_PAINT
Debug "Callback: Paint"
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0, 0, 0, 400, 300, "Windows Callback", #PB_Window_SystemMenu |
#PB_Window_MinimizeGadget |
#PB_Window_ScreenCentered)
SetWindowCallback(@WinCallback())
MessageRequester("Windows Messages",
"Move this message box over the window" + #CRLF$ +
"and notice that PureBasic's event loop" + #CRLF$ +
"does not receive the WM_PAINT events.")
MessageRequester("Windows Messages",
"When the window is minimized, PureBasic's event" + #CRLF$ +
"loop can only process the WM_SIZE message, but" + #CRLF$ +
"not the SIZE_MINIMIZED message parameter.")
ClearDebugOutput()
Repeat
Select WaitWindowEvent()
Case #WM_SIZE
Debug "PureBasic: Size"
;EventwParam()?
Case #WM_PAINT
Debug "PureBasic: Paint"
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
In addition to this, in some cases, callbacks can offer greater control over the subclassed gadgets in the way the windows' messages are processed. Although PureBasic's SetWindowCallback() function does not seem to do this, the Windows' API function SetWindowLongPtr() provides the option to either dispatch or discard the intercepted messages, which can be very useful. This functionality is demonstrated in this example, which subclasses an EditorGadget() and disables the TAB and ENTER keys:
Code: Select all
Procedure EditorProc(hWnd, uMsg, wParam, lParam)
Shared sysProc
Select uMsg
Case #WM_CHAR, #WM_KEYDOWN
Select wParam
Case #VK_TAB
SetGadgetText(1, "You pressed TAB")
uMsg = 0
Case #VK_RETURN
SetGadgetText(1, "You pressed ENTER")
uMsg = 0
EndSelect
EndSelect
ProcedureReturn CallWindowProc_(sysProc, hWnd, uMsg, wParam, lParam)
EndProcedure
OpenWindow(0, 0, 0, 200, 150, "Windows Callback",
#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
EditorGadget(1, 5, 5, 190, 110, #PB_Editor_WordWrap)
ButtonGadget(2, 5, 120, 190, 20, "Activate Callback")
SetGadgetText(1, "Press the TAB & RETURN keys to test their normal behaviour...")
SetActiveGadget(1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 2
If activated
SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, sysProc)
SetGadgetText(2, "Deactivated - Click to Activate")
activated = 0
Else
sysProc = SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, @EditorProc())
SetGadgetText(2, "Activated - Click to Deactivate")
activated = 1
EndIf
SetGadgetText(1, "Press the TAB & RETURN now...")
SetActiveGadget(1)
EndSelect
EndSelect
Until appQuit = 1
Since PureBasic's SetWindowCallback() is now a Windows-only function, the SetWindowLong() alternative will not compromise cross-platform compatibility. However, the use of Windows-only message constants like WM_MOUSEMOVE, WM_KEYDOWN, etc., in the main event loop would require a lot of conditional compiling to keep the program cross-compatible.
My apologies if this is off-topic.
