Progress Programming Tips
By Rod Gaither (rdg@worldinfo.com)
PPT-5 Walking the Widget Tree
Tip:
With the advent of widgets Progress began opening up the door
to dynamic operations other than the old RUN VALUE() statement.
Since many attributes can be affected from the widget-handle of a
widget you now have the opportunity to customize some display and
behaviour characteristics of widgets at run time. One tool everyone
should have available is a procedure to traverse the widget tree of
widget handles. The sample included below is designed to accomplish
several things.
1. Traverse the tree from starting point X.
2. Only affect widgets by name and type
3. Run the passed in procedure for each selected widget
---- Code insert begins ----
PROCEDURE widget-walk :
/*--------------------------------------------------------------------
----------
Purpose: Walks the widget tree to various purposes
Parameters: Starting widget handle, run procedure info
Notes: Requires run procedure to have the following
parameters - (INPUT widget-handle, INPUT character)
p-start Start traversal with this widget, usually a frame
p-run Name of the internal procedure to run for each widget
p-in Handle of program to run the internal procedure in
p-pass A parameter the caller can set to pass to the IP
p-types Only affect these types of widgets - selection criteria
p-name The list of widget names to be affected
----------------------------------------------------------------------
--------*/
DEFINE INPUT PARAMETER p-start AS WIDGET-HANDLE NO-UNDO.
DEFINE INPUT PARAMETER p-run AS CHAR NO-UNDO.
DEFINE INPUT PARAMETER p-in AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER p-pass AS CHAR NO-UNDO.
DEFINE INPUT PARAMETER p-types AS CHAR NO-UNDO.
DEFINE INPUT PARAMETER p-names AS CHAR NO-UNDO.
DEF VAR t-wh AS WIDGET-HANDLE NO-UNDO.
DEF VAR t-name AS CHAR NO-UNDO.
DEF VAR l-loop AS LOGICAL NO-UNDO.
DEF VAR l-down AS LOGICAL NO-UNDO.
ASSIGN
t-wh = p-start
l-loop = (IF VALID-HANDLE(t-wh) THEN TRUE ELSE FALSE)
l-down = TRUE.
BLK-MAIN:
DO WHILE l-loop:
/***[ Execute current item ]***/
/* setup the name portion for checking */
/* may want this to be an internal procedure to deal with prefixes
*/ ASSIGN t-name = p-wh:NAME.
/***[ Do type and name checking then execute internal procedure
]***/
IF l-down AND (IF p-types <> "" THEN CAN-DO(p-types,t-wh:TYPE)
ELSE TRUE)
AND (IF p-names <> "" THEN CAN-DO(p-names,t-name) ELSE TRUE)
THEN RUN VALUE(p-run) IN p-in (INPUT t-wh, INPUT p-pass) NO-ERROR.
/***[ Try to go down first - only on first time ]***/
IF CAN-QUERY(t-wh,"FIRST-CHILD")
AND VALID-HANDLE(t-wh:FIRST-CHILD)
AND l-down
THEN ASSIGN t-wh = t-wh:FIRST-CHILD
l-down = TRUE.
/***[ If down not an option try sideways ]***/
ELSE IF VALID-HANDLE(t-wh:NEXT-SIBLING)
THEN ASSIGN t-wh = t-wh:NEXT-SIBLING
l-down = TRUE.
/***[ If not down or sideways then go back up ]***/
/***[ If up is back to top then signal exit ]***/ ELSE
IF t-wh:PARENT = p-start
THEN ASSIGN t-wh = p-start
l-loop = FALSE.
/***[ Go up but look sideways ]***/
ELSE ASSIGN t-wh = t-wh:PARENT
l-down = FALSE.
END. /***[ End of DO WHILE ]***/
END PROCEDURE.
---- Code insert ends ----
Wisdom:
Just because you CAN do something doesn't always mean you SHOULD.
Rod Gaither | rdg@worldinfo.com
World Information Systems | (910) 333-2580 Voice
Greensboro, NC | (910) 333-2584 Fax