GetParent() - (Windows Only)

Share your advanced PureBasic knowledge/code with the community.
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

GetParent() - (Windows Only)

Post by ChrisR »

GetParent() to Retrieves the PB Parent Gadget or PB Parent Window number.
It is the equivalent of the GetParent and GetAncestor windows API functions but for PB Gadget and PB Window number.
And also, Count the number of Children's Gadgets or GrandChildren.
But the main reason of this code for me, is the possibility to read Hierarchically the Children And GrandChildren of a Window or a Container Gadget.



Available functions:
  • GetParent(#Gadget) : Retrieves the Parent Window Number or the Parent Gadget Number
  • GetWindowRoot(#Gadget) : Retrieves the Root Parent Window Number
  • GetParentID(#Gadget) : Retrieves the Parent WindowID or the Parent GadgetID
  • ParentIsWindow(#Gadget) : Is the Parent a Window
  • ParentIsGadget(#Gadget) : Is the Parent a Gadget
  • CountChildGadget(#Parent[, GrandChildren = #False]) : Count Child Gadget. Call with #True as 2nd parameter to also count Grand Children
  • EnumChildTemplate(#Gadget) : A template to list hierarchically the child gadgets

Code: Select all

; -------------------------------------------------------------------------------------------------
;        Name: GetParent.pbi
; Description: Get the PB Parent Gadget or PB Window Number. Get the specified Window Root for a Gadget. Count the number of Children's Gadgets or GrandChildren.
;              And also, the main reason for this code, is the possibility to read Hierarchically the Children And GrandChildren of a Window or a Container Gadget.
;      Author: ChrisR
;        Date: 2022-04-16
;  PB-Version: 5.73 x64/x86
;          OS: Windows Only.
;       Forum: https://www.purebasic.fr/english/viewtopic.php?t=79004
; -------------------------------------------------------------------------------------------------
;-  Usage:
;-
;   GetParent(#Gadget)                                    : Get the Parent Window Number or the Parent Gadget Number
;
;   GetWindowRoot(#Gadget)                                : Get the Root Parent Window Number 
;
;   GetParentID(#Gadget)                                  : Get the Parent WindowID or the Parent GadgetID
;
;   ParentIsWindow(#Gadget)                               : Is the Parent a Window
;
;   ParentIsGadget(#Gadget)                               : Is the Parent a Gadget
;
;   CountChildGadget(#Parent[, GrandChildren = #False])   : Count Child Gadget. Call with #True as 2nd parameter to also Count Grand Children 
;
;   EnumChildTemplate(#Gadget)                            : A template to list Hierarchically the Child and GrandChildren Gadgets
;
; -------------------------------------------------------------------------------------------------

EnableExplicit

Global Dim Window(1, 0)
Global CountWindow

Structure StObject
  Level.i             ; If = 1, Parent Is a Window Else a Gadget
  ObjectID.i
  IsContainer.b
  ParentObject.i
  ParentObjectID.i
  GParentObjectID.i   ; Temporary Loaded For Child of ScrollArea and Panel, it is then reset to 0 
EndStructure
Global NewMap Object.StObject()

Import ""
  PB_Object_EnumerateAll(Object, *Object, ObjectData)
  PB_Object_Count(PB_Gadget_Objects)
  PB_Gadget_Objects.i
  PB_Window_Objects.i
EndImport

;- ----- Private -----

Procedure IsContainer(Gadget)
  ; Procedure IsContainer(Cross-platform) based on procedure IsCanvasContainer by mk-soft here: https://www.purebasic.fr/english/viewtopic.php?t=79002
  Select GadgetType(Gadget)
    Case #PB_GadgetType_Container, #PB_GadgetType_Panel, #PB_GadgetType_ScrollArea
      ProcedureReturn #True
    Case #PB_GadgetType_Canvas
      CompilerSelect #PB_Compiler_OS
        CompilerCase #PB_OS_Windows
          If GetWindowLongPtr_(GadgetID(Gadget), #GWL_STYLE) & #WS_CLIPCHILDREN
            ProcedureReturn #True
          EndIf
        CompilerCase #PB_OS_MacOS
          Protected sv, count
          sv    = CocoaMessage(0, GadgetID(Gadget), "subviews")
          count = CocoaMessage(0, sv, "count")
          ProcedureReturn count
        CompilerCase #PB_OS_Linux
          Protected GList, count
          GList = gtk_container_get_children_(GadgetID(Gadget))
          If GList
            count = g_list_length_(GList)
            g_list_free_(GList)
            ProcedureReturn count
          EndIf
      CompilerEndSelect
  EndSelect
ProcedureReturn #False
EndProcedure
    
Procedure WindowCB(Window, *Window, WindowData)
  Window(0, CountWindow) = Window
  Window(1, CountWindow) = WindowID(Window)
  CountWindow + 1
  ProcedureReturn #True
EndProcedure

Procedure ObjectCB(Object, *Object, ObjectData)
  With Object(Str(Object))
    \ObjectID        = GadgetID(Object)
    \IsContainer     = IsContainer(Object)
    ; For 
    \ParentObjectID  = GetParent_(\ObjectID)
    \GParentObjectID = GetParent_(\ParentObjectID)
  EndWith
  ProcedureReturn #True
EndProcedure

Procedure CleanUpGParent(ObjectID, Level)
  Protected ParentObjectID
  PushMapPosition(Object())
  ResetMap(Object())
  With Object()
    While NextMapElement(Object())
      If \Level <> Level + 1 : Continue : EndIf
      If \ParentObjectID = ObjectID
        \GParentObjectID  = 0
      ElseIf \GParentObjectID = ObjectID
        \ParentObjectID   = ObjectID
        \GParentObjectID  = 0
      EndIf
    Wend
  EndWith
  PopMapPosition(Object())
EndProcedure

Procedure WinHierarchy(ParentObjectID, ParentObject, FirstPassDone = #False)
  Static Level
  Protected ObjectType
  If FirstPassDone = #False
    Level          = 0
    FirstPassDone  = #True
  EndIf
  
  Level + 1
  PushMapPosition(Object())
  ResetMap(Object())
  With Object()
    While NextMapElement(Object())
      If IsGadget(ParentObject) : ObjectType = GadgetType(ParentObject) : Else : ObjectType = 0 : EndIf
      If \ParentObjectID = ParentObjectID Or (\GParentObjectID = ParentObjectID And ObjectType & (#PB_GadgetType_Panel | #PB_GadgetType_ScrollArea))
        \Level        = Level
        \ParentObject = ParentObject
        If \IsContainer
          WinHierarchy(\ObjectID, Val(MapKey(Object())), FirstPassDone)
          Level - 1
        EndIf
      EndIf
    Wend
  EndWith
  PopMapPosition(Object())
EndProcedure

Procedure LoadObject()
  Protected I
  CountWindow = PB_Object_Count(PB_Window_Objects)
  ReDim Window(1, CountWindow - 1)
  CountWindow = 0
  PB_Object_EnumerateAll(PB_Window_Objects, @WindowCB(), 0)
  PB_Object_EnumerateAll(PB_Gadget_Objects, @ObjectCB(), 0)
  
  If MapSize(Object()) > 0
    ; Pass through the hierarchy for each window
    For I = 0 To ArraySize(Window(), 2)
      WinHierarchy(Window(1, I), Window(0, I))
    Next
    ; CleanUp ParentObject vs GParentObject
    ResetMap(Object())
    With Object()
      While NextMapElement(Object())
        If Object()\IsContainer
          CleanUpGParent(Object()\ObjectID, Object()\Level)
        EndIf
      Wend
    EndWith
  Else 
    ProcedureReturn #False
  EndIf
  ProcedureReturn #True
EndProcedure
;- ----- Private -----

;-
;- ----- Public -----
Procedure GetParent(Gadget)
  If MapSize(Object()) = 0 : LoadObject() : EndIf
  If FindMapElement(Object(), Str(Gadget))
    ProcedureReturn Object(Str(Gadget))\ParentObject
  EndIf
  ProcedureReturn #PB_Default
EndProcedure

Procedure GetWindowRoot(Gadget)
  If MapSize(Object()) = 0 : LoadObject() : EndIf
  If FindMapElement(Object(), Str(Gadget))
    If Object(Str(Gadget))\Level = 1
      ProcedureReturn Object(Str(Gadget))\ParentObject
    Else
      Gadget = Object(Str(Gadget))\ParentObject
    EndIf 
  Else
    ProcedureReturn #PB_Default
  EndIf
  
  Repeat
    If FindMapElement(Object(), Str(Gadget))
      Gadget = Object(Str(Gadget))\ParentObject
    EndIf
  Until Object(Str(Gadget))\Level = 1
  ; Parent of Level 1 is the Window Root
  If FindMapElement(Object(), Str(Gadget))
    Gadget   = Object(Str(Gadget))\ParentObject
  EndIf
  
  ProcedureReturn Gadget
EndProcedure

Procedure GetParentID(Gadget)
  If MapSize(Object()) = 0 : LoadObject() : EndIf
  If FindMapElement(Object(), Str(Gadget))
    If Object(Str(Gadget))\Level = 1
      ProcedureReturn WindowID(Object(Str(Gadget))\ParentObject)
    Else
      ProcedureReturn GadgetID(Object(Str(Gadget))\ParentObject)
    EndIf
  EndIf
  ProcedureReturn #PB_Default
EndProcedure

Procedure ParentIsWindow(Gadget)
  If MapSize(Object()) = 0 : LoadObject() : EndIf
  If FindMapElement(Object(), Str(Gadget))
    If Object(Str(Gadget))\Level = 1
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
  ProcedureReturn #PB_Default
EndProcedure

Procedure ParentIsGadget(Gadget)
  If MapSize(Object()) = 0 : LoadObject() : EndIf
  If FindMapElement(Object(), Str(Gadget))
    If Object(Str(Gadget))\Level > 1
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
  ProcedureReturn #PB_Default
EndProcedure

Procedure CountChildGadget(ParentObject, GrandChildren = #False, FirstPassDone = #False)
  Static Level, Count
  If FirstPassDone = 0
    If MapSize(Object()) = 0 : LoadObject() : EndIf
    If IsWindow(ParentObject)
      Level = 0
    ElseIf IsGadget(ParentObject)
      If FindMapElement(Object(), Str(ParentObject))
        If Not(Object(Str(ParentObject))\IsContainer) : ProcedureReturn #PB_Default : EndIf
        Level = Object(Str(ParentObject))\Level
      EndIf
    Else
      ProcedureReturn #PB_Default
    EndIf
    Count = 0
    FirstPassDone = #True
  EndIf
  
  Level + 1
  PushMapPosition(Object())
  ResetMap(Object())
  With Object()
    While NextMapElement(Object())
      If \Level = Level And \ParentObject = ParentObject
        Count + 1
        If GrandChildren And \IsContainer
          CountChildGadget(Val(MapKey(Object())), GrandChildren, FirstPassDone)
          Level - 1
        EndIf
      EndIf
    Wend
  EndWith
  PopMapPosition(Object())
  ProcedureReturn Count
EndProcedure

Procedure EnumChildTemplate(ParentObject, FirstPassDone = #False)
  Static Level
  If FirstPassDone = 0
    If MapSize(Object()) = 0 : LoadObject() : EndIf
    If IsWindow(ParentObject)
      Level = 0
      Debug "Enum Child Gadget of Window " + LSet(Str(ParentObject), 10) + "|  WindowID " + LSet(Str(WindowID(ParentObject)), 10) + "(Level = 0)"
    ElseIf IsGadget(ParentObject)
      If FindMapElement(Object(), Str(ParentObject))
        If Not(Object(Str(ParentObject))\IsContainer) : ProcedureReturn #PB_Default : EndIf
        Level = Object(Str(ParentObject))\Level
        Debug "Enum Child Gadget of Gadget " + LSet(Str(ParentObject), 10) + "|  GadgetID " + LSet(Str(GadgetID(ParentObject)), 10) + "(Level = " + Str(Level) + ")"
      EndIf
    Else
      ProcedureReturn #PB_Default
    EndIf
    FirstPassDone = #True
  EndIf
  
  Level + 1
  PushMapPosition(Object())
  ResetMap(Object())
  With Object()
    While NextMapElement(Object())
      If \Level = Level And \ParentObject = ParentObject
        Debug LSet("", \Level*3 , " ") + "Gadget " + LSet(MapKey(Object()), 10) + "ParentGadget " + LSet(Str(\ParentObject), 10)  + "|  GadgetID " + LSet(Str(\ObjectID), 10) + "ParentGadgetID " + LSet(Str(\ParentObjectID), 10) + "(Level = " + Str(\Level) + ")"
        If \IsContainer
          EnumChildTemplate(Val(MapKey(Object())), FirstPassDone)
          Level - 1
        EndIf
      EndIf
    Wend
  EndWith
  PopMapPosition(Object())
EndProcedure

;- ----- Public -----
;-
;- ----- Demo -----
CompilerIf (#PB_Compiler_IsMainFile)
  
  Enumeration Window
    #Window_1
  EndEnumeration
  
  Enumeration Gadgets
    #ScrollArea_1
    #CanvasContainer_1
    #Panel_1
    #Button_1
    #Button_3
    #Button_4
    #Button_5
  EndEnumeration
  
  Global Container_1, Button_2
  Global Window_2, SubPanel_2, Button_6
  
  Procedure Open_Window_2(X = 480, Y = 20, Width = 440, Height = 380)
    Window_2 = OpenWindow(#PB_Any, X, Y, Width, Height, "Window_2  (#PB_Any)", #PB_Window_SystemMenu)
    If Window_2
      PanelGadget(#Panel_1, 20, 20, 400, 270)
      AddGadgetItem(#Panel_1, -1, "Tab_1  (2)")
      SubPanel_2 = PanelGadget(#PB_Any, 20, 20, 350, 190)
      AddGadgetItem(SubPanel_2, -1, "SubTab_1  (#PB_Any)")
      ButtonGadget(#Button_5, 20, 20, 200, 50, "Button_5  (6)")
      AddGadgetItem(SubPanel_2, -1, "SubTab_2  (#PB_Any)")
      CloseGadgetList()   ; SubPanel_2
      AddGadgetItem(#Panel_1, -1, "Tab_2  (2)")
      ButtonGadget(#Button_4, 30, 30, 200, 50, "Button_4  (5)")
      CloseGadgetList()   ; #Panel_1
      Button_6 = ButtonGadget(#PB_Any, 20, 310, 200, 50, "Button_6  (#PB_Any)")
    EndIf
  EndProcedure
  
  Procedure Open_Window_1(X = 20, Y = 20, Width = 440, Height = 380)
    If OpenWindow(#Window_1, X, Y, Width, Height, "Window_1  (0)", #PB_Window_SystemMenu)
      ScrollAreaGadget(#ScrollArea_1, 20, 20, 400, 270, 1200, 800, 10, #PB_ScrollArea_Raised)
      CanvasGadget(#CanvasContainer_1, 20, 20, 330, 160, #PB_Canvas_Border | #PB_Canvas_Container)
      Container_1 = ContainerGadget(#PB_Any, 20, 20, 290, 110, #PB_Container_Raised)
      ButtonGadget(#Button_1, 20, 20, 200, 50, "Button_1  (3)")
      CloseGadgetList()   ; Container_1
      CloseGadgetList()   ; #CanvasContainer_1
      Button_2 = ButtonGadget(#PB_Any, 20, 200, 200, 50, "Button_2  (#PB_Any)")
      CloseGadgetList()   ; #ScrollArea_1
      ButtonGadget(#Button_3, 20, 310, 200, 50, "Button_3  (4)")
    EndIf
  EndProcedure
   
  Open_Window_1()
  Open_Window_2()
  
  ;- ----- Debug -----
  EnumChildTemplate(#Window_1)
  Debug "" : Debug "--------------------------------------------------------------------------------" : Debug ""
  Debug "#Window_1 : " + Str(#Window_1)
  Debug "Count Child Gadget of #Window_1 : " + Str(CountChildGadget(#Window_1))
  Debug "Count Child + GrandChildren Gadget of #Window_1 : " + Str(CountChildGadget(#Window_1, #True))
  Debug ""
  Debug "Parent of #ScrollArea_1 : " + LSet(Str(GetParent(#ScrollArea_1)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#ScrollArea_1)) + ", IsGadget=" + Str(ParentIsGadget(#ScrollArea_1)) + ")"
  Debug "Parent of #CanvasContainer_1 : " + LSet(Str(GetParent(#CanvasContainer_1)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#CanvasContainer_1)) + ", IsGadget=" + Str(ParentIsGadget(#CanvasContainer_1)) + ")"   
  Debug "Parent of Container_1 : " + LSet(Str(GetParent(Container_1)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(Container_1)) + ", IsGadget=" + Str(ParentIsGadget(Container_1)) + ")"
  Debug "Parent of #Button_1 : " + LSet(Str(GetParent(#Button_1)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#Button_1)) + ", IsGadget=" + Str(ParentIsGadget(#Button_1)) + ")"
  Debug "Parent of Button_2 : " + LSet(Str(GetParent(Button_2)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(Button_2)) + ", IsGadget=" + Str(ParentIsGadget(Button_2)) + ")"
  Debug "Parent of #Button_3 : " + LSet(Str(GetParent(#Button_3)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#Button_3)) + ", IsGadget=" + Str(ParentIsGadget(#Button_3)) + ")"
  Debug ""
  Debug "Window Root of #Button_1 : " + Str(GetWindowRoot(#Button_1))
  Debug "" : Debug "--------------------------------------------------------------------------------" : Debug ""
  
  EnumChildTemplate(Window_2)
  Debug "" : Debug "--------------------------------------------------------------------------------" : Debug ""
  Debug "Window_2 : " + Str(Window_2)
  Debug "Count Child Gadget of Window_2 : " + Str(CountChildGadget(Window_2))
  Debug "Count Child + GrandChildren Gadget of Window_2 : " + Str(CountChildGadget(Window_2, #True))
  Debug ""
  Debug "Parent of #Panel_1 : " + LSet(Str(GetParent(#Panel_1)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#Panel_1)) + ", IsGadget=" + Str(ParentIsGadget(#Panel_1)) + ")"
  Debug "Parent of SubPanel_2 : " + LSet(Str(GetParent(SubPanel_2)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(SubPanel_2)) + ", IsGadget=" + Str(ParentIsGadget(SubPanel_2)) + ")"
  Debug "Parent of #Button_5 : " + LSet(Str(GetParent(#Button_5)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#Button_5)) + ", IsGadget=" + Str(ParentIsGadget(#Button_5)) + ")"
  Debug "Parent of #Button_4 : " + LSet(Str(GetParent(#Button_4)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(#Button_4)) + ", IsGadget=" + Str(ParentIsGadget(#Button_4)) + ")"
  Debug "Parent of Button_6 : " + LSet(Str(GetParent(Button_6)), 10) + "(Parent: IsWindow=" + Str(ParentIsWindow(Button_6)) + ", IsGadget=" + Str(ParentIsGadget(Button_6)) + ")"
  Debug ""
  Debug "Window Root of #Button_5 : " + Str(GetWindowRoot(#Button_5))
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
CompilerEndIf
Last edited by ChrisR on Wed Apr 20, 2022 1:49 pm, edited 13 times in total.
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GetParent() and more (CrossPlatform)

Post by Shardik »

ChrisR wrote: Sun Apr 17, 2022 4:57 pm I only use Windows but it should work on Mac and Linux as well.
No, it currently doesn't work on Linux and MacOS because you still use the Windows API function GetParent_() in the procedure ObjectCB().
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: GetParent() and more (CrossPlatform)

Post by ChrisR »

Damn. I screwed up in my search "_("
So Windows only.
From my phone
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

GetParent() - (Windows and probably Linux)

Post by ChrisR »

It is probably good for Linux but I haven't tested. I don't use but It would be good to install a distro in VM.
I had tried to install macOS 11.0 Big Sur Beta in VMware, but it was not usable, really too slowww.

I added the function:
CountChildGadget(#Parent[, GrandChildren = #False]) : Count Child Gadget. Call with #True as 2nd parameter to also count Grand Children.
mestnyi
Addict
Addict
Posts: 999
Joined: Mon Nov 25, 2013 6:41 am

Re: GetParent() - (Windows and probably Linux)

Post by mestnyi »

User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: GetParent() - (CrossPlatform!)

Post by ChrisR »

Thanks mestnyi, I added your code to get the parent for MacOS.
I don't like to do without being able to check so I'm waiting for a confirmation for Linux and MacOS.
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: GetParent() - (CrossPlatform!)

Post by mk-soft »

You have remove procedure NSView and GetClass

macOS:
GetParent not work on PanelGadget. Only the active Tab has a superview. Its macOS internal.

Linux:
Is not complete, sometime need parent of parent

Perhaps help this updated code:
Link: GetParentGadget
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: GetParent() - (CrossPlatform!)

Post by ChrisR »

um, I wanted to add it a little quickly last night without looking at the full code, I shouldn't have.
Thanks for the info on the TabGadget in MacOS, so it's not possible anyway without switching tabs...
Well, I will give up for MacOS and in a general way, better not to try to do if I can't test.

And your optimised GetParentGadget, meets the need for most cases anyway without the need to go further.
For my needs (windows only), in addition to GetParent, I also need the hierarchical list to browse the childrens and grandchildrens of a window or container, the reason for my code here.
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: GetParent() - (CrossPlatform!)

Post by ChrisR »

mk-soft wrote: Tue Apr 19, 2022 10:51 am Linux:
Is not complete, sometime need parent of parent
Same thing, I shouldn't do it without being able to test.
However, it is already done on 2 levels in ObjectCB currently: Parent and Grand-Parent.
Then I keep only the right one, no matter if it is a window or a Gadget container (even with the same number eg: 0).
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: GetParent() - (CrossPlatform!)

Post by mk-soft »

Depends on the gadget. Sometimes the third parent is the right gadget. Therefore, I search backwards until a valid gadget is found.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: GetParent() - (Windows Only)

Post by ChrisR »

Thanks mk-soft,
I give up for MacOS and Linux, so it is Windows Only.
Your GetParentGadget meets most needs so I won't go any further :wink:

As a reminder: the main reason for this code (in addition to GetParent, GetWindowRoot or CountChildGadget) is the possibility to read Hierarchically the Children And GrandChildren of a Window or a Container Gadget. To be able to send infos, such as the background Color for example, from a Parent to its Childrens.
Post Reply