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

Part III The Programmer's Job

Chapter 9 Creating and Managing Help Dialog Boxes

This chapter describes the Help dialog widgets and how to create them.

Help Dialog Boxes

For application programmers, the Help System provides a programming library that adds help dialog boxes to any OSF/Motif application. The library provides two types of help dialog boxes:

Standard Xt Paradigm

In terms of programming, you interact with the help dialogs the same as you do with any other OSF/Motif widgets in your applications. The two types of help dialog boxes are defined as two new widget classes: DtHelpDialog and DtHelpQuickDialog.

Nearly every attribute of the help windows--including the volume name and topic ID--are manipulated as widget resources. For instance, to display a new topic, you just execute an XtSetValues() call to set the DtNhelpVolume, DtNlocationId, and DtNhelpType resources. For more information, refer to "Displaying Help Topics".


Note -

Integrating the Help System into an application requires a working knowledge of the C programming language, the OSF/Motif programmer's toolkit, and the Xt Intrinsics toolkit.


General Help Dialog

A general help dialog has two display areas: the topic tree and topic display area. The topic tree provides a scrollable list of help topics. The home topic title is always the first item. When a user chooses a title, an arrow (=>) marks the title and its help information is displayed in the topic display area. Figure 9-1 shows the topic tree and topic display area of a general help window. The current topic, "To select a palette", is displayed.

The general help dialog includes three dialog buttons: Backtrack, History, and Index. These commands are also available in the Help menus. For an overview of the Help dialogs and the graphical user interface, refer to the section, "Help User Interface".

Figure 9-1 General help dialog

Graphic

To Create a General Help Dialog

  1. Include the appropriate header files:

    #include <Help.h>
     #include <HelpDialog.h>
  2. Create an instance of the general help dialog widget:

    • Use the DtCreateHelpDialog() convenience function.

      Or, use the XtCreateManagedWidget() function.

  3. Add a callback for handling hyperlink events that occur within the dialog. (For more information, see "Responding to Hyperlink Events".)

  4. Add a close callback for handling the Close command.

Example

The following code segment creates a general help dialog (as a child of parent) using the convenience function. The dialog is left unmanaged--presumably it is managed elsewhere in the application when a help request is made.

Widget   mainHelpDialog, moreButton, helpButton;
 ac = 0;
 XtSetArg (al[ac], XmNtitle,  "My Application - Help");  ac++;
 XtSetArg (al[ac], DtNhelpVolume,  "My Help Volume");  ac++;
 XtSetArg (al[ac], DtNlocationId,  "Getting Started");  ac++;
 XtSetArg (al[ac], DtNhelpType,  "DtHELP_TYPE_TOPIC");  ac++;

 mainHelpDialog =
   DtCreateHelpDialog (parent,  "mainHelpDialog", al, ac);

The following two calls add the hyperlink and close callbacks to the dialog. Presumably, the functions HyperlinkCB() and CloseHelpCB() are declared elsewhere in the application.

XtAddCallback (mainHelpDialog, DtNhyperLinkCallback,
 				HyperlinkCB, (XtPointer)NULL);
 XtAddCallback (mainHelpDialog, DtNcloseCallback,
                CloseHelpCB, (XtPointer)NULL);

See Also

Quick Help Dialog

The quick help dialog box is designed to help you meet the first objective of online help: Get the user back on task as quickly and successfully as possible. This simple user interface helps keep the user focused on the information. The information should be useful enough that the user dismisses the dialog after reading it and continues working.

Figure 9-2 Quick help dialog with four standard buttons

Graphic

The quick help dialog has five buttons, four of which are managed. The remaining dialog button is configurable, so this button can be used for anything. However, its intended purpose is to provide a path to more help in one of these two ways:

The Developer's toolkit includes a convenience function, DtHelpQuickDialogGetChild(), for determining the widget ID for any of the quick help dialog buttons.

To Create a Quick Help Dialog

  1. Include the appropriate header files:

    #include <Help.h>
     #include <HelpQuickD.h>
  2. Create an instance of the quick help dialog widget:

    • Use the DtCreateHelpQuickDialog() convenience function.

      Or, use the XtCreateManagedWidget() function.

  3. Add a callback for handling hyperlink events that occur within the dialog. (For more information, see "Responding to Hyperlink Events".)

  4. Add a close callback for handling the OK button.

  5. Configure the dialog buttons that you want to use:

    • If you intend to use the application-configured button, manage it and add an activate callback.

    • If you want to disallow printing, unmanage the Print button.

    • Manage the Help button and add a help callback to the dialog to allow the user to get help on help.

Example

