[Gambas-user] Dynamic Objects

Doriano Blengino doriano.blengino at ...1909...
Tue Mar 31 08:12:38 CEST 2009


Rodney Rundstrom ha scritto:
> Thanks using last.text works in this case, can you clarify how I would
> access using parent/child can a form itself be the container or my I use
> another although a similar arrangement is available in VB I am not really
> sure how to use it?
>   
The following routine iterates through all the controls inside a given 
container, recursively (included other containers), and returns its 
children one after another.

    ' Returns the i-th children of hContainer, recursively
    PUBLIC SUB ith_children_of(hContainer AS Container, i AS Integer) AS
    Object
      DIM hScan AS Object
      DIM hResult AS Object
      DIM counted AS Integer

      counted = 0
      FOR EACH hScan IN hContainer.Children
        INC counted
        DEC i
        IF i = 0 THEN RETURN hScan
        IF hScan IS Container THEN
          ' traverse it
          hResult = ith_children_of(hScan, i)
          IF hResult THEN RETURN hResult  ' function found the control
          ' function exhausted controls, but how many?
          counted += ith_controls_counted
          i -= ith_controls_counted
        ENDIF
      NEXT
      ith_controls_counted = counted
    END

In one of my apps, I use it to fill TextBoxes associating ldap field 
names to textboxes names. It is slightly more complicated than 
necessary, but it shows what is possible to do. You can pass a form as 
first parameter, which is indeed a container:

      DIM hScan AS Object
      DIM i AS Integer

      i = 0
      DO
        INC i
        hScan = ith_children_of(ME, i)
        IF NOT hScan THEN BREAK

        IF aname = "lDn" THEN hScan.text = dn

        IF object.Type(hScan) = "TextBox" OR object.Type(hScan) =
    "TextArea" THEN
          hScan.text = ""   ' default
        ELSE IF object.Type(hScan) = "Button" THEN
          IF db_is_readonly AND hScan.name = "btModify" THEN
    hScan.Visible = FALSE
          IF db_is_readonly AND hScan.name = "btDelete" THEN
    hScan.Visible = FALSE
        ENDIF
      LOOP


Here you see: I scan all the container (ME, the form where the 
subroutine resides), then I do several things depending on what I've got.
You can test for the class of the object, or its name. A useful thing to 
test for is TAG, where you can store data serving no other purposes than 
your ones.

As I said before, there is no need of such complication, I took it 
simply to show the variety of things. If you have a bunch of dynamically 
created controls scattered in a form, you can set the .Tag or .Name on 
each of them at the time of instanciation, and then use these kinds of 
routine. But if you put them all inside a single container, then you 
access them with

    for each hScan in hManyButtonsHbox.Children
      hScan.Enabled = false   ' all the children of this hBox are disabled
    next

The more effective way is to keep an array of handles when creating the 
controls, thought. I showed all this complication because you asked me 
about containers and childrens, but sometimes, especially in complex 
form, to operate this way saves time and errors.

Regards,

-- 
Doriano Blengino

"Listen twice before you speak.
This is why we have two ears, but only one mouth."





More information about the User mailing list