` Printed Icetips Article

Icetips Article



Par2: Using queues to dynamically create controls
1998-07-13 -- Arnor Baldvinsson
 
...
>> I always use queues to maintain dynamically created
>> controls.

Now, let me see - not sure if it's easier to write it up in English or
Clarion - maybe I just send you the couple of thousand lines of C4
code

Let's say you need to dynamically create buttons that call external
programs on a window.  You don't know at design time, how many buttons
you need to create, all you know is that the information about what to
do and what icon file to use, if specified etc.  How could you handle
that without a queue.  Well, you could set up an array to hold the
references to the created controls.  So you write the code using an
array of 20 buttons.  Those that aren't used, are just left empty.  On
a nice morning, sometime around Christmas you boss tells you that you
need to be able to handle 30 more buttons.  You spend the day before
Christmas going through those nicely formatted lines looping through
the array or hard code reference to it, cursing yourself for not
having put it into a queue  

For flexibility the queue offers much more than the static arrays and
you get no benefits from using arrays.  They are not faster than
queues (maybe if you are looping through them billions of times, but
you'd need a few square miles of windows for that anyway)

Now, let's take a small example:

System{Prop:DeferMove} = -1
Loc:ID = LastField()+1
Loc:FirstField = Loc:ID
Free(Loc:ControlQ)
Set(Buttons)
Loop
   Next(Buttons)
   If ErrorCode()
     Break
   End
   Loc:CQControl  = Create(Loc:ID,CREATE:Button)
   Loc:CQNumber   = BUT:ButtonID
   Add(Loc:ControlQ,Loc:CQControl)
   Get(Loc:ControlQ,X#)
   Loc:CQControl{Prop:Xpos} = 10
   Loc:CQControl{Prop:Ypos} = Loc:ID * 20
   If BUT:Icon
     Loc:CQControl{Prop:Icon} = BUT:Icon
   Else
     If BUT:Program
       Loc:CQControl{Prop:Icon} = Clip(BUT:Program) & '[ 0 ]'
     End
   End
   Loc:CQControl{Prop:Hide} = False
   Loc:ID        += 1
End
Loc:LastField = Loc:ID-1 ! Subtract the one added just before it broke out.
System{Prop:DeferMove} = 0

Now what?  Now you have the controls created and displayed in the
correct positions (well, lets say that at least;)  What happens when
the user presses the button?  Nothing!  So, what do you do?  Well, you
need to process these buttons just like any other control on the
window.  Here, the queue really becomes useful:

Case Event()
Of Event:Accepted
   If Inrange(Field(),Loc:FirstField, Loc:LastField)
     ! We know now we are processing "our" buttons
     Loc:CQControl = Field()
     Get(Loc:ControlQ,Loc:CQControl)
     BUT:ButtonID = Loc:CQNumber
     Get(Buttons,BUT:ButtonIDKey)
     If Not ErrorCode()
       Loc:Program = BUT:Program
       Loc:Param   = ''
       Loc:OpenMode = 'open'       
       X# = ShellExecute(Loc:Program,Loc:Param,Loc:OpenMode,SW_Normal)
     Else
       Message('Debug.  Button not found - this message should never show')
     End
   End ! Event:Accepted
End ! Case
    
Now, IF you can beat this with some other structure than a queue, I
sure would like to know  Remember this is typed directly into my
news reader, not from clarion code and there are obviously a few
things missing like the file declaration etc., but bascially this is
very much like the code I have in several programs to control the
creation and handling of buttons.  For other controls there are
obviously other things to look into.



Printed May 3, 2024, 3:34 am
This article has been viewed/printed 35119 times.