Use widget pools
- Last Updated: January 16, 2024
- 5 minute read
- OpenEdge
- Version 12.8
- Documentation
Deleting individual dynamic objects is a big responsibility, and a serious nuisance as well. Widget pools are designed to help you make your use of dynamic objects much simpler and more reliable.
CREATE WIDGET-POOL statement in the template’s definitions
section:
|
This means that, by default, all the dynamic objects you create that go into the window are deleted when the window is closed and its procedure deleted. This includes not just visual objects but dynamic buffers, queries, and so forth.
Remember that a simple CREATE WIDGET-POOL statement creates an unnamed
widget pool. This pool automatically goes away when its procedure terminates. This might
not always be the behavior you want. In fact, by passing the handles to dynamic objects
around, you can easily wind up with a handle whose scope exceeds the lifetime of the
dynamic object it points to. In this case, the value of the handle can become
invalid.
getBuffer that creates a
dynamic buffer and returns it to the caller. The CREATE WIDGET-POOL
statement puts all such buffers into an unnamed widget pool for that
procedure:
|
PERSISTENT and then runs getBuffer:
|
What happens, though, when the procedure has deleted its instance of h-MakeBuffer.p?
The unnamed widget pool in that instance of h-MakeBuffer.p goes
away, and the dynamic buffer that hMyBuf points to goes away with it.
But the hMyBuf variable is still very much alive, and in fact the value
of the handle that it holds has not changed. However, that handle value does not point
to anything anymore, so you get a string of errors, as shown here.
This sequence of errors is the bane of any dynamic programmer’s existence. It is the most likely consequence of failing to make sure that all your dynamic objects live exactly as long as they need to, but no longer.
Use named widget pools
PERSISTENT. You can then create dynamic
objects explicitly in that pool:
|
|
When you run the procedure, the errors go away, because the handle is valid until you delete the pool.
- You must give the widget pool a name if you want to allocate objects to it specifically or if you want it to outlive the procedure that creates it.
- The widget pool name is a character expression. So, if you are using a
literal string rather than a variable for the name, you must remember to put
it in quotes both where you create it and wherever you reference it. This is
different from other
CREATEstatements, where you normally specify a handle variable as a target for the create and where the dynamic object you create does not really have a name the same way that static objects do. - You must also make a named pool
PERSISTENTif you want it to outlive the procedure that creates it. - You must remember to delete the widget pool when you are done using it, just as you delete individual dynamic objects that are not in a specific widget pool when you are done with them.
You might create a named widget pool that was not persistent simply to put different dynamic objects in different pools within a single procedure, so that you could delete one widget pool within the procedure without deleting objects in some other widget pool. In this case, all of the pools that have not been specifically deleted during the execution of the procedure are deleted when the procedure is deleted.
A widget pool cannot be created as PERSISTENT without giving it a
name.
When you create a persistent named pool, its name effectively becomes global to the
session. Any procedure running anywhere in the session can delete it. You cannot,
however, access named widget pools through the SESSION handle as
you can with some other kinds of objects, such as windows and procedures.