Help information is the information about how to use an application. By describing an application's choices, objects, and interaction techniques, help information can assist users in learning to use a product.
The Open Class Class Library provides an IHelpWindow class that uses either native Windows help (Rich Text Format) or the OS/2 Information Presentation Facility (IPF) to provide help information for applications. To view the help file on Windows, use IVIEW.EXE. On OS/2, the executable is VIEW and on Motif it is xview.
You create and associate an IHelpWindow object with one of
your
application's main windows. The Open Class Class Library also
provides an IHelpHandler class to process help window events.
When you associate an application window with a help window, help
events are dispatched to the help handlers attached to the
application window.
To use the IHelpWindow class, you create and associate an IHelpWindow object with one or more of your application's main windows. The help panels displayed by IHelpWindow are written and compiled using tools native to your development environment or provided with VisualAge for C++ for Windows. To present a consistent look and feel for help across development environments, use the IPF help information compiler and runtime. On the Windows environment, you can also display your information using the native Windows help facility. Although the process of generating the help information is different, and the display and interaction of the Windows help facility is different from IPF, you can still use the classes of IHelpWindow to interact with native Windows help. However, some of the IHelpWindow functions have no equivalent for Windows help and therefore return without performing any operation. See the IHelpWindow class in the Open Class Library Reference for information on behavior in the Windows environment.
To use IPF help files, call the following before constructing your IHelpWindow objects:
IHelpWindow::setDefaultStyle( IHelpWindow::ipfCompatible );
By default, IHelpWindow uses native Windows help.
In some cases, you may want to override the behavior of the help facility. You can attach an IHelpHandler object to a frame window that has been associated with a help window. By default, the IHelpHandler provides meaningful message boxes when odd situations occur, such as the help file not being found. To override this behavior, derive your own class from IHelpHandler and overide the functions you need to change.
Use the following steps to create IPF help information for
your
application:
Create the source text that displays in your application's help window using the IPF format (.ipf file) for the OS/2 operating system and the IPF/X format (.ipf file) for the Windows and Motif environments. Compile your file into a help file (.hlp file) using the IPFC compiler.
Refer to the Information Presentation Facility documentation for descriptions of the tags you use to create the source .ipf file.
For an example of a .ipf source file, see the Hello World version 5 ahellow5.ipf file, which is described in Hello World Version 5: Adding Canvases, a List Box, Native System Functions, and Help.
STR_HTITLE, "C++ Hello World - Help Window" //Help window title string POPUP "&Help" , MI_HELP , RIGHTJUSTIFY BEGIN MENUITEM "&General help..." , SC_HELPEXTENDED /*MIS_SYSCOMMAND*/ MENUITEM "&Keys help..." , SC_HELPKEYS /*MIS_SYSCOMMAND*/ MENUITEM "Help &index..." , SC_HELPINDEX /*MIS_SYSCOMMAND*/ END
The AIX and OS/2 .rc file appears as follows:
STR_HTITLE, "C++ Hello World - Help Window" SUBMENU "~Help", MI_HELP, MIS_HELP BEGIN MENUITEM "~General help...", SC_HELPEXTENDED, MIS_SYSCOMMAND MENUITEM "~Keys help...", SC_HELPKEYS, MIS_SYSCOMMAND MENUITEM "Help ~index...", SC_HELPINDEX, MIS_SYSCOMMAND END
Applications with .rc files that use the following constants should include the icconst.h file:
SC_HELPKEYS SC_HELPINDEX SC_HELPEXTENDED
MI_HELP is the help menu ID.
Normally, you specify MIS_HELP for a menu item to cause a help event, rather than a command event, to be posted when the menu item is selected.
When you specify MIS_HELP (OS/2) or RIGHTJUSTIFY
(Windows) for a submenu item, Motif automatically
positions the item to the far right of the menu bar. OS/2
PM ignores MIS_HELP specified on submenu items. Windows
NT 3.51 ignores RIGHTJUSTIFY specified on
submenu items.
When MIS_SYSCOMMAND is specified with the predefined SC_HELP* IDs, a system command event is generated. The default system command handler recognizes the predefined IDs and shows the appropriate help panel, except for SC_HELPKEYS, which by default does nothing. SC_HELP* IDs are defined in the <icconst.h> file. You can override this default processing for SC_HELPKEYS, using an IHelpHandler, which is described in a later step.
The help table defines the relationship between the window ID and the general or contextual panel ID that is defined in the .ipf file. The following help table is defined in the resource file, ahellow5.rc, for Hello World version 5:
HELPTABLE HELP_TABLE BEGIN HELPITEM WND_MAIN, SUBTABLE_MAIN, 100 HELPITEM WND_TEXTDIALOG, SUBTABLE_DIALOG, 200 END HELPSUBTABLE SUBTABLE_MAIN //Main window help subtable BEGIN // HELPSUBITEM WND_HELLO, 100 //Hello static text help ID HELPSUBITEM WND_LISTBOX,102 //List box help ID HELPSUBITEM MI_EDIT, 110 //Edit menu item help ID HELPSUBITEM MI_ALIGNMENT, 111 //Alignment menu item help ID HELPSUBITEM MI_LEFT, 112 //Left command help ID HELPSUBITEM MI_CENTER, 113 //Center command help ID HELPSUBITEM MI_RIGHT, 114 //Right command help ID HELPSUBITEM MI_TEXT, 199 //Text command help ID END // HELPSUBTABLE SUBTABLE_DIALOG //Text dialog help subtable BEGIN // HELPSUBITEM DID_ENTRY, 201 //Entry field help ID HELPSUBITEM DID_OK, 202 //OK command help ID HELPSUBITEM DID_CANCEL, 203 //Cancel command help ID END //
WND_HELLO and WND_LISTBOX are control IDs, MI_* are menu item IDs, and the DID_* are push button IDs. Each window ID is related to a help panel ID. In the preceding example, WND_MAIN and WND_HELLO both correspond to help panel ID 100. That is, pressing the F1 key in the main window area displays the same help panel as selecting General help... from the Help submenu.
Use the IHelpWindow class to associate help information with an application window. Hello World version 5 defines the private data member, helpWindow, as an IHelpWindow object. It is initialized in the AHelloWindow constructor in ahellow5.cpp using the following statement:
,helpWindow(HELP_TABLE,this)
The first parameter identifies the help table defined in the resource file. The second parameter identifies the application window for which the help is being provided.
Use the IHelpWindow::addLibraries member function to associate a help file with a help window. The AHelloWindow constructor in Hello World version 5 provides an example:
helpWindow.addLibraries("ahellow5.hlp");
You can set the title of the help window by using the IHelpWindow::setTitle member function. The following code sets the title from a string defined in the resource file:
helpWindow.setTitle(STR_HTITLE);
A help handler processes help events. Create your own help handler class derived from IHelpHandler to provide help event processing that is unique to your application. Hello World version 5 uses a help handler only to display the keys help panel describing accelerator key definitions.
To override keys help processing, do the following:
class AHelpHandler : public IHelpHandler { protected: virtual bool keysHelpId(IEvent& evt); };
bool AHelpHandler :: keysHelpId(IEvent& evt) { evt.setResult(1000); //1000=keys help ID in // ahellow5.ipf file return (true); //Event is always processed } /* end AHelpHandler :: keysHelpId(...) */
In the preceding code, the help panel ID for the Hello World version 5 keys help is set in the event result.
Your help handler, previously described, does not begin handling help events until you use the handleEventsFor member function. For example, the following code causes the helpHandler to begin processing help events for this frame window:
helpHandler.handleEventsFor(this);
Typically, you include this statement in the constructor for the frame window.
Note that the window that handles help events must be an associated window. That is, you should identify the window as the associated window on the IHelpWindow constructor or explicitly identify the window as an associated window using the IHelpWindow::setAssociatedWindow function.
When you want to stop handling help events, for example, when you close your frame window, use the stopHandlingEventsFor member function, as follows:
helpHandler.stopHandlingEventsFor(this);
You typically include this statement in the destructor for the frame window.
class ChildFrameHelpHandler : public IHandler { typedef IHandler Inherited; /******************************************************************************* * This handler enables the OS/2 Help Manager to use help tables to display * * contextual help for a child frame window (one whose parent window is not * * the desktop). This handler should only be attached to child frame windows. * *******************************************************************************/ public: virtual ChildFrameHelpHandler &handleEventsFor ( IFrameWindow* frame ), &stopHandlingEventsFor ( IFrameWindow* frame ); protected: virtual bool dispatchHandlerEvent ( IEvent& evt ); ChildFrameHelpHandler &setActiveWindow ( IEvent& evt, bool active = true ); private: virtual IHandler &handleEventsFor ( IWindow* window ), &stopHandlingEventsFor ( IWindow* window ); };
bool ChildFrameHelpHandler :: dispatchHandlerEvent ( IEvent& evt ) { switch ( evt.eventId() ) { case WM_ACTIVATE: setActiveWindow(evt, evt.parameter1().number1()); break; case WM_HELP: setActiveWindow(evt, true); break; default: break; } /* endswitch */ return false; // Never stop processing of event } ChildFrameHelpHandler& ChildFrameHelpHandler :: setActiveWindow ( IEvent& evt, bool active ) { IHelpWindow* help = IHelpWindow::helpWindow(evt.window()); if (help) { IFrameWindow* frame = 0; if (active) { frame = (IFrameWindow*)evt.window(); } help->setActiveWindow(frame, frame); } return *this; } ChildFrameHelpHandler& ChildFrameHelpHandler :: handleEventsFor ( IFrameWindow* frame ) { IASSERTPARM(frame != 0); Inherited::handleEventsFor(frame); return *this; } ChildFrameHelpHandler& ChildFrameHelpHandler :: stopHandlingEventsFor ( IFrameWindow* frame ) { IASSERTPARM(frame != 0); Inherited::stopHandlingEventsFor(frame); return *this; } IHandler& ChildFrameHelpHandler :: handleEventsFor ( IWindow* window ) { // private to hide version in IHandler ITHROWLIBRARYERROR(IC_MEMBER_ACCESS_ERROR, IErrorInfo::invalidRequest, IException::recoverable); return *this; } IHandler& ChildFrameHelpHandler :: stopHandlingEventsFor ( IWindow* window ) { // private to hide version in IHandler ITHROWLIBRARYERROR(IC_MEMBER_ACCESS_ERROR, IErrorInfo::invalidRequest, IException::recoverable); return *this; }
You can assign helpIDs directly to windows by using IWindow::setHelpId( unsigned long topicId ); while maintaining portability. When F1 is pressed, the window with focus is then be queried for its context helpID and if one is found, it is used to identify the help panel to display. If one is not found and there is a help table, it is searched for the appropriate helpID to use.
If you are not using a help table, the helpId of the active frame is used as the general help panel.
By default, IHelpWindow uses the native help for the platform to handle help requests using a .hlp file that was created from RTF or IPF source. This allows the code you write to be portable while giving your users native look-and-feel. IPF help files are also portable between the various platforms. RTF help files are not portable. In addition, some functions provided by IPF are not available when using Windows native help (RTF). The major differences are as follows:
Refer to the Open Class Library Reference for more information on IHelpWindow and IHelpHandler.
Fly-over help displays short help windows for the object that the mouse pointer is currently positioned over. As users move their mouse pointer over various objects, different help windows are displayed. In addition, you can display descriptive text for the object in a text control, such as the information area at the bottom of the window.
You can use the following classes to add fly-over help to your applications:
The following figure shows an example of fly-over help used on a toolbar.
The IFlyText control displays help messages in a bordered window that is sized large enough to contain the help text. The text is displayed using one row that does not reflow. The default font used to display the help messages in PM is 8-point Helvetica.
The IFlyText control positions itself relative to one of the
corners of the window the mouse pointer is over. Fly-over help
displays the help message so that none of the text is drawn
outside the desktop. This determines the corner
of the IFlyText control from which the arrow is drawn. The order
in which the IFlyText control attempts to position itself is as
follows:
You can construct instances of this class from a given window ID and an owner window.
For example:
IFrameWindow frameWindow( 0x1000 ); IToolBar toolbar( 0x1001, &frameWindow, &frameWindow ); IFlyText flyText( 0x1002, &toolbar ); IFlyOverHelpHandler flyOverHelpHandler( &flyText ); flyOverHelpHandler.handleEventsFor( &toolbar );
IFlyText provides the function setText to set the accessible
attributes of each instance, and it provides functions
setRelativeWindowRect and
relativeWindowRect to set and query the position relative to the
IFlyText control.
The control ID of IFlyText is ignored.
By attaching an IFlyOverHelpHandler to a window, you can provide context-specific help messages for any window that is a child of the window you attached the handler to.
You can use the IFlyOverHelpHandler to update an IFlyText control, an ITextControl, or both. The IFlyText control contains short messages (one or two words, for example) for a window, and ITextControl displays more descriptive text in the information area. You do not need a string associated with every window in your application. When a help string cannot be found for a window, a single blank is displayed by default to keep the frame extension handler from hiding the ITextControl when it contains a null string. You can also use the setMissingText function to set the text to be displayed when an information string cannot be found.
Note: | New-line characters are removed from a string before they are displayed in the IFlyText control. |
The last two parameters of each handler constructor are time delays expressed in milliseconds. The first delay, indicates the time the mouse pointer must remain in in the same location before the fly-over help is displayed for the first time. The second delay, indicates the time the mouse pointer must remain in the same location after the fly-over help has been displayed for the first time.
You can change the length of the first delay using the
setInitialDelayTime member function or query what is currently
set using the initialDelayTime member function. Use the
setDelayTime member function to change the second
delay and use delayTime to query what is currently set for that
second delay.
You associate context-specific help for a window to a help message by specifying a window identifier. This identifier is used with an offset to load strings from a string table. Specify different offsets into the string table for the IFlyText and the ITextControl objects to display different help messages in each of the controls.
Note: | To display help for a window using the string, you must either create the window using the Open Class Library or wrapper an existing window. |
You can also dynamically associate help text to a window using
IFlyOverHelpHandler, a window handler. This is useful when you
dynamically add controls to a canvas or push buttons to a tool
bar.
Use the following functions to dynamically add or remove the help text specified for a window:
For more information on these functions, see the Open Class Library Reference or refer to the toolbar samples in the \samples\ioc\tbar1 and \samples\ioc\tbar2 directory. These samples show you how to incorporate fly-over help into your applications.
Adding Menus to your Application
Adding a Menu Bar
Adding Events and Event Handlers
IFlyText
IFlyOverHelpHandler
IHelp
IHelpHandler