Page 1 of 2
CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 6:32 am
by BarryG
Just spent over an hour trying to work out why my main app wasn't responding to a checkbox change... and discovered this.
Surely this event type should be supported for checkboxes when their state changes? Using GetGadgetState() doesn't help because I just want to know if one of MANY checkboxes has been clicked (as well as a stringgadget being changed), without iterating through all my gadgets and checking their new state compared to their old state.
Code: Select all
If OpenWindow(0, 0, 0, 270, 100, "Changed", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
StringGadget(1, 10, 40, 250, 20, "")
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget And EventType()=#PB_EventType_Change ; Doesn't work for CheckBoxes. :(
Debug "Either a CheckBox or StringGadget changed"
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
[Edit] Example of what I want to do: In the screenshot below (not my app), I just want to know if the user has changed ANY gadget shown, including the checkbox states. See how many there are, and why I don't want to save the state of every gadget to test? An event raised when any gadget changes would be fantastic and more convenient, because my main loop would know SOMETHING changed without me needing to know WHAT changed.

Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 6:50 am
by breeze4me
Check by the event gadget number without the event type.
There are a few gadgets that don't have a specified event type, and it's a bit ambiguous to just check by gadget number.
Code: Select all
If OpenWindow(0, 0, 0, 270, 160, "CheckBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget And EventGadget() = 0
Debug "Checkbox changed"
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 6:51 am
by BarryG
Edited my first post while you replied.

That won't work because as mentioned, I don't want to iterate through and check all my gadgets. There could be an unlimited number of them as they can be created at runtime. EventType() would do the job better, as demonstrated in my edited first post (see the edited "Debug" line). I don't need to check their state, but just to know that they've been changed.
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 7:14 am
by breeze4me
For the time being, you can use something like this.
Code: Select all
Procedure WndProc(hwnd, msg, wparam, lparam)
Protected Window, Gadget
If msg = #WM_COMMAND And (wparam >> 16) & $FFFF = #BN_CLICKED
Window = GetProp_(hwnd, "PB_WindowID") - 1
If WindowID(Window) = hwnd
Gadget = GetWindowLongPtr_(lparam, #GWLP_ID)
If GadgetID(Gadget) = lparam
PostEvent(#PB_Event_Gadget, Window, Gadget, #PB_EventType_Change)
EndIf
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If OpenWindow(0, 0, 0, 270, 160, "CheckBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
CheckBoxGadget(1, 10, 40, 250, 20, "CheckBox standard")
StringGadget(2, 10, 70, 250, 20, "")
SetWindowCallback(@WndProc())
; Fixed an issue with an event being fired immediately after execution. Probably not happening in real app.
While WindowEvent() : Wend
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget And EventType() = #PB_EventType_Change
Debug "Either a CheckBox or StringGadget changed : " + EventGadget()
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 7:19 am
by jacdelad
Checkboxen usually work well with BindGadget if just a short piece of code has to be executed.
Can't test right now: Does it send a #PB_EventType_LeftClick?
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 7:30 am
by BarryG
At the moment I've resorted to this (no callback and no need to test a specific gadget):
Code: Select all
If OpenWindow(0, 0, 0, 270, 100, "CheckBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
StringGadget(1, 10, 40, 250, 20, "")
Repeat : Until WaitWindowEvent()=0 ; Flush events before main loop starts.
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget
ag=GetActiveGadget()
If EventType()=#PB_EventType_Change Or (ag<>-1 And GadgetType(ag)=#PB_GadgetType_CheckBox)
Debug "CheckBox or StringGadget changed"
EndIf
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
The manual says the CheckBoxGadget doesn't support ANY event types... and neither does the ButtonGadget.

Both should, IMO, because the ButtonGadget has a #PB_Button_Toggle mode, so like a CheckBox it'd be good to get a change event when it's been toggled from a click.
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 7:45 am
by AZJIO
1. When an event comes from a checkbox, it always changes.
2. If checkboxes are generated, then you can create a range of identifiers for them and check them in a cycle from 1 to the maximum.
3. It would be possible to save the state in SetGadgetData, but this is unnecessary; it is enough to check the state of the gadget without additional data caching.
Code: Select all
Define y, x, i, eg
If OpenWindow(0, 0, 0, 620, 450, "Example...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 18, 30, Chr($205E)) ; ⁞ (menu)
ButtonGadget(2, 30, 10, 18, 30, Chr($2261)) ; ≡ (menu)
ButtonGadget(3, 50, 10, 26, 30, Chr($2630)) ; ☰ (menu)
ButtonGadget(4, 78, 10, 26, 30, Chr($25BC)) ; ▼ (menu)
ButtonGadget(5, 10, 50, 26, 30, Chr($266B)) ; ♫ (melody)
ButtonGadget(6, 78, 50, 26, 26, Chr($2026)) ; … (browse)
y = 80
x = 10
For i = 7 To 108
CheckBoxGadget(i , x , y , 100 , 20 , Str(i))
y + 20
If y > 400
y = 80
EndIf
If y = 80
x + 100
EndIf
Next
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
eg = EventGadget()
Select eg
Case 7 To 108
Debug eg
Debug GetGadgetState(eg) & #PB_Checkbox_Checked
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(0)
End
EndSelect
ForEver
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 7:57 am
by breeze4me
@BarryG
Clicking the checkbox gadget while the string gadget is active fires two more events from the string gadget. And typing in the string gadget fires two events.
If this is not a problem in your app, you don't need to fix it.
Code: Select all
If OpenWindow(0, 0, 0, 270, 100, "CheckBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
StringGadget(1, 10, 40, 250, 20, "")
Repeat : Until WaitWindowEvent()=0 ; Flush events before main loop starts.
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget
ag=GetActiveGadget()
If EventType()=#PB_EventType_Change Or (ag<>-1 And GadgetType(eg)=#PB_GadgetType_CheckBox)
Debug "CheckBox or StringGadget changed " + EventGadget()
EndIf
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 10:18 am
by mk-soft
Save last state ...
Code: Select all
;-TOP
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
; Resize Gadgets
EndProcedure
Procedure Main()
Protected dx, dy
#WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
; MenuBar
CreateMenu(0, WindowID(0))
MenuTitle("&File")
MenuItem(99, "E&xit")
; StatusBar
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
CheckBoxGadget(0, 10, 10, 120, 25, "CheckBox")
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
; Main Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case 0
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case 99
PostEvent(#PB_Event_CloseWindow, 0, 0)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Select EventType()
Case #PB_EventType_LeftClick
state = GetGadgetState(0)
If state <> GetGadgetData(0)
SetGadgetData(0, state)
; Do any
Debug "ComboBox changed"
EndIf
EndSelect
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 10:39 am
by BarryG
Thanks for the replies and workarounds, but this is just to request that CheckBoxGadgets (and ButtonGadgets) support #PB_EventType_Change so that workarounds aren't needed.

It's logical that any gadget that can change, should use #PB_EventType_Change when it does. To me, anyway.
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 4:09 pm
by AZJIO
The constant #PB_EventType_Change is not just a change of any element, it is a constant existing in WinAPI for elements that support text input. If you make a universal crutch, then it can later create problems. There are a lot of WinAPI functions that are not supported, for ListIconGadget up to
150 functions instead of 10
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 5:19 pm
by Axolotl
not as fancy as the others, but maybe ...
Code: Select all
; selfmade constant .....
;
#PB_EventType_Checked = 0
If OpenWindow(0, 0, 0, 270, 100, "Changed", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
StringGadget(1, 10, 40, 250, 20, "")
Repeat
ev=WaitWindowEvent()
If ev = #PB_Event_Gadget And (EventType() = #PB_EventType_Change Or EventType() = #PB_EventType_Checked) ; Doesn't work for CheckBoxes. :(
Debug "Either a CheckBox or StringGadget changed"
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 9:47 pm
by mestnyi
That's how it works.
Code: Select all
If OpenWindow(0, 0, 0, 270, 100, "Changed", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CheckBoxGadget(0, 10, 10, 250, 20, "CheckBox standard")
StringGadget(1, 10, 40, 250, 20, "")
Repeat
ev=WaitWindowEvent()
If ev=#PB_Event_Gadget And EventType()=0;#PB_EventType_Change ; Doesn't work for CheckBoxes. :(
Debug "Either a CheckBox or StringGadget changed"
EndIf
Until ev= #PB_Event_CloseWindow
EndIf
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sat Nov 09, 2024 11:54 pm
by mk-soft
EventType() = #Null is ...
Re: CheckBox doesn't support #PB_EventType_Change
Posted: Sun Nov 10, 2024 6:31 pm
by mestnyi
mk-soft wrote: Sat Nov 09, 2024 11:54 pm
EventType() = #Null is ...
That's true, but Fred doesn't want to fix this situation in any way. moreover, I do not understand how the event value can be zero.