The following code segment creates a quick help dialog (as a child of parent) using the convenience function. The dialog is left unmanaged; presumably, it is managed elsewhere in the application when a help request is made. In this example, the application-configured button is enabled and used to request more help.

Widget   quickHelpDialog, moreButton, helpButton;
 ac = 0;
 XtSetArg (al[ac], XmNtitle,  "My Application - Help");  ac++;
 XtSetArg (al[ac], DtNhelpVolume,  "My Help Volume");  ac++;
 XtSetArg (al[ac], DtNlocationId,  "Getting Started");  ac++;
 XtSetArg (al[ac], DtNhelpType,  "DtHELP_TYPE_TOPIC"); ac++;


 quickHelpDialog =
   DtCreateHelpQuickDialog (parent,  "quickHelpDialog", al, ac);

The following two calls add the hyperlink and close callbacks to the dialog. Presumably, the functions HyperlinkCB() and CloseHelpCB() are declared elsewhere in the application.

XtAddCallback (quickHelpDialog, DtNhyperLinkCallback,
				HyperlinkCB, (XtPointer)NULL);
XtAddCallback (quickHelpDialog, DtNcloseCallback,
                CloseHelpCB, (XtPointer)NULL);

Here, the application-configured button is managed and assigned an activate callback that invokes the application's MoreHelpCB() function.

moreButton = DtHelpQuickDialogGetChild (quickHelpDialog,
										DT_HELP_QUICK_MORE_BUTTON);
 XtManageChild (moreButton);
XtAddCallback (moreButton, XmNactivateCallback,
                MoreHelpCB, (XtPointer)NULL);

To provide "help on help," the dialog's Help button is managed and a help callback is added to the dialog.

helpButton = DtHelpQuickDialogGetChild (quickHelpDialog,
										DT_HELP_QUICK_HELP_BUTTON);
 XtManageChild (helpButton);
XtAddCallback (quickHelpDialog,DtNhelpCallback,
                HelpRequestCB, USING_HELP);

Like other OSF/Motif dialogs, when you add a help callback to a quick help dialog, it is used by both the F1 key and the Help button.

See Also

Summary of Application Program Interface

Related man pages for the Help System are:

Chapter 10 Responding to Help Requests

This chapter explains how to display different types of help information by setting Help Dialog widget resources.

Requesting Help

When a user requests help while using your application, it's the application's responsibility to determine what help topic should be displayed.

Context Sensitivity

Some help requests amount to an explicit request for specific information, such as help on "version" (which usually displays the copyright topic). Other help requests, however, may require some degree of context sensitivity. That is, some processing might be needed to determine the appropriate help topic based on the user's current context within the application.

For instance, your application might test the status of certain modes or settings to determine the appropriate help topic. Or, it might test the value of an input field and provide detailed help if the value is not valid, and general help if the value is valid.

Entry Points

An entry point is a specific location within a help volume--usually the beginning of a topic--that can be directly accessed by requesting help within the application.

From the author's point of view, entry points are established by assigning IDs at the appropriate places within the help volume. From the programmer's point of view, entry points are created by enabling the user to request help and using the appropriate ID when a particular request is made.

There are four general ways for users to request help:

Displaying Help Topics

When a help request is made, the application determines what help topic to display. It then creates (if necessary) and manages a help dialog, and sets the appropriate resources to display a help topic.

Most requests display help topics that are part of the application's help volume. But, the Help System's help dialogs are also capable of displaying man pages, text files, and simple text strings.

The Help System's help dialogs are based exclusively on Xt Intrinsics and OSF/Motif programming, so you change the values within a help dialog just like any other widget: by setting resources.

The DtNhelpType resource determines what type of information is displayed. It can be set to any of these values:

These values are defined in the Help.h file.

See Also

To Display a Help Topic

  1. Create a help dialog.

  2. Set the following resources for the help dialog:

    DtNhelpType

    Set to DtHELP_TYPE_TOPIC.

    DtNhelpVolume

    Set to the volume name for your application.

    DtNlocationId

    Set to the topic ID that you want to display.

    You can also set other values for the dialog, such as its size and title.

  3. Manage the dialog using XtManageChild().

Example

This program segment displays a topic with the ID getting-started in the volume MyVolume.

ac = 0;
XtSetArg (al[ac], DtNhelpType,   DtHELP_TYPE_TOPIC);  ac++;
 XtSetArg (al[ac], DtNhelpVolume,  "MyVolume");         ac++;
 XtSetArg (al[ac], DtNlocationId,  "getting-started");  ac++;
 XtSetArg (al[ac], DtNcolumns,    40);                  ac++;
 XtSetArg (al[ac], DtNrows,       12);                  ac++;
 XtSetValues (helpDialog, al, ac);
 XtManageChild (helpDialog);

