Hi all,
I've just come across something interesting with the scrollbar gadget. It's a very simple scenario, there is an edit box on my form and a scrollbar (other stuff as well of course, but these are the only two of relevance here). I have some code in the LostFocus event for the edit box that writes the value into a variable. This works fine when the focus is lost by clicking on another gadget (i.e. a Save button or another field), but if I click on the Scrollbar, then the scrollbar event is fired first before the LostFocus event on the editbox. This is not desirable as the scrollbar event triggers a field refresh, so the field values are changed before the LostFocus takes effect, and therefore the LostFocus code is querying the wrong (refreshed) value. I've tried moving the event code around so that the scrollbar event is placed after the lostfocus event but this doesn't make any difference. Has anyone else come across this behaviour, and if so any ideas on how to prevent it?
Thank you.
Event handling with scrollbar
Event handling with scrollbar
Valui ad satanam in computatrum meum invocandum
Re: Event handling with scrollbar
maybe you should use an on change event for the edit box instead of lost focus to set your variable
Windows 11, Manjaro, Raspberry Pi OS


Re: Event handling with scrollbar
Hello kiwidave. idle's suggestion to trap the #PB_EventType_Change event is quite preferable as the changes are tracked "real time". However, I can't seem to get a lost focus event by simply clicking on the ScrollBarGadget():kiwidave wrote:...there is an edit box on my form and a scrollbar ... This works fine when the focus is lost by clicking on another gadget (i.e. a Save button or another field), but if I click on the Scrollbar, then the scrollbar event is fired first before the LostFocus event on the editbox. ...
Code: Select all
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 200, 230, "Focus Events", wFlags)
EditorGadget(1, 10, 10, 165, 90)
StringGadget(2, 10, 105, 165, 90, "StringGadget()")
ScrollBarGadget(3, 175, 10, 15, 185, 0, 100, 20, #PB_ScrollBar_Vertical)
ButtonGadget(4, 10, 200, 180, 20, "Button")
SetGadgetText(1, "EditorGadget()")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case 1, 2
Select EventType()
Case #PB_EventType_Focus
Debug "Gadget #:" + EventGadget() + " got focus"
Case #PB_EventType_LostFocus
Debug "Gadget #:" + EventGadget() + " lost focus"
EndSelect
Case 3
Debug "ScrollBar event..."
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: Event handling with scrollbar
Thank you TI-994A, your example is exactly what I'm seeing - clicking from either of the edit or string boxes to the scrollbar doesn't fire the lostfocus event. The fact that I am seeing a subsequent lostfocus being fired may be something to do with the fact that on my scrollbar event I do a pile of gadget manipulation, but this is not of a concern at the moment.TI-994A wrote:Hello kiwidave. idle's suggestion to trap the #PB_EventType_Change event is quite preferable as the changes are tracked "real time". However, I can't seem to get a lost focus event by simply clicking on the ScrollBarGadget()
I would suggest that this is a bug in that case. I was trying to avoid using #PB_EventType_Change as suggested by idle simply because it incurs unnecessary system overhead for what I am wanting to achieve, but given your example confirming the behaviour, I think I will need to go down this path.
Valui ad satanam in computatrum meum invocandum
Re: Event handling with scrollbar
@kiwidave:
What happens on your OS when you use BindGadgetEvent()?The old event system had some problems with real-time event handling, for example with ScrollbarGadget(),
and also window resize and such things. That's why it has been replaced with the new system using Bind(Gadget)Event, PostEvent, etc.
On Windows, the OS bypasses the ordinary event queue for some real-time events. It calls directly
the event handler of the specific control, so it also bypasses the PureBasic event handling. That's the problem.
In your special case you could simply do:
What happens on your OS when you use BindGadgetEvent()?
Code: Select all
Procedure OnGotFocus()
Debug "Gadget #:" + EventGadget() + " got focus"
EndProcedure
Procedure OnLostFocus()
Debug "Gadget #:" + EventGadget() + " lost focus"
EndProcedure
Procedure OnScroll()
Debug "ScrollBar event..."
EndProcedure
Procedure OnClose()
End
EndProcedure
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 200, 230, "Focus Events", wFlags)
EditorGadget(1, 10, 10, 165, 90)
StringGadget(2, 10, 105, 165, 90, "StringGadget()")
ScrollBarGadget(3, 175, 10, 15, 185, 0, 100, 20, #PB_ScrollBar_Vertical)
ButtonGadget(4, 10, 200, 180, 20, "Button")
SetGadgetText(1, "EditorGadget()")
BindGadgetEvent(1,@OnGotFocus() ,#PB_EventType_Focus)
BindGadgetEvent(1,@OnLostFocus(),#PB_EventType_LostFocus)
BindGadgetEvent(2,@OnGotFocus() ,#PB_EventType_Focus)
BindGadgetEvent(2,@OnLostFocus(),#PB_EventType_LostFocus)
BindGadgetEvent(3,@OnScroll())
BindEvent(#PB_Event_CloseWindow,@OnClose(),0)
While WaitWindowEvent(): Wend
EndIf
and also window resize and such things. That's why it has been replaced with the new system using Bind(Gadget)Event, PostEvent, etc.
On Windows, the OS bypasses the ordinary event queue for some real-time events. It calls directly
the event handler of the specific control, so it also bypasses the PureBasic event handling. That's the problem.
In your special case you could simply do:
Code: Select all
Procedure OnScroll()
If GetActiveGadget()=1
; save your values
Debug "values saved"
EndIf
; more processing
Debug "ScrollBar event..."
EndProcedure