Widget Pools.One cause of crashes, in any programming language, is the creation of dynamic objects that are not ultimately deleted. The buildup of these dynamic objects that are not cleaned up, causes memory leaks. If the memory leaks go on for long enough,system memory is depleted and a crash ensues. A tool to assist in the management of dynamic objects is the WIDGET-POOL. This is an area in memory, in which, dynamic objects are created. When the WIDGET-POOL is deleted, all objects in the WIDGET-POOL are cleaned up. In essence, a WIDGET-POOL provides a means of treating the objects as a set. Deleting the WIDGET-POOL deletes all objects contained therein.
WIDGET-POOLS are very useful for user interface work. In fact, the AppBuilder automatically inserts a CREATE WIDGET-POOL statement in any new window created
.
Example demonstrating the general use of a WIDGET-POOL:
/* r-widpl.p */
DEFINE VARIABLE wh AS WIDGET-HANDLE.
DEFINE BUTTON b_create LABEL "Create Button".
DEFINE BUTTON b_del LABEL "Delete Buttons".
DEFINE BUTTON b_quit LABEL "Quit"
TRIGGERS:
ON CHOOSE DO:
IF VALID-HANDLE(wh) THEN DELETE WIDGET-POOL "new-buttons".
QUIT.
END.
END.
DEFINE FRAME butt-frame
b_create b_del b_quit WITH ROW SCREEN-LINES - 2.
DEFINE FRAME new-buttons WITH SIZE 76 BY 11 CENTERED ROW 2 TITLE "New Buttons".
ON CHOOSE OF b_create IN FRAME butt-frame DO:
STATUS INPUT "Press RETURN to select a new button".
IF wh = ? OR NOT VALID-HANDLE(wh) THEN
CREATE WIDGET-POOL "new-buttons" PERSISTENT.
CREATE BUTTON wh IN WIDGET-POOL "new-buttons"
ASSIGN FRAME = FRAME new-buttons:HANDLE
ROW = RANDOM(2, 9)
COLUMN = RANDOM(2, 58)
LABEL = "BUTTON " + STRING(etime)
SENSITIVE = TRUE
VISIBLE = TRUE
TRIGGERS:
ON CHOOSE PERSISTENT RUN dispmsg.
END.
END.
ON CHOOSE OF b_del IN FRAME butt-frame DO:
IF VALID-HANDLE(wh) THEN
DELETE WIDGET-POOL "new-buttons".
STATUS INPUT.
END.
ENABLE b_create b_del b_quit WITH FRAME butt-frame.
DO ON ENDKEY UNDO, LEAVE:
WAIT-FOR CHOOSE OF b_quit IN FRAME butt-frame.
END.
IF VALID-HANDLE(wh)
THEN DELETE WIDGET-POOL "new-buttons".
PROCEDURE dispmsg:
MESSAGE "You chose button " SELF:LABEL.
END.
Please note, relative to the code example above. Notice that the code IF wh = ? OR NOT VALID-HANDLE(wh) is used to check for the existence of the WIDGET-POOL. There is not an explicit handle object with which one can check for the existence of the WIDGET-POOL. Instead, the code checks for the existence of one of the objects created within the WIDGET-POOL. Also note that unnamed WIDGET-POOLS disappear when the program in which they were created, exits or goes out of scope. It becomes easy to make handles invalid unintentionally.
Example demonstrating the inadvertent and premature deletion of a WIDGET-POOL:
RUN procedure.p PERSISTENT SET hProc.
RUN GetTable (OUTPUT hBuffer) IN hProc.
DELETE PROCEDURE hProc. /* hBuffer handle not anymore valid */
/* procedure.p */
CREATE WIDGET-POOL.
PROCEDURE GetTable:
CREATE BUFFER(....).
HBuffer = ....
END
Please see
https://docs.progress.com/bundle/openedge-oo-abl-develop-applications-122/page/Use-widget-pools.html for additional details relative to using widget-pools with object oriented programs.