This chapter discusses:
You can access any module directly from your application
code by creating an internal link to that module.
An internal link is like a link callback—it lets you
specify the module type, a setup function, and, where
appropriate, a location. But unlike a link callback, which
is always associated directly with a widget callback, an
internal link has no association with any widget. Instead,
PhAB will generate a manifest that you use in your
application code to specify which internal link you want to
use. PhAB provides several functions to help you use
internal links (discussed below).
You can use internal links to:
- Create a PhAB module within application code.
Using a link callback, you can directly link a widget to a
PhAB application module. But sometimes you need to create
the module from your application code instead. To do that,
use an internal link.
Here are some common situations where you should use an
internal link to create a module:
- when your application can display one of two different modules
based on some condition inside the application
- when you need to control the parentage of a module instead of
using the PhAB defaults (by default a new module is a child of the
- when you want to display a menu when the user presses the right
- Access and display picture modules.
You use picture modules primarily to replace
the contents of existing container widgets, such as
PtWindow or PtPanelGroup.
Note that when you create a picture module using ApCreateModule(),
you must specify the parent container widget.
- Open widget databases. For more information, see
“Using widget databases.”
To create an internal link:
- Choose Internal Links from the Application menu
or press F4. You'll see the
Internal Module Links dialog:
Internal Module Links dialog.
- Click on the <NEW> option if it isn't already selected.
- Choose the type of module you want.
- Fill in the fields in the Module Link Info section — see below.
- Click on Apply, then click on Done. If the module you
specified in the Name field doesn't exist,
PhAB will ask whether it should create that module.
||You can create only one internal link per module.|
The fields in the Internal Module Links dialog include:
- Name—Contains the name of the module.
To select from a list of existing modules, click on
the icon next to this field.
- Location—Determines where the module will appear; see
“Positioning a module”
in the Working with Modules chapter.
- Setup Function—Specifies the function that will be called
when the module is realized (optional). To edit the function,
click on the icon next to this field.
For more information, see
functions” in the Working with Code chapter.
- Called—Determines whether the setup function is called
before the module is realized, after the module is realized,
- Apply—Applies any changes.
- Reset—Restores the internal link
information to its original state.
- Remove—Deletes the selected internal link
from the Module Links list.
For every internal link defined in your application, PhAB
generates a manifest so you can identify and access the
Since PhAB derives the manifest name from the module name,
each module can have only one internal link. This may appear
limiting, but PhAB provides module-related functions (see
below) that let you customize a module's setup function and
location from within your application code.
To create the manifest name, PhAB takes the module's name
and adds ABM_ as a prefix. So, for example,
if you create an internal link to a module named
mydialog, PhAB creates the manifest
The manifest is used by the following PhAB
- Lets you manually create modules designed within PhAB.
A module created with this function behaves exactly as if it
were linked directly with a link callback. For example, if
you define a location and a setup function for the internal
link, the module will appear at that location and the setup
function will be called. Furthermore, widget callbacks,
hotkeys, and so on will become active.
- Lets you change the setup function associated with an
- Lets you change the display location associated with an
- Lets you change the parent of a window or dialog module associated
with an internal link. This function applies only to
internal links for window and dialog modules.
- Lets you open the module associated with an internal link as
a widget database.
For more info on the above functions, see the Photon Library
Here's how you can display a menu module when the user presses the right
mouse button while pointing at a widget:
- In PhAB, create the menu module. Give it a name, such as
- Create an internal link
to the menu module, as described above.
For a popup menu, you'll usually want the module to be positioned
relative to the widget or relative to the pointer.
- Select the widget to be associated with the menu. Make sure it
has Pt_MENUABLE set and Pt_ALL_BUTTONS
cleared in its Pt_ARG_FLAGS.
- Generate the code for your application. PhAB creates a manifest for
the internal link. In this example, it's called ABM_my_menu.
- Every widget that's a descendant of PtBasic has a
resource that's a list of callbacks invoked when you press the right
mouse button while pointing at the widget. Edit this resource, and create
a callback function like this:
text_menu_cb( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
/* eliminate 'unreferenced' warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
ApCreateModule (ABM_my_menu, widget, cbinfo);
return( Pt_CONTINUE );
The widget passed to ApCreateModule() is used if
the menu is to be positioned relative to the widget;
the cbinfo argument is used if
the menu is to be positioned relative to the pointer.
- Compile, link, and run your application. When you press the right mouse
button over the widget, your menu should appear.
Picture modules have two purposes:
- to let an application replace the contents of any container widget
- to serve as widget databases.
If you plan to use a widget several times within your
application, a widget database lets you design the widget
just once. It also saves you from a lot of coding. All you
have to do is preset the widget's resources and then, using
PhAB's widget-database API functions, create
a copy of the widget wherever you'd normally
create the widget within your code.
Here's an example of a widget database—it's part of the one that
PhAB uses for its own interface:
Widget database used for PhAB's interface.
To create a widget database:
- Create a picture module within your application.
- Create an internal link to the picture module.
- Create the widgets that you'll need to
access in your application code.
For example, let's say you need to create
a certain icon many times in your application. By
creating the icon inside the picture module, you can create
as many copies of the icon as you need at run time.
Besides being able to preset all of a widget's resources in
the database module, you can also preattach its callbacks.
When you create the widget dynamically, any callbacks you
attached will also be created.
By presetting the resources and callbacks of a database
widget, you can easily reduce the code required to
dynamically create the widget to a single line.
||Preattached callbacks work only with modules and functions that are part
of your executable. If your application opens an external file as a widget
database, the PhAB library won't be able to find the code to attach to
Assign each widget in a widget database an
instance name—this lets you refer to the
widgets when using database-related API
You can also create a widget database that you can change
dynamically. To do this, open an external widget
database—that is, one that isn't bound into your
lets you access a module file directly and
open it as a database.
Once you've opened the module file, you can copy the
widgets from that file to your application's internal
database and save the resulting database to a new file that
you can reopen later.
PhAB provides several support functions to let you open a
widget database and copy its widgets into modules—you
can copy the widgets as often as needed. PhAB also provides
convenience functions to let you copy widgets between
databases, create widgets, delete widgets, and save widget
- These let you open and close a widget database.
To ensure that the database is always available,
you typically use ApOpenDBase() in the
application's initialization function.
- These let you open and save external module
files as databases within your application.
- This function lets you indicate which widget classes you're likely to
encounter when you call ApOpenDBaseFile().
When you link your application, only those widgets it needs
are linked into it. If you access widgets that aren't in your
application because they're in an external database, you must add them to
your internal class table so that they can be linked in at compile time.
- These create widgets from the widget database.
ApCreateWidget() and ApCreateDBWidget()
create a single widget only, regardless of
the widget's class.
For a noncontainer-class widget,
ApCreateWidgetFamily() and ApCreateDBWidgetFamily()
create a single widget; for a container-class widget,
they create all the widgets within the container.
These functions differ in the parent used for the widgets:
- ApCreateDBWidget() and ApCreateDBWidgetFamily()
include a parent argument; if this is NULL,
the widget has no parent.
ApCreateWidget() and ApCreateWidgetFamily() put the
new widget(s) in the current parent. To make sure the correct widget is
the current parent, call
before calling either of these functions.
Don't use the manifests generated for the widget
database's picture module. Instead, use the widget pointers
returned by ApCreateWidget() or ApCreateDBWidget().
- Lets you copy a widget from one widget
database to another. Typically, you use this only when you're
dynamically creating and saving widget databases within
- Deletes a widget from a widget database.
- Gets information about a widget in a widget database, including its
name, class, parent, and level in the hierarchy.
- Pull out image-resource data from a widget and use this data
to set resources of a widget already displayed in your
This function lets you achieve very basic animation.
|| If you use a widget database to create widgets that
data attached to them, don't close the database with
until after those widgets are destroyed.
(Closing the database frees the memory used by the image.)
If you must close the database, make sure to copy the image data within
your application code and to reset the image data resource to
point to your new copy.
For more information, see the
in the chapter on Drawing.
- This lets you extract text strings from a widget database. It's useful
for multilingual applications, as the text is automatically translated if the
language support is enabled. For more information, see the
International Language Support
- Remove a widget class.
If you've loaded a DLL that defines widget classes, you should remove
them before unloading the DLL.
For more information, see
“Making a DLL out of a PhAB application”
in the Generating, Compiling, and Running Code chapter.
For more info on widget database functions, see
the Photon Library Reference.