If the help volume MyVolume is not registered, then a complete path to the MyVolume.sdl file is required for the value of DtNhelpVolume.

To Display a String of Text

  1. Create a quick help dialog.

    You can use a general help dialog to display string data, but this isn't recommended because most of its features do not apply to string data.

  2. Set the following resources for the help dialog:

    DtNhelpType

    Set to DtHELP_TYPE_DYNAMIC_STRING (if you want word wrap enabled) or DtHELP_TYPE_STRING (if you want the line breaks within the string to be maintained) .

    DtNstringData

    Set to the string you want to display. A copy of the string is kept internally, so you need not maintain your copy of it.

    You can also set other values for the dialog, such as its size and title.

  3. Manage the dialog using XtManageChild().

Example

This program segment displays a string stored in the variable descriptionString.

ac = 0;
 XtSetArg (al[ac], DtNhelpType,   DtHELP_TYPE_DYNAMIC_STRING); ac++;
 XtSetArg (al[ac], DtNstringData, (char *)descriptionString);   ac++;
 XtSetValues (quickHelpDialog, al, ac);
 XtManageChild (quickHelpDialog);

If the string is no longer needed within the application, the memory can be freed, because the help dialog makes its own copy of the data.

 XtFree (descriptionString);

To Display a Text File

  1. Create a quick help dialog or retrieve one from your dialog cache.

    You can use a general help dialog to display a text file, but this isn't recommended because most of its features are useful only for standard help topics.

  2. Set the following resources for the help dialog:

    DtNhelpType

    Set to DtHELP_TYPE_FILE..

    DtNhelpFile

    Set to the file name you want to display. If the file is not in the application's current directory, provide a path to the file.

    You can also set other values for the dialog, such as its size and title. In particular, you might want to set the width to 80 columns, which is the standard width for text files.

  3. Manage the dialog using XtManageChild().

Example

The following program segment displays a file named /tmp/printer.list. It also sets the size of the dialog to better suit a text file.

ac = 0;
 XtSetArg (al[ac], DtNhelpType, DtHELP_TYPE_FILE);      ac++;
 XtSetArg (al[ac], DtNhelpFile,  "/tmp/printer.list");  ac++;
 XtSetArg (al[ac], DtNcolumns,  80);                    ac++;
 XtSetArg (al[ac], DtNrows,     20);                    ac++;
 XtSetValues (quickHelpDialog, al, ac);
 XtManageChild (quickHelpDialog);

To Display a Man Page

  1. Create a quick help dialog.

    You can use a general help dialog to display a man page, but this isn't recommended because most of its features are useful only with standard help topics.

  2. Set the following resources for the help dialog:

    DtNhelpType

    Set to DtHELP_TYPE_MAN_PAGE.

    DtNmanPage

    Set to the name of the man page. The value of this resource is passed directly to the system man command. So, to specify a particular section of a man page, precede the man page name by a section number, just as you would if you were typing the man command conventionally.

    You can also set other values for the dialog, such as its size and title.

  3. Manage the dialog using XtManageChild().

Example

The following program segment displays the man page for the grep command. It also sets the size of the dialog to better suit a man page.

ac = 0;
 XtSetArg (al[ac], DtNhelpType, DtHELP_TYPE_MAN_PAGE);  ac++;
 XtSetArg (al[ac], DtNmanPage,   "grep");                ac++;
 XtSetArg (al[ac], DtNcolumns,  80);                     ac++;
 XtSetArg (al[ac], DtNrows,     20);                     ac++;
 XtSetValues (quickHelpDialog, al, ac);
 XtManageChild (quickHelpDialog);

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.

Providing a Help Menu

The CDE Style Guide and Certification Checklist recommends that each menu bar include a Help menu. The Help menu may contain a variety of commands that let the user access different types of online help for your application.

The most important commands include:

See Also

Supporting Item Help Mode

Some applications provide an On Item or Help Mode command in their Help menu. This command temporarily redefines the mouse pointer as a ? (question mark) to prompt the user to select an item on the screen. When an item is selected, the application is expected to display a description of the item.

The convenience function, DtHelpReturnSelectedWidgetId(), changes the pointer to a question mark and waits for the user to pick a widget. The ID of the selected widget is returned. This function is similar to the XmTrackingLocate() function except that DtHelpReturnSelectedWidgetId() returns NULL if the user presses Escape to cancel the operation.

To display help on the selected item, your application can simply invoke the help callback for the returned widget. This is equivalent to the user pressing F1 while using that widget.

