[Previous] [Contents] [Index] [Next]

Accessing PhAB Modules from Code

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:

Creating internal links

To create an internal link:

  1. Choose Internal Links from the Application menu or press F4. You'll see the Internal Module Links dialog:

    Internal Links dialog


    Internal Module Links dialog.

    
    
  2. Click on the <NEW> option if it isn't already selected.
  3. Choose the type of module you want.
  4. Fill in the fields in the Module Link Info section - see below.
  5. 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.

Note: You can create only one internal link per module.

The fields in the Internal Module Links dialog include:

Using internal links in your code

Manifests

For every internal link defined in your application, PhAB generates a manifest so you can identify and access the link.

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 ABM_mydialog.

API

The manifest is used by the following PhAB API functions:

ApCreateModule()
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.

ApModuleFunction()
Lets you change the setup function associated with an internal link.
ApModuleLocation()
Lets you change the display location associated with an internal link.
ApModuleParent()
Lets you change the parent of a window module associated with an internal link. This function applies only to internal links for window modules.
ApOpenDBase()
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 Reference.

Example - displaying a menu

Here's how you can display a menu module when the user presses the right mouse button while pointing at a widget:

  1. In PhAB, create the menu module. Give it a name, such as my_menu.
  2. 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.
  3. 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.
  4. Generate the code for your application. PhAB creates a manifest for the internal link. In this example, it's called ABM_my_menu.
  5. Every widget that's a descendant of PtBasic has a Pt_CB_MENU 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:
    int
    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.

  6. Compile, link, and run your application. When you press the right mouse button over the widget, your menu should appear.

Using widget databases

Picture modules have two purposes:

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 the one that PhAB uses for its own interface.


PhAB database


Widget database used for PhAB's interface.


Creating a database

To create a widget database:

  1. Create a picture module within your application.
  2. Create an internal link to the picture module.
  3. 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.

Preattaching callbacks

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.


Note: 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 the callback.

Assigning unique instance names

Assign each widget in a widget database an instance name-this lets you refer to the widgets when using database-related API functions.

Creating a dynamic database

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 executable-with ApOpenDBaseFile() instead of ApOpenDBase(). ApOpenDBaseFile() 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. The Photon Desktop Manager (PDM) takes this approach to maintain the icons in its quick-launch folders.

Widget-database functions

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 databases.

ApOpenDBase()
ApCloseDBase()
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.

ApOpenDBaseFile()
ApSaveDBaseFile()
These let you open external module files as databases within your application.
ApAddClass()
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.
ApCreateWidget()
ApCreateWidgetFamily()
These create widgets from the widget database. ApCreateWidget() creates a single widget only, regardless of the widget's class.

For a noncontainer-class widget, ApCreateWidgetFamily() creates a single widget; for a container-class widget, it creates all the widgets within the container.

ApCreateWidget() and ApCreateWidgetFamily() put the new widget(s) in the current parent. To make sure the correct widget is the current parent, call PtSetParentWidget() before calling either of these functions.


Note: Don't use the manifests generated for the widget database's picture module. Instead, use the widget pointers returned by the ApCreateWidget() function.

ApCopyWidget()
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 your application.
ApDeleteWidget()
Deletes a widget from a widget database.
ApGetBitmapRes()
ApGetImageRes()
These let you achieve very basic animation. Essentially, they let you pull out bitmap or image-resource data from a widget and use this data to set resources of a widget already displayed in your application.
Note: If you use a widget database to create widgets that have PhImage_t data attached to them, you shouldn't close the database with ApCloseDBase() 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 "Animation" section in the chapter on Drawing.

ApFreeBitmapRes()
This function frees a bitmap resource structure returned by ApGetBitmapRes(). It doesn't free the bitmap planes or colors because they point back into the widget database.
ApGetTextRes()
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 appendix on International Language Support.

[Previous] [Contents] [Index] [Next]