Another way to manage the memory dynamic objects use is through widget pools. A widget pool is a pool of run-time memory that dynamic objects are created in. Every dynamic object you create is assigned to a widget pool.

The AVM creates a single unnamed widget pool for each client session. This session pool is the default pool for all dynamic objects created during the session. It is automatically deleted when the session ends.

You can also create your own widget pools with the CREATE WIDGET-POOL statement:

CREATE WIDGET-POOL [ pool-name [ PERSISTENT ] ] [ NO-ERROR ] .

If you do not specify a pool-name, then you create an unnamed widget pool. Any dynamic objects you create are then assigned, by default, to the most recently created unnamed widget pool. The scope of the pool is the scope of the procedure that created it. When that procedure terminates, the widget pool is deleted along with all the dynamic objects that were created in it. This can be a very simple and powerful way of handling much of your memory management of dynamic objects. In fact, the standard template the AppBuilder uses for a window procedure puts this statement at the top of every window procedure you create:

/* Create an unnamed pool to store all the widgets created
  by this procedure. This is a good default which assures
  that this procedure's triggers and internal procedures
  will execute in this procedure's storage, and that proper
  cleanup will occur on deletion of the procedure. */

CREATE WIDGET-POOL.

In this way, all the dynamic objects you create from within the procedure are deleted when the procedure terminates. The CREATE WIDGET-POOL statement is in the Definitions section, which is editable, so if you need some other treatment of your dynamic objects, you are free to change it.

Note that this and other standard code in a procedure you create using the AppBuilder is not actually generated by the AppBuilder. It is part of the template procedure file the AppBuilder uses as a starting point for a procedure of that type. These template procedure files are located in the src/template directory and identified by a set of text files with the .cst extension in the same directory. The AppBuilder reads and parses these .cst files on startup to build its Palette and the contents of its New dialog box. For example, the starting point for a window procedure, such as CustOrderWin, is the window .w file. For a structured procedure, such as h-WinSuper.p, it is procedur.p.

Sometimes you might need to manage objects more explicitly than just with an unnamed widget pool. In this case, you can give a name to a pool. Once you do this, you can then create objects and allocate them explicitly to that pool, as you saw in the syntax for the CREATE object statement. For example, this sequence of statements creates a named widget pool and then a button in that pool:

DEFINE VARIABLE hButton AS HANDLE NO-UNDO.
CREATE WIDGET-POOL "ButtonPool".
CREATE BUTTON hButton IN WIDGET-POOL "ButtonPool".

Note, first of all, that the pool name is a character expression. You can specify either a quoted string literal or a variable or other character expression that holds the name.

When you create the button, you allocate it to the specific widget pool named ButtonPool. You can then later delete this pool using the DELETE WIDGET-POOL statement:

DELETE WIDGET-POOL [ pool-name ] [ NO-ERROR ] .

The memory for the button and any other dynamic objects you allocated to the pool goes away without disturbing other dynamic objects in other pools, including the unnamed pool.

You can only assign dynamic objects to a named widget pool, so if you want something other than the default allocation, you need to name your widget pools.