If you want the application to differentiate between item help and F1 help, you can set a flag before calling the widget's help callback. The help callback procedure can then use that flag to determine that the callback was invoked as a result of item help and alter its response accordingly.

To Add Support for Item Help

  1. Write a function that uses the DtHelpReturnSelectedWidgetId() function. Within this function, invoke the help callback for the selected widget. In the following steps, this function is called ProcessOnItemHelp(), but you can name it whatever you want.

  2. Add to your Help menu a command button labeled On Item. Add an activate callback that invokes your ProcessOnItemHelp() function.

  3. Add a help callback to each widget in your application where you want item help to be available.

    If the selected widget does not have a help callback, the application should try its parent widget. Similarly, if the parent does not have a help callback, the application should continue to walk up the widget hierarchy until it finds a help callback.

Example

The following procedure is a sample ProcessOnItemHelp() function that would be invoked by choosing On Item from the Help menu.

void  ProcessOnItemHelp(
   Widget widget)
 {
  /* Declare a variable for the selected widget. */ 
  Widget selWidget=NULL;
   int status=DtHELP_SELECT_ERROR;
  /* Get an application shell widget from our widget hierarchy to
        * pass into DtHelpReturnSelectedWidgetId().
    */
  while (!XtIsSubclass(widget, applicationShellWidgetClass))
                    widget = XtParent(widget);
  status = DtHelpReturnSelectedWidgetId(widget, NULL, &selWidget);
  switch ((int)status)
     {
       case DtHELP_SELECT_ERROR:
         printf("Selection Error, cannot continue\n");
      break;
      case DtHELP_SELECT_VALID:
          /* We have a valid widget selection, now let's look for a registered help
                        * callback to invoke.
           */
         while (selWidget != NULL)
           {
             if ((XtHasCallbacks(selWidget, XmNhelpCallback)
                                      == XtCallbackHasSome))
               {
                 /* Found a help callback, so just call it */
                XtCallCallbacks((Widget)selWidget,
                                 XmNhelpCallback,NULL);
                 break;
               }
            else
              /* No help callback on current widget, so try the widget's parent  */
                 selWidget = XtParent(selWidget);
           }
      break;
       case DtHELP_SELECT_ABORT:
         printf("Selection Aborted by user.\n");
      break;
      case DtHELP_SELECT_INVALID:
         printf("You must select a component within your app.\n");
      break;
     }
 }
 

Chapter 11 Handling Events in Help Dialogs

This chapter describes several Help dialog events that an application must be equipped to handle.

Supporting Help Dialog Events

Like other widgets within your application, help windows have some behavior that must be supported by the application.

Hyperlink Events

Most standard hyperlink events are handled internally by the Help System. However, there are four types of hyperlinks that your application is responsible for handling:

When Dialogs Are Dismissed

When the user closes a help dialog, your application needs to know so it can store the dialog in its cache, or destroy it. The general help dialog supports a help closed callback. To detect when a quick dialog is dismissed, add a callback to its Close button.

Quick Help Buttons

The behavior for some of the buttons in quick help dialogs must be handled by your application. These buttons can be managed and unmanaged as needed. You add behavior just like any other push button: using an activate callback.

See Also

Responding to Hyperlink Events

Your application needs to provide support only for the types of hyperlinks used within the help volume to be displayed. In general, it is recommended that you provide support for all link types.

For your application to be notified when a hyperlink is chosen, it must add a hyperlink callback to the help dialog. You must write a callback function that handles the hyperlink appropriately.

To Provide a Hyperlink Callback

  1. Add a hyperlink callback to each help dialog as shown:

    XtAddCallback (helpDialog, DtNhyperlLinkCallback,
                    HyperlinkCB, (XtPointer)NULL);

    Where helpDialog is the widget ID of the help dialog and HyperlinkCB is the name of the callback function for handling hyperlinks.

  2. Write the HyperlinkCB function to handle the hyperlink events that can occur within the dialog.

    Within the hyperlink callback, you have access to the following callback structure (which is declared in <Dt/Help.h>):

    typedef struct
     	{
    		int      reason;
    		XEvent  *event;
    		char    *locationId; 
    		char    *helpVolume;
    		char    *specification;
    		int      hyperType;
    		int      windowHint;
    } DtHelpDialogCallbackStruct;

    The hyperType element indicates which type of link was executed. Its possible values are: DtHELP_LINK_TOPIC, DtHELP_LINK_MAN_PAGE, DtHELP_LINK_APP_DEFINE, or DtHELP_LINK_TEXT_FILE. For a description of which structure elements are valid for different types refer to the DtHelpDialog(3) man page.

    The windowHint element indicates a window type. Its possible values are: DtHELP_CURRENT_WINDOW, DtHELP_POPUP_WINDOW, or DtHELP_NEW_WINDOW.

Example

The following function, HyperlinkCB(), illustrates the general structure needed to handle hyperlink callbacks.

XtCallbackProc
HyperlinkCB (widget, clientData, callData)
      Widget     widget;
      XtPointer  clientData;
      XtPointer  callData;
   {
      DtHelpDialogCallbackStruct *hyperData =
         (DtHelpDialogCallbackStruct *) callData;
      switch ((int)hyperData-> hyperType)
         {
            case DtHELP_LINK_TOPIC:
              /* Handles  "jump new view"hyperlinks. */
              break;
            case DtHELP_LINK_MAN_PAGE:
              /* Handles  "man page" hyperlinks. */
              break;
            case DtHELP_LINK_APP_DEFINE:
              /* Handles ``application-defined" hyperlinks. */
              break;
            case DtHELP_LINK_TEXT_FILE:
              /* Handles ``text file" hyperlinks. */
              break;
            default:
              break;
    }

Detecting When Help Dialogs Are Dismissed

To detect when a general help dialog is closed, add the following callback to the dialog:

XtAddCallback (helpDialog, DtNcloseCallback,
                HelpCloseCB, (XtPointer)NULL);

Where helpDialog is the widget ID for the help dialog and HelpCloseCB is the name of the callback procedure you've written to handle closing dialogs.

To detect when a quick help dialog is closed, add the following callback to the dialog's OK button:

XtAddCallback (DtHelpQuickDialogGetChild (helpDialog,
 DtHELP_QUICK_OK_BUTTON), XmNactivateCallback, HelpCloseCB, (XtPointer)NULL);

Where helpDialog is the widget ID for the help dialog and HelpCloseCB is the name of the callback procedure you've written to handle closing dialogs.

Using the Application-Configured Button

The quick help dialog's application-configured button lets you add custom behavior to any quick help dialog. This button can be used for anything you want, but its intended purpose is to provide a path to more help in one of these two ways:

To Enable the Application-Configured Button

  1. Get the button's ID.

  2. Add an activate callback to the button.

  3. Manage the button.

Example

The following code segment gets the button's ID, assigns a callback, and manages the button. It assumes that quickHelpDialog was just created.

Widget  moreButton;
moreButton = DtHelpQuickDialogGetChild (quickHelpDialog,
                                      DtHELP_QUICK_MORE_BUTTON);
 XtAddCallback (moreButton, XmNactivateCallback,
                MoreHelpCB, NULL);
 XtManageChild (moreButton);

See Also

Chapter 12 Providing Help on Help

This chapter explains how to incorporate a help volume into your application that describes the features of the Help System and how to use them. This help volume provides help on using the Help dialog boxes.

Providing Help on Help

Help on help tells users how to use the Help System. Specifically, it describes such tasks as using hyperlinks, navigating topics, using the index, and printing help topics. Normally, help on help is supplied as an individual help volume named Help4Help.

The Help4Help volume and its source files are included in the Developer's Toolkit. You can use the default volume "as is," or modify it for your application's design.

For Application Help

If you are writing application-specific help, there are two ways to ensure that your application has help on help for its own help dialogs:

For Standalone Help

If you are writing standalone help, you are probably relying on the Helpview program already being installed and ready to use. If this is the case, you don't have to worry about help on help because Helpview accesses the standard Help4Help volume by default.

How Help on Help Is Found

Each application that uses the Help System (including Helpview) has a helpOnHelpVolume resource that identifies a help volume to be accessed for help on help topics. For Helpview, this resource is set as follows:

DtHelpview*helpOnHelpVolume:  Help4Help

If you provide your own help on help volume, be sure to give it a unique name so it doesn't conflict with another help on help volume that may be installed on the system.

Accessing Help on Help in an Application

Your application should do the following to support help on help:

To Set the helpOnHelpVolume Resource

    Add a line to your application's application-defaults file like this:

 
App-class*helpOnHelpVolume:  volume

Where App-class is the application's class name and volume is the name of the help on help volume you want to access.

Or, within your application, set the helpOnHelpVolume resource for each help dialog you create.

Examples

To Provide a Using Help Command

  1. Add to your Help menu a button labeled Using Help. Also add the necessary activate callback to call your HelpRequestCB() function.

  2. Add support to your HelpRequestCB() function to display help on help. Specifically:

    • Create a quick help dialog.

    • Set the dialog's title to Help On Help.

    • Display the home topic of the help on help volume.

    • Manage the quick help dialog.

Example

The following lines create a menu button labeled Using Help... that calls the HelpRequestCB() function.

/* Create the ` Using Help ...' button. */
labelStr = XmStringCreateLtoR ("Using Help ...",           XmSTRING_DEFAULT_CHARSET);
 ac = 0;
 XtSetArg (al[ac], XmNlabelString, labelStr);     ac++;
 button = XmCreatePushButtonGadget (parent, "usingHelpButton", al,  ac);
    XtManageChild (button);
    XmStringFree (labelStr);
    /* Add a callback to the button. */
   XtAddCallback (button,XmNactivateCallback,HelpRequestCB,
    USING_HELP);

USING_HELP is the client data passed to the HelpRequestCB() function when the menu button is chosen by the user. Presumably it has been defined somewhere in the application (perhaps in a Help.h file) as a unique integer:

#define USING_HELP  47

To see how the HelpRequestCB() function handles the USING_HELP case, see the example in the next section, "To Display Help on Help."

To Display Help on Help

  1. Create a quick help dialog (or retrieve one from your cache).

  2. Display in the dialog the home topic of your help on help volume.

    Help on help can be displayed in a general help window. However, a quick help dialog is recommended because its user interface is simpler, which is less intimidating to new users who commonly need help on help.

Example

The following program segment is part of a HelpRequestCB() function. Presumably, the USING_HELP constant is passed to the function because the user chose Using Help from the application's Help menu or chose the Help button in a quick help dialog.

This example assumes that the application never creates more than one Help On Help dialog and maintains its widget ID in a variable called onHelpDialog.

case USING_HELP:
   if (onHelpDialog == (Widget)NULL)
      {
         /* Get a quick help dialog for use as the ` help on help' dialog. */
         onHelpDialog = FetchHelpDialog (True);
 
        if (onHelpDialog == (Widget)NULL)
           /* We didn't get a dialog! Add your error handling code here. */
      }
 
   /* Set the proper volume and ID to display the home topic of
       the help on help volume. Also, set the dialog's title.   */
    ac = 0;   XtSetArg (al[ac], XmNtitle,  "Help On Help");     ac++;
    XtSetArg (al[ac], XmNhelpType,   DT_HELP_TYPE_TOPIC); ac++;
    XtSetArg (al[ac], XmNhelpVolume, "Help4Help");        ac++;
    XtSetArg (al[ac], XmNlocationId, "_hometopic");       ac++;
    XtSetValues (onHelpDialog, al, ac);
 
   /*  If the ` help on help' dialog is already managed, it might
        be in another workspace, so unmanage it.  */
    if (XtIsManaged (onHelpDialog))
      XtUnmanageChild (onHelpDialog);
 
   /* Manage the ` help on help' dialog. */
    XtManageChild (onHelpDialog);
 
   break;

To see how the rest of the HelpRequestCB() function might be structured, refer to the example in "To Add a Help Callback".

See Also

Writing Your Own Help on Help Volume

If you need to provide your own help on help volume, you should start with the existing Help4Help volume and then make the necessary changes. All the source files used to write the Help4Help volume are provided in the /usr/dt/dthelp/help4help/C directory.

To prevent installation conflicts, name your help on help volume something other than Help4Help. Consider picking a name that is specific to your product. For example, if your application's help volume is Newapp, your help for help volume could be NewappH4H.

Required Entry Points

To ensure that context-sensitive help within a help dialog operates correctly, you must provide the following entry points (IDs) within your help on help volume. (These are already included in the Help4Help source files.)

ID 

Fopic Description 

_hometopic

Displays an introduction to using the help system. This topic is displayed when you choose Using Help from the general help dialog's Help menu, or when you press F1 in a quick help dialog. (The ID _hometopic is created automatically by the <hometopic> element.)

_copyright

Displays the copyright and version information for the help on help volume. This topic is displayed when you choose Version from the general help dialog's Help menu. (The ID _copyright is created automatically by the <copyright> element.)

history

Displays a topic that describes how to use the History dialog. This topic is displayed when you choose Help or press F1 within the History dialog. 

printing

Displays a topic describing how to use the Print dialog. This topic is displayed when you choose Help or press F1 within the Print dialog. 

index-search

Displays a topic describing how to use the Index Search dialog. This topic is displayed when you choose Help or press F1 within the Index Search dialog. 

volume-select

Displays a topic describing how to use the Search Volume Selection Dialog. This topic is displayed when you choose Help or press F1 within the Search Volume Selection Dialog. 

To Copy the Help4Help Source Files

  1. Copy the entire /usr/dt/dthelp/help4help/C directory to a new working directory (new-dir) using a command like this:

     cp -r /usr/dt/dthelp/help4help/C new-dir 
    

    This creates new-dir and copies all the files and directories into it.

  2. To permit editing the files (which are copied as read only), change the permissions using a command like this:

     chmod -R u+w new-dir 
    

    The Help4Help volume uses these HelpTag source files:

    • MetaInfo

    • Toc

    • Tasks

    • HomeTopic

    • Concepts

    • Reference

    • Glossary

    Also included is a control directory, where you run HelpTag to create the run-time help file. Graphics are stored in the control/graphics subdirectory.

    Be sure to rename the Help4Help.htg file before running HelpTag. Your help on help volume should have a unique name to prevent conflicts with other help on help volumes.

Example

The following commands create a copy of the help on help volume and make its files writable. (Presumably the projects subdirectory already exists.)

cp -r /usr/dt/dthelp/help4help/C /users/dex/projects/NewHelp4Help
 chmod -R u+w /users/dex/projects/NewHelp4Help

To build a new version of the run-time help files, first ensure that the directory /usr/dt/bin is in your search path. Then, change to the new directory, rename the Help4Help.htg file, and run HelpTag:

cd /users/dex/projects/NewHelp4Help
mv Help4Help.htg NewH4H.htg
 dthelptag NewH4H

When the HelpTag software is done, you can display the new help on help volume using this command:

dthelpview -helpVolume NewH4H

Chapter 13 Preparing an Installation Package

This chapter identifies the help files that are included in an application installation package. It also describes how help files are handled when your application is registered on the desktop.

Overview

When it comes time to prepare your final product, you must be sure that all your help files are created and installed properly. Your product package includes both the run-time help file (volume.sdl) and its graphic files. Additionally, you can provide a help family file that enables your volume to be viewed using the Front Panel Help Viewer.

Delivering Online Help

Online help can be fully integrated into an application or provided as a standalone help volume. Fully integrated help allows a user to directly access help information from an application by using a Help menu or Help key. A standalone volume on the other hand, can only be displayed using the desktop Help Viewer.

A system administrator may choose to add a standalone help volume to the desktop when an application does not provide integrated help or a customized environment provides a supplemental help volume. See "Standalone Help" for instructions to install a standalone volume on the desktop.

Creating an Installation Package

Your installation package should include these help files:

The run-time help file and any graphics used in the online help are included in your installation package. A help family file is optional for integrated application help. However, if you want your application help to be browsable using the desktop Help Viewer, you must provide a family file. If you are delivering a standalone help volume, you must provide a help family file. See "To Create a Help Family ".

If your application's help volume includes execution links, it is recommended that the author define execution aliases in an application defaults file. This takes advantage of the Help System's default execution policy which will automatically execute links with execution aliases. However, if the help volume is viewed as an independent volume using a separate information viewer, such as the Help Viewer, the Help System will display a confirmation dialog box when an execution link is selected.

Figure 13-1 shows a typical installation package for an application and its help files. Help files are grouped in a separate help subdirectory which contains a default language directory (C is the default). The run-time help file, family file, and graphics files are located in this directory.

Figure 13-1 Application installation package

Graphic

If your application provides online help in multiple languages, you should create a language subdirectory to accommodate each language (where language matches the user's LANG environment variable). For example, an application that provides both an English and German user interface stores its corresponding online help in two subdirectories: C for English and german for German.

Run-Time Help File

HelpTag creates a single run-time help file, volume.sdl. The base name, volume, is the same as the base name of your volume.htg file. The Help Viewer uses information stored in this master help file and also accesses any associated graphic files.

You don't need to ship the volume.htg or any additional files generated by the HelpTag software.

Graphics Files

If your help volume uses graphics, the image files are typically stored in a separate directory for convenience. However, you may choose to store them in the same location as your volume.htg file.

A run-time help file does not include actual graphic images. Instead, it contains a "reference" to the location of each graphic file. When you run HelpTag, the dthelptag compiler incorporates the relative path names of the graphics files into the help volume.

When the help files are installed, the graphics files must be in the same relative position as when the run-time file was built. Otherwise, the help volume will be unable to locate the graphics files. For example, if your graphics files are in a subdirectory named graphics one level below your volume.htg file, then your installation package must preserve that relative position. The graphics files must be placed in a subdirectory named graphics one level below the volume.sdl file.

Figure 13-2 Relationship of build directories and installation package

Graphic

Help Family File

You can optionally provide a help family file (volume.hf). A family file briefly describes your help volume and includes copyright information. It can also be used to group one or more related volumes into a single product category.

If you want your help volume to be accessible from the desktop browser volume, then you must provide a family file in your installation package. To create a family file, see "To Create a Help Family ".

Registering Your Application and Its Help

The desktop's integration utility, dtappintegrate, registers your application and its help files by creating symbolic links between the installed application files and specific desktop directories. Application registration ensures that your help files are located in the directory search paths used by the Help System.

Registration enables two important features of the Help System:

Registering your online help makes it easier to access the help you provide. For authors and programmers, it's easier because references to your volume can use just the volume name -- without specifying the volume's actual location.

If you register a help family with one or more help volumes, you make your help available for general browsing from the Front Panel Help Viewer. This allows access to application-specific help without using the application. Or, if you are writing standalone help, this is the only way for users to get to your help.

Standalone Help

A standalone help volume for an application or a customized environment can be created using the Help System Developer's Kit. To make the help volume accessible from in the desktop browser volume, a system administrator installs the run-time help file, associated graphics, and family file in the /etc/dt/appconfig/help/language directory.

Remember that the run-time help file and its graphics files must be installed in the same relative position as when the help volume was built. See "Graphics Files" to review the installation of graphics files.

What Happens When the Application Is Registered

Application registration creates symbolic links from the run-time help file and family located in app_root/dt/appconfig/help/language to the /etc/dt/appconfig/help/language directory.

Refer to the CDE Advanced User's and System Administrator's Guide for detailed instructions for application registration.

How a Help Volume Is Found

The Help System uses desktop search paths to locate help volumes. When help is requested within an application or a help volume is specified in a command line, the help volume is found by checking a set of search path directories. You can control the directory search path for help volumes by modifying several environment variables. Refer to the CDE Advanced User's and System Administrator's Guide for detailed information about specifying search paths.

Product Preparation Checklists

The following checklists should help you verify that you've prepared your product correctly. Of course, there's no substitute for testing your product by using it as a user will.

For Authors

  1. A final version of the run-time help file was created.

    Here are the recommended commands for creating the run-time file:

    dthelptag -clean volume
     dthelptag volume nomemo onerror=stop

    The -clean option removes files from any previous dthelptag command, the nomemo option ensures that writer's memos are not displayed, and the onerror=stop option stops processing if any parser errors occur. You should not distribute a help volume that has any parser errors.

  2. All hyperlinks have been tested.

    Each hyperlink displays the proper topic or performs the correct action.

  3. Execution aliases have been defined for execution links.

    Execution aliases are defined as resources in the application's application defaults file. An execution alias associates a name with a shell command to be executed. If you have used execution links in your help volume, coordinate with the application developer to add these resources to the application defaults file. For more information, refer to "Execution Aliases".

  4. All graphics are acceptable.

    The graphics have been tested on various color, grayscale, and monochrome displays.

For Product Integrators

  1. The run-time file is installed.

  2. All graphics are installed in the proper locations.

    Each graphics file must be installed in the same relative position to the .sdl file that it was in relative to the.htg file when the HelpTag software was run.

  3. The help volume is registered.

    The dtappintegrate script was run to create symbolic links from the installation directory to the registration directory.

  4. A product family file is installed and registered.

    The family file is installed with the other help files. When dtappintegrate is run, it creates a symbolic link for the family file. Registering a family file for your help volume is optional. However, if you choose not to register a family file, your help volume will not be accessible from the Front Panel Help Viewer.

For Programmers

  1. The application sets the correct values for these required resources:

    App-class*helpVolume:        volume
     App-class*helpOnHelpVolume:  help-on-help-volume 
    

    The helpVolume resource identifies the help volume for your application.The helpOnHelpVolume identifies the help volume that contains the help on using the help system.

  2. Execution aliases are included in the application defaults file.

    An author defines execution aliases as application resources. An execution alias associates a name with a shell command to be executed. If execution links have been used in the help volume, check with the author to identify the resources that need to be added. For more information, refer to "Execution Aliases".

  3. The application sets the desired values for the following optional resources:

    App-class*DtHelpDialogWidget*onHelpDialog*rows:     rows
     App-class*DtHelpDialogWidget*onHelpDialog*columns:  columns
     App-class*DtHelpDialogWidget*definitionBox*rows:    rows
     App-class*DtHelpDialogWidget*definitionBox*columns: columns 
    

    The onHelpDialog resources control the size of the quick help dialogs used to display Help on Help. The definitionBox resources control the size of the quick help dialog used for definition links.

  4. The application uses either the default font resources or defines font resources in the application's application-defaults file.

    In most cases an application can rely on the default font resources. However, when custom fonts are used, they must be defined in the application-defaults file. Sample font schemes are provided in the /usr/dt/dthelp/fontschemes directory. See Chapter 14, Native Language Support, for additional information about font schemes.