Connecting HTML Help To C++ & MFC Programs
Connecting HTML Help To C++ & MFC Programs
by Don Lammers
Scope
Although optimized for WinHelp (as of Visual Studio 6), MFC provides several hooks for easily connecting to
any online help, including HTML Help and HTML based help. In addition, you can call the HtmlHelp API from
anywhere in your program for additional access to help. The Connecting Context Sensitive Help to C++/MFC
Programs section shows how to connect to the built in hooks that MFC provides, and is therefore specific to
programming with MFC. The remainder of the document should be easily adaptable to any version of C++, as it
sets forth the Windows calls and command line interface for HTML Help.
Acknowledgements
The following information is from my own experimentation and from people who have walked this path before
me. Thanks to all of the following:
Microsoft HTML Help WorkShop Help, Microsoft Knowledge Base, The Developer's Guide to WINHELP.EXE
(Jim Mischel), Building Windows 95 Help (Nancy Hickman), Paul O'Rear, Developing Online Help for Windows
95 (Boggan, Farkas, and Welinske), Gordon F. MacLeod, Burt Abreu.
Note:
• The above creates support for WinHelp. The following sections show how to override this to call HTML
Help or HTML based help.
• Since no dialog boxes are created in this process, you will need to add context sensitive help support for
each dialog box as you create it.
• Once you have the initial help file and .hm file, it is usually easier to have the help author add new topics
using their preferred help authoring tool. You can still have the program generate the framework help
each time you build, because that will give you appropriate additional topic mapping entries.
Tips:
• m_pszHelpFilePath can be changed at runtime, so you can reset it in code as needed to call additional
help files.
• If you have more than one help file to call from the program you should put the code for changing help
file names in a separate subroutine. This makes any changes during the project much easier to implement.
• You can let the help author edit the help file name and window specification by putting them in a separate
text file. Setting this file up in INI file format lets you use standard INI file commands to access this "text
database."
To ensure that the program and HTML Help can always find the help file:
• Register the help file by creating a string value under
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\HTMLHelp. The name of the string value is
the help file name (without path) and the value is the path.
• Always use the full path and file name when setting m_pszHelpFilePath, even if the help file is in the
same folder as the program executable.
Note:
• This creates the same basic hooks in the program as the App Wizard, but does not generate a framework
help file or the .hm file with the topic ID mapping. You will need to create a list of IDs for the help author
to use.
Tips:
• It is often easier to create a separate function or class to process the help calls and open topics in the
correct window. This can be part of the main program or can be created as a separate DLL. The main
advantage of a DLL is that it can be called from other programs if necessary.
• If you want the help author to be able to control the help file and window called by this function, class, or
DLL, put the help file and window definitions in an INI file (you can use the topic number as the key) and
look them up before calling Help. If you include the help type as an INI file entry you can easily call
multiple types of user assistance from the same program.
Note:
• You cannot add the What's This? Help button to any resizeable window or to a tool window.
Tip:
• If you want the What's This? Help button in a tool window, make it a Fixed Dialog window instead. The
only difference I've ever seen is that the title bar is slightly smaller on a tool window.
To intercept the call and display the topic number for troubleshooting:
This simply shows the topic number called. To activate it you need to put a ShowTopicNumber=1 entry in the
[Genera] section of a text file that has the DLL path and name but with a .dat extension. This little bit of code
can often save hours of arguing over where the context help calls are broken, since it shows the exact numeric
value being sent by the program to help.
//See if we are supposed to display the topic number for debugging
char iniFile[256];
ChangeExtension(cDLLName, ".dat", iniFile);
if (GetPrivateProfileInt("General", "showTopicNumber", 0, \
iniFile) != 0) {
char buffer[256];
wsprintf(buffer, "About to open topic number %d \
(%X hex)", Topic, Topic);
MessageBox( NULL, buffer, \
"Topic Number", MB_OK | MB_ICONINFORMATION );
}
Notes:
• The above code filters out any messages coming from controls assigned an ID of IDC_STATIC. If you
want static controls (labels) to also have context help, they must each be assigned unique identifiers.
• Since all controls in a program should have unique IDs, you may be able to use the control ID rather than
the context ID for this function. This is a smaller number and easier to deal with in the help mapping
(sorry, just being lazy).
Tip:
• Unless there are only a few controls that do not implement a right click menu, I recommend calling the
topic directly if the user right clicks a button that does not otherwise have a right click menu. A popup
menu with a single What's This? item looks a bit strange, and this saves the user one click.
Note: The filename may be followed by an angle bracket (>) and the name of a secondary window if the topic
is to be displayed in a secondary window rather than in the primary window. The name of the secondary
window must have been defined in the [WINDOWS] section of the help project (.hhp) file.
uCommand specifies the type of help requested. For a partial list of possible values and how they affect the
value to place in the dwData parameter, see Help Command Constants below. For a full list, see the Microsoft
HTML Help Workshop Help.
dwData specifies additional data. The value used depends on the value of the uCommand parameter. For a
partial list of possible values, see Help Command Constants below. For a full list, see the Microsoft HTML Help
Workshop Help.
Note:
• This structure contains standard Windows POINTAPI and RECT structures, which must be defined in the
project. You can get these structures from the API Text Viewer that came with Visual Basic.
To display the Contents tab in the navigation pane and open the default topic:
HtmlHelp(m_hWnd, m_pszHelpFilePath, HH_DISPLAY_TOC, ByVal 0&);
To display the Contents tab in the navigation pane and open a specific topic:
HtmlHelp(m_hWnd, m_pszHelpFilePath & \
"::/RelativeFolder\\TopicFileName.htm", \
HH_DISPLAY_TOPIC, ByVal 0&);
-OR-
HtmlHelp(m_hWnd, m_pszHelpFilePath, HH_DISPLAY_TOPIC, \
ByVal "RelativeFolder\\TopicFileName.htm");
To force all HTML Help windows closed that were opened by this app:
HtmlHelp(0&, "", HH_CLOSE_ALL, ByVal 0&);
The wParam value for the WM_TCARD message is one of the following:
IDABORT The user clicked an authorable Abort button.
IDCANCEL The user clicked an authorable Cancel button.
IDCLOSE The user closed the training card.
IDHELP The user clicked an authorable Help button.
IDIGNORE The user clicked an authorable Ignore button.
IDOK The user clicked an authorable OK button.
IDNO The user clicked an authorable No button.
IDRETRY The user clicked an authorable Retry button.
IDYES The user clicked an authorable Yes button.
HELP_TCARD_DATAThe user clicked an authorable button. The lParam parameter contains a long integer
specified by the help author.
HELP_TCARD_NEXT The user clicked an authorable Next button.
HELP_TCARD_OTHER_CALLER Another program has requested training cards.
If wParam is HELP_TCARD_DATA, lParam is the number indicated by the TCARD macro. Otherwise
lParam is 0 (zero).
Resources
All of the following plus links to other reference sites about online user assistance are available through the
Shadow Mountain Tech Web site (www.smountain.com).
On the Help/Connecting page:
• Latest update of this document and other documents about connecting online help to your program
• Programmer's Reference to WinHelp (by Don Lammers and Paul O'Rear)
• Sample code, including API definition modules.
• David Liske's help subclassing tutorial and modules
On the Help/Bugs & FAQ page:
• WinHelp 4.0 Unofficial Bug and Anomaly List (currently maintained by Don Lammers)
• WinHelp FAQ File (by Charlie Munro)