Continuing on the subject of a child window closing when it loses focus
(running PB 5.62 (X64) on Windows 10 Pro x64)
I'm still using
the.weavster's sample code, heavily modified by
Ti-994A and some more by
me. What follows is its latest incarnation, with the addition of a few debug statements to track what happens under certain circumstances :
Code: Select all
;- :: ************************************
;- :: may 2018
;- :: source : the.weavster
;- :: modified by TI-994A, Blue
;- :: child window 3
; https://www.purebasic.fr/english/viewtopic.php?p=522679#p522679
; demo : how to open an interactive child window WITHOUT using a secondary dedicated events loop
;- :: ************************************
EnableExplicit
; :: constantes
Enumeration windows
#main_WINDOW
#child_WINDOW
EndEnumeration
Enumeration gadgets
#main_btn
#main_clock
#child_btn
#child_clock
EndEnumeration
Enumeration timers
#main_timer
#child_timer
EndEnumeration
;.
Procedure Child_Open()
If OpenWindow(#child_WINDOW,#PB_Ignore,#PB_Ignore,250,150,"child",#PB_Window_SystemMenu)
ButtonGadget(#child_btn,10,10,150,30,"Message Box")
TextGadget(#child_clock,20, 110, 210, 30,
FormatDate("%hh:%ii", Date()), #PB_Text_Right)
AddWindowTimer(#child_WINDOW, #child_timer, 1000)
SetWindowData(#child_WINDOW,#True) ; signals that, when losing focus, the child window must close
ResizeWindow(#child_WINDOW,WindowX(#main_WINDOW)+80,WindowY(#main_WINDOW)+80,#PB_Ignore,#PB_Ignore) ;so it remains visible
SetWindowTitle(#child_WINDOW,"Closes spontaneously !") ; show action in title
#timerTime = 20 ; timer duration
Global timer_t = #timerTime ; timer countdown
EndIf
EndProcedure
Procedure Child_gadgets(gadget, eventType)
Select gadget
Case #child_btn
;##############################
SetWindowData(#child_WINDOW,#False) ; child window must NOT close when losing focus to message box
SetWindowTitle(#child_WINDOW,"Remains active")
MessageRequester("Message", "something real important... or not !",$40)
; reset the window to its auto-close state
SetWindowData(#child_WINDOW,#True) ; will close when losing focus
SetWindowTitle(#child_WINDOW,"Closes spontaneously !")
;##############################
EndSelect
EndProcedure
; app's main window
Procedure Main_opened()
If OpenWindow(#main_WINDOW,#PB_Ignore,#PB_Ignore,400,300,"Main window")
ButtonGadget(#main_btn,10,10,150,30,"Show Child")
TextGadget(#main_clock,280, 20, 100, 30,
FormatDate("%hh:%ii:%ss", Date()), #PB_Text_Right)
AddWindowTimer(#main_WINDOW, #main_timer, 1000)
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Procedure Main_gadgets(gadget, eventType)
Select gadget
Case #main_btn
Child_Open()
EndSelect
EndProcedure
;- ************************************
Procedure Events_Timer()
Static currentMinute
Select EventTimer()
Case #main_timer
;updates every second
SetGadgetText(#main_clock,
FormatDate("%hh:%ii:%ss", Date()))
Case #child_timer
;updates every minute
Define thisMinute = Minute(Date())
If thisMinute <> currentMinute
currentMinute = thisMinute
SetGadgetText(#child_clock, FormatDate("%hh:%ii", Date()))
EndIf
; timer_t previously defined as global
If timer_t <= 10
SetGadgetText(#child_clock, "NotePad opens in " + timer_t + "...")
EndIf
timer_t - 1
Debug "timer_t: "+ timer_t
If timer_t = 0
RunProgram("notepad.exe")
timer_t = #timerTime ; reset timer countdown to original value
SetGadgetText(#child_clock, FormatDate("%hh:%ii", Date())) ; re-display the clock
EndIf
EndSelect
EndProcedure
Procedure Events_Gadget()
Define gadget, eventType
gadget = EventGadget()
eventType = EventType()
Select EventWindow()
Case #main_WINDOW
Main_gadgets(gadget,eventType)
Case #child_WINDOW
Child_gadgets(gadget,eventType)
EndSelect
EndProcedure
Procedure Events_window_closed()
; closing main window quits app
Debug "closing " + EventWindow()
If #main_WINDOW = EventWindow()
Debug " >>> " + #main_WINDOW + " is #main_WINDOW"
Debug "all done !"
End
Debug "never displayed ???"
EndIf
Debug " >>> " + #child_WINDOW + " is #child_WINDOW"
CloseWindow(#child_WINDOW)
EndProcedure
Procedure Events_window_deactivated()
Protected window = EventWindow()
Select window
Case #child_WINDOW
If GetWindowData(window) = #True
CloseWindow(window)
;SetActiveWindow(#main_WINDOW) ; nothing happens !
Debug " >>> has #main_WINDOW changed to activated appearance ???"
EndIf
EndSelect
EndProcedure
Procedure Events_window_activated()
Protected window = EventWindow()
Debug "ActivateWindow " + EventWindow()
Debug " >>> has window changed to activated appearance ???"
EndProcedure
BindEvent(#PB_Event_Gadget,@Events_gadget())
BindEvent(#PB_Event_Timer,@Events_timer())
BindEvent(#PB_Event_CloseWindow,@Events_window_closed())
BindEvent(#PB_Event_ActivateWindow,@Events_window_activated())
BindEvent(#PB_Event_DeactivateWindow,@Events_window_deactivated())
If Main_opened()
Repeat
WaitWindowEvent()
ForEver
EndIf
End
The code works really well, but something is missing :
Launch the app, minimize PB's IDE, just leaving the debug output window opened. When you select PB's debug output window, it takes on its activated look, while the demo changes to its deactivated look. When you return to the demo, the reverse happens : its window takes on its activated look, while the debug window looks deactivated. All normal. That's the behaviour you expect and it happens correctly with any opened window on the desktop, and with the desktop itself.
However, If you now open a child window in the demo app, and then
click into the parent window, the child window closes (as designed by code), but the parent window does not take on its activated look ! Furthermore, at line 144 of the code, the instruction
SetActiveWindow(#main_WINDOW), intended to provoke a change of appearance, produces nothing; the debug statements also clearly show that the
#PB_Event_ActivateWindow event never fires, even though it should (I think...). The parent window is expected to change its appearance to its activated colors.
Is this a PB bug ?