Introduction
I recently had to add HTML help to an existing MFC dialog-based application. This article is my attempt to document what I learned.
NOTE: At one time, there was a checkbox when creating a new MFC application that indicated you wanted support for help. At the time of this writing, it appears Visual Studio 2017 no longer provides this option. I can't explain Microsoft's seemingly lackadaisical support for application help these days. But for the purpose of this article, there have been options to add support for HTML Help when your application is generated and this article is about adding support for HTML help in your dialog-based application after the application has been generated.
MFC Uses WinHelp by Default
The first thing I noticed is that, if I pressed F1 from my application's main dialog box, I got a pop-up error message that says "Failed to launch help." This let me know that, in fact, help was enabled. I just needed to alter a few things.
I also determined that, by default, the application was using WinHelp. WinHelp is the old Windows help format. And since Windows no longer ships with the WinHelp viewer, that won't be of much help for your users. (For information about viewing WinHelp files on newer versions of Windows, check out the article Error opening Help in Windows-based programs: "Feature not included" or "Help not supported".)
Configuring the application to use HTML help instead of WinHelp is easy enough. Just call EnableHtmlHelp() to set the internal m_eHelpType enum in the constructor of your main application class. (This is the class that derives from CWinApp.)
CMyWinApp::CMyWinApp()
{
EnableHtmlHelp();
}
At this point, all that seems to be missing is your correctly configured help file. You can press F1 from any dialog box, or click any button or menu command with the ID ID_HELP, and MFC will attempt to load your help file with the corresponding help topic.
Generate an HTMLDefines.h File
In order to have all the correct help topic IDs, you'll need an HTMLDefines.h file that includes the needed IDs from your application. While you could create this file yourself, we'll have Visual Studio create it for us. To do this, right click over Resource.h in the Visual Studio Solution Explorer and select the Properties command.
Set the Configuration dropdown to All Configurations. Then under the General section, set the Item Type to Custom Build Tool.
Once you've done that, click the Apply button and the Custom Build section will become visible. You need to set three settings in this section.
First, set the command line. You'll need to click the dropdown and select Edit. Then enter the following. (NOTE: You'll want to change [ProjectName] to the actual name of your project.
echo // Generated Help Map file. Used by [ProjectName].HHP. > "hlp\HTMLDefines.h"
echo. > "hlp\HTMLDefines.h"
echo // Commands (ID_* and IDM_*) >> "hlp\HTMLDefines.h"
makehm /h ID_,HID_,0x10000 IDM_,HIDM_,0x10000 "%(FullPath)" >> "hlp\HTMLDefines.h"
echo. >> "hlp\HTMLDefines.h"
echo // Prompts (IDP_*) >> "hlp\HTMLDefines.h"
makehm /h IDP_,HIDP_,0x30000 "%(FullPath)" >> "hlp\HTMLDefines.h"
echo. >> "hlp\HTMLDefines.h"
echo // Resources (IDR_*) >> "hlp\HTMLDefines.h"
makehm /h IDR_,HIDR_,0x20000 "%(FullPath)" >> "hlp\HTMLDefines.h"
echo. >> "hlp\HTMLDefines.h"
echo // Dialogs (IDD_*) >> "hlp\HTMLDefines.h"
makehm /h IDD_,HIDD_,0x20000 "%(FullPath)" >> "hlp\HTMLDefines.h"
echo. >> "hlp\HTMLDefines.h"
echo // Frame Controls (IDW_*) >> "hlp\HTMLDefines.h"
makehm /h /a afxhh.h IDW_,HIDW_,0x50000 "%(FullPath)" >> "hlp\HTMLDefines.h"
Second, change the Description to Generating map file for help compiler.
And finally, set Outputs to hlp\HTMLDefines.h;%(Outputs).
This will cause Visual Studio to create a file called HTMLDefines.h in the hlp subfolder every time you build your Visual Studio project.
Create Your Help Project
The next step is to create your help project file using HTML Help Workshop. This is old and clunky software, to be sure. But once you get the hang of it, you can get done what you need.
As recommended above, be sure to create your help project in a hlp folder (under your project folder). This should be the same folder that also contains the res folder.
Each topic gets it's own HTM file. If you have common styling, you can create a CSS file and include it in each HTM file just as you would on an HTML web page. There is obviously a lot you could do here with regard to styling, etc. The main point of using HTML for help is that it would give you all the flexibility and power of HTML when creating your help pages.
This article won't go into more depth about creating content with HTML Help Workshop. But we do need to go over what's needed to define the correct help topic IDs so that your help can be context sensitive, and also so you don't get any errors from topic IDs that are not correctly defined in your help file.
The first step here is to include the HTMLDefines.h we configured earlier in the help project. You do this by clicking the HtmlHelp API information button in HTML Help Workshop and adding the header file under the Map tab.
The trick here is to make sure you define all the help topics that your application might request. While it's possible to have various help commands and dialog controls that have their own topic ID, most IDs come from your dialog boxes. You can cover these by reviewing all your dialog IDs in Visual Studio's Resource View. And, if your dialog ID is IDD_ABOUTBOX, for example; then you need to define a help topic for HIDD_ABOUTBOX (with the extra "H" at the start).
Define these IDs by clicking HtmlHelp API information button and going to the Alias tab. Here, you can add each help topic ID and associated it with the corresponding HTM file.
Be sure to do this for all your dialog boxes, and any other help topic IDs that your application might request. Once your help is up and running, you should certainly spend time testing to make sure all topic requests succeed.
Conclusion
That's about it. With true support for help built in, Visual Studio will also rebuild your help project for you. I didn't get into that as it just wasn't necessary for me. I'll just be sure to rebuild the help project when I'm about to release my software. To test the help, just copy your CHM file to your applications Debug and Release folders.
If everything is working, you will see context-sensitive help whenever the user hits F1 from any of your dialog boxes, or clicks on a button or menu command with the ID ID_HELP.
End-User License
Use of this article and any related source code or other files is governed
by the terms and conditions of
.
Author Information
Jonathan Wood
I'm a software/website developer working out of the greater Salt Lake City area in Utah. I've developed many websites including Black Belt Coder, Insider Articles, and others.