This document covers the following topics:
Dialog elements are usually added to a dialog by means of the dialog editor. However, they can also be created and deleted dynamically. This may be done, for example, when the layout of a dialog is strongly context-sensitive.
A dialog element is created dynamically with the ADD
action of the
PROCESS GUI
statement. This action returns a handle to the newly created
dialog element. As soon as the dialog element is created, this handle points to a set of
attributes specified for the dialog element just created.
Note
ActiveX controls are created in a slightly different way than the standard way
described below. This is described in Working with ActiveX Controls.
For more information on the actions available, and on the parameters that can be passed, see Executing Standardized Procedures.
By modifying any handle attribute operand of the form
handlename.attributename
(for example,
#PB-1.STRING
), you change an attribute value of the specific dialog
element. As long as the dialog element is not yet created and the handle variable has its
initial value (NULL-HANDLE
), the handle attribute operand
handlename.attributename refers to the global attribute
list.
The global attribute list is a collection of all attributes defined for any dialog
element. Natural contains one such collection. Whenever a dialog element is created, it
"inherits" its attributes from this global attribute list. It does not
inherit them when you create the dialog element with the PROCESS GUI
statement action ADD
using the WITH PARAMETERS
option.
To define a dialog element statically (in the dialog editor), with an individual set of attributes, you must first set the attributes in the global attribute list to the desired values and then create the dialog element. After creation, the values of the attributes in the global attribute list remain intact. The next created dialog element gets the same attributes from the global attribute list as the previous one, except those that have been modified.
The status of the global attribute list as found in the "after open" event
handler is influenced by the dialog elements defined statically. Therefore, before you
start creating dialog elements dynamically in the "after open" event handler,
you should reset the attributes by means of the PROCESS GUI
action RESET-ATTRIBUTES
to prevent your dialog elements from
inheriting unexpected values from the global attribute list. If you want to avoid this
inheritance problem, use the PROCESS GUI
statement action ADD
with the
WITH PARAMETERS
option.
Unexpected values may also result from having attribute values that mean different things
if used by different types of dialog elements. For example, the value s
of
the attribute STYLE
means "scaled" for the
dialog element type bitmap control but "solid" for the dialog element type
line control.
The PROCESS GUI
action ADD
is used to define a dialog element
dynamically. This clause of the PROCESS GUI
statement enables you to specify
the attribute values within the statement. The inheritance of attributes from the global
attribute list does not affect the PROCESS GUI
statement action ADD
. The
attributes specified in the statement are transferred to the global attribute list before
the action ADD
is performed.
Note
When you use the PROCESS GUI
statement with Parameter Clause 2 of the
ADD
action, the global attribute list is not used or affected. For parameters which are needed
to create the dialog element, but which were not specified in the WITH
PARAMETERS
section of the PROCESS GUI
action ADD
statement,
the default value is taken. Apart from these, only the parameters which are passed
explicitly in the parameter list are used to create the dialog element.
To create list-box and selection-box items dynamically, it may be more convenient to use
the PROCESS GUI
action ADD-ITEMS
. This allows you to insert several items
at a time.
Example:
/* #PB-A inherits the current settings of the global attribute list #PB-A.STRING := 'TEST1' PROCESS GUI ACTION ADD WITH #DLG$WINDOW PUSHBUTTON #PB-A #PB-B.STRING := 'TEST2' /* #PB-B has the same attributes as #PB-A except STRING. This leads to #PB-B /* covering #PB-A. PROCESS GUI ACTION ADD WITH #DLG$WINDOW PUSHBUTTON #PB-B COMPUTE #PB-C.RECTANGLE-Y = #PB-B.RECTANGLE-Y + #PB-C.RECTANGLE-H + 20 /* #PB-B has the same attributes as #PB-A except RECTANGLE-Y /* #PB-C will be located 20 pixels below #PB-B PROCESS GUI ACTION ADD WITH #DLG$WINDOW PUSHBUTTON #PB-C
To delete dialog elements dynamically, you use the PROCESS GUI
action
DELETE
. You can also use this technique to delete dialog
elements created with the dialog
editor (at design time). You should, however, avoid using the handle of the
deleted dialog element because this is invalid.
Dialog elements often do not have to be created dynamically. In some cases, it is
sufficient to make dialog elements VISIBLE = TRUE
and VISIBLE =
FALSE
, depending on the context. This technique is more
efficient and easier to handle. It also enables you to "insert" dialog
elements anywhere in the navigation sequence.
Example:
DEFINE DATA LOCAL ... 1 #PB-1 HANDLE OF PUSHBUTTON ... END-DEFINE ... #PB-1.VISIBLE := FALSE ... IF... /* Logical condition #PB-1.VISIBLE := TRUE END-IF
When a dialog element is created dynamically, you cannot use the dialog editor to associate
events to it. Instead, you must handle all events of all dynamically created dialog
elements in the DEFAULT
event. In this event, you must filter out which event
occurred for which dialog element. The code for this is similar to the code generated by
the dialog editor. The
general structure is:
Example:
DECIDE ON FIRST *CONTROL VALUE #PB-A DECIDE ON FIRST *EVENT VALUE 'CLICK' /* Click event-handler code NONE IGNORE END-DECIDE VALUE #PB-B ... VALUE #PB-C ... END-DECIDE
In the case of event code for dynamically created ActiveX controls, where event
parameters are used, it is necessary to precede the event code with an
OPTIONS 2
statement containing the name of the event, otherwise the
compiler will not be able to process parameter references (e.g.,
#OCX-1.<<PARAMETER-...>>
) successfully. However, in contrast to
the implicit generation of the OPTIONS
statement by the dialog editor for events for
statically created controls, no OPTIONS 3
statement should be coded in this
case. Otherwise the dialog
editor would falsely interpret the OPTIONS 3
statement as the
end marker for the DEFAULT
event, resulting in a scanning error on attempting to
load the dialog.
Example:
DECIDE ON FIRST *CONTROL VALUE #OCX-1 /* MS Calendar control DECIDE ON FIRST *EVENT VALUE '-602' /* DispID for KeyDown event OPTIONS 2 KeyDown /* KeyDown event-handler code containing parameter /* access (e.g. #OCX-1.<<parameter-shift>>) NONE IGNORE END-DECIDE ... END-DECIDE