Common Desktop Environment: Help System Author's and Programmer's Guide

Enabling the Help Key (F1)

The help key mechanism is a feature built into all OSF/Motif manager widgets and primitive widgets. The help key is enabled by adding a help callback to the widget where you want the help key active.

Within your application, you should add a help callback to each widget where you want a unique entry point into help. The help callback mechanism automatically "walks" up the widget hierarchy (up to the shell widget) until it finds a widget with a help callback, then invokes that callback.

If you add a help callback to a manager widget, when the help key is pressed for any of its children, the manager's help callback is invoked (unless the child widget has a help callback of its own).

To Add a Help Callback

    Use the XtAddCallback() function as follows:

XtAddCallback (
       Widget          widget,
       String          DtNhelpCallback,
       XtCallbackProc  HelpRequestCB,
       XtPointer       clientData );

Where:

widget

The widget where you want to activate the help key.

HelpRequestCB()

The function in your application that handles the help request when the user presses the help key.

clientData

The data you want passed to the HelpRequestCB() function. Typically, this data identifies the topic to be displayed.

When the user presses the help key, the help callback is invoked for the widget with the current keyboard focus. If that widget does not have a help callback, the help callback for its nearest ancestor that does have a help callback is invoked.

If no help callbacks are found, nothing happens. Therefore, it is recommended that you add a help callback to each shell in your application. This ensures that no user requests for help are lost.

Adding a help callback to a dialog shell automatically enables the Help button on the dialog to invoke the help callback.

Importance of Client Data

Specifying a unique value for clientData in each help callback you add saves you the trouble of writing a separate function to process each help callback. Your application can have a single callback procedure to process all help requests (see "To Add a Help Callback"). Within the callback procedure, use the clientData to identify where the user requested help. That is, each time you add a help callback, you should provide a unique value for clientData.

Example

The following example demonstrates one way to associate IDs with entry points. A HelpEntryIds.h file is used to define a unique integer for each clientData value for each help callback. Also defined are two ID strings for each widget: one for normal F1 help, the other for item help mode (where the user picks a widget to get a description).

For this example, assume that the application's user interface is just a main window with three input fields: Name, Address, and Telephone Number. Here's what the HelpEntryIds.h file would contain:

#define HELP_volumeName            "MyVolume"
 #define HELP_MainWindow            100
 #define HELP_MainWindow_ID         "basic-tasks"
 #define HELP_MainWindow_ITEM_ID    "main-window-desc" 
 #define HELP_NameField             101
 #define HELP_NameField_ID          "specifying-a-name"
 #define HELP_NameField_ITEM_ID     "name-field-desc" 
 #define HELP_AddressField          102
 #define HELP_AddressField_ID       "specifying-an-address"
 #define HELP_AddressField_ITEM_ID  "address-field-desc" 
 #define HELP_PhoneField            103
 #define HELP_PhoneField_ID         "specifying-a-phone-no"
 #define HELP_PhoneField_ITEM_ID    "phone-field-desc"

Within the part of the application that initially creates the widgets, a help callback is added to each widget as follows:

XtAddCallback (mainWindow, DtNhelpCallback,
               HelpRequestCB, HELP_MainWindow);
 XtAddCallback (nameField, DtNhelpCallback,
                HelpRequestCB, HELP_NameField);
 XtAddCallback (addressField, DtNhelpCallback,
                HelpRequestCB, HELP_AddressField);
 XtAddCallback (phoneField, DtNhelpCallback,
                HelpRequestCB, HELP_PhoneField);

Within the HelpRequestCB() function, the clientData parameter is used to dispatch the help requests (through a switch() statement). Within each case, the value of a global flag itemHelp is tested to see if the help callback was invoked by the F1 key (the flag is "false") or by the user picking the widget in item help mode (the flag is "true").

XtCallbackProc HelpRequestCB (
       Widget     w,
       XtPointer  clientData,
       XtPointer  callData )
 {
    char    *topicToDisplay;
    Boolean  useQuickHelpDialog;
    /* Determine the topic ID for the given ` clientData.' */
    switch ((int)clientData)
      {
        case HELP_MainWindow:
          useQuickHelpDialog = False;
          if (itemHelpFlag)
            topicToDisplay = HELP_MainWindow_ITEM_ID;
          else
            topicToDisplay = HELP_MainWindow_ID;
          break;       case HELP_NameField:
          useQuickHelpDialog = True;
          if (itemHelpFlag)
            topicToDisplay = HELP_NameField_ITEM_ID;
          else
            topicToDisplay = HELP_NameField_ID;
          break;       case HELP_AddressField:
          useQuickHelpDialog = True;
          if (itemHelpFlag)
            topicToDisplay = HELP_AddressField_ITEM_ID;
          else
            topicToDisplay = HELP_AddressField_ID;
          break;       case HELP_PhoneField:
          useQuickHelpDialog = True;
          if (itemHelpFlag)
            topicToDisplay = HELP_PhoneField_ITEM_ID;
          else
            topicToDisplay = HELP_PhoneField_ID;
          break;       default:
          /* An unknown clientData was received. */
          /* Put your error handling code here. */
          return;
          break;
      }
    /* Display the topic. */
    ac = 0;
    XtSetArg (al[ac], DtNhelpType,   DtHELP_TYPE_TOPIC); ac++;
    XtSetArg (al[ac], DtNhelpVolume, HELP_volumeName);    ac++;
    XtSetArg (al[ac], DtNhelpType,   topicToDisplay);     ac++;
    if (useQuickHelpDialog)
      {
         XtSetValues (mainQuickHelpDialog, al, ac);
         XtManageChild (mainQuickHelpDialog);
      }
    else
      {
         XtSetValues (mainHelpDialog, al, ac);
         XtManageChild (mainHelpDialog);
      }
    /* Clear the ` item help' flag. */
    itemHelpFlag = False;
  }

The preceding function assumes that the application uses two help dialogs for all help requests (mainHelpDialog and mainQuickHelpDialog), and that those dialogs have already been created. It also assumes that al and ac (used in assembling Xt argument lists) are declared elsewhere.