“Tim Clem” <tclem@natech-inc.com> wrote in message
news:dkgdhr$j21$1@inn.qnx.com…
Wojtek Lerch wrote:
The easiest first guess is that you’re passing a bad pointer as the
second argument to ApCreateModule(). A common way to do that is by using
a widget pointer after the widget has been destroyed – for instance, the
ABW value of a window that just got closed. Does that sound possible?
Yes. That is very possible, especially with the sequence of actions that
causes the failure. How do I check to make sure that the ABW value is not
pointing to a window that just got closed? Will it be NULL?
No, unless it’s a dialog module. For any widget other than the window
widget of a dialog module, PhAB just sets its ABW variable whenever an
instance of the widget is created, and never unsets it or even looks at it.
In other words, the ABW points to the most recently created instance of the
widget, or is a bad pointer if that instance has been destroyed, or is NULL
if no instance of the widget has been created yet.
For dialog modules, PhAB registers a Pt_CB_DESTROYED callback that sets the
ABW of the window to NULL when it’s destroyed. And when you call
ApCreateModule() (or click on on a button linked to the module, etc.), it
checks the ABW, and if it’s not NULL, it just brings the existing window to
the front instead of creating a new one. Unless you mess with the ABW
yourself (which we recommend you not do), you’ll never have more than one
instance of any given dialog module.
For example if I:
- Called: ApCreateModule(ABM_window,ABW_window, NULL)
- destroyed that window: PtDestroyWidget(ABW_window);
- and then tried to create it again: ApCreateModule(ABM_window,
ABW_window, NULL) before the widget has been completely destroyed.
By the time PtDestroyWidget() returns, the widget is guaranteed to be
“almost completely” destroyed. It’s gone from the screen and its
Pt_CB_DESTROYED callbacks have run (which means that if it was a dialog
window, its ABW is NULL). The memory it occupies in your process space
hasn’t been freed yet, but you can safely ignore that fact (except when you
run a tight loop that creates and destroys more widgets that you have memory
for; but why would you do that). After PtDestroyWidget(), it may still be
safe to get the dead widget’s resources – in particular, it is safe if
you know you’re in a callback of a widget inside the destroyed hierarchy.
(For instance, it’s OK to have button with two functions attached to the
ACTIVATE callback, such that the first function destroys the window that the
button is in and the second function grabs the string from a text field in
the window). But unless that’s something you want to do, you don’t need
to care or even know about it.
The ABW_window is a window created by PhAB. I am creating and destorying
the window as part of the application. Is there a better way to do this
than my current approach?
The easiest way to keep track of whether your window is there or not is by
making it a dialog module and checking its ABW for NULL. The only reason
you might not want to make it a dialog module is when your application may
sometimes need multiple instances of it on the screen; in those cases, a
single ABW is not sufficient to keep track of all the instances, and you’ll
need to implement something in your own code, such as a small structure
attached to each instance using the Pt_ARG_USER_DATA or Pt_ARG_POINTER
resource, and perhaps a global variable pointing to a linked list of all
those structures. You can still use the ABWs to initialize a new list item
when you create a new instance of the module (because they’re valid
immediately after creating the instance), and you’ll need a Pt_CB_DESTROYED
callback to remove it from the list.