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 November 21, 2024, 11:51 am
This article has been viewed/printed 35203 times.