HTML Help in MFC – Tales from the Crypto

HTML Help in MFC

I recently got around to converting an old MFC project from WinHelp format to HTML Help. Mostly this was to satisfy customers who are using Windows Vista or Windows Server 2008, but who don’t want to install WinHlp32 from Microsoft. (If you do want to install WinHlp32, you can find it for Windows Vista or Windows Server 2008 at Microsoft’s download site.]

Here’s a quick round trip of how I did it:

1. Convert the help file – yeah, this is the hard part, but there are plenty of tools, including Microsoft’s HTML Help Editor, that will do the job for you. Editing the help file in HTML format can be a little bit of a challenge, too, but many times your favourite HTML editor can be made to do the job for you.

2. Call EnableHtmlHelp() from the CWinApp-derived class’ constructor.

3. Remove the line ON_COMMAND(ID_HELP_USING, CWinApp::OnHelpUsing), if you have it – there is no HELP_HELPONHELP topic in HTML.

4. Add the following function:

void CWftpdApp::HelpKeyWord(LPCSTR sKeyword)
{
HH_AKLINK akLink;
switch (GetHelpMode())
{
case afxHTMLHelp:
akLink.cbStruct = sizeof(HH_AKLINK);
akLink.fReserved=FALSE;
akLink.fIndexOnFail=TRUE;
akLink.pszKeywords=sKeyword;
akLink.pszMsgText=(CString)”Failed to find information in the help file on ” + sKeyword;
akLink.pszMsgTitle=”HTML Help Error”;
akLink.pszWindow=NULL;
AfxGetApp()->HtmlHelp((DWORD_PTR)&akLink,HH_KEYWORD_LOOKUP);
break;
case afxWinHelp:
AfxGetApp()->WinHelp((long)(char *)sKeyword,HELP_KEY);
break;
}
}

5. Change your keyword help calls to call this new function:

((CWftpdApp *)AfxGetApp()->WinHelp((long)(char *)”Registering”);

Becomes:

HelpKeyWord(“Registering”,HELP_KEY);

6. If you want to trace calls to the WinHelp function to watch what contexts are being created, trap WinHelpInternal:

void CWftpdApp::WinHelpInternal(DWORD_PTR dwData, UINT nCmd)
{
TRACE(“Executing WinHelp with Cmd=%d, dwData=%d (%x)\r\n”,nCmd,dwData,dwData);
CWinApp::WinHelpInternal(dwData,nCmd);
}

This trace comes in really, really (and I mean REALLY) handy when you are trying to debug “Failed to load help” errors. It will tell you what numeric ID is being used, and you can compare that to your ALIAS file.

7. If your code gives a dialog box that reads:

—————————
HTML Help Author Message
—————————
HH_HELP_CONTEXT called without a [MAP] section.
—————————
OK
—————————

image_2

 

What it means is that the HTML Help API could not find the [MAP] or the [ALIAS] section – without an [ALIAS] section, but with a [MAP] section, this message still will appear.

8. Don’t edit the ALIAS or MAP sections of your help file in HTML Help Editor – Microsoft has a long-standing bug here that makes it crash (losing much of your unsaved work, of course) unpredictably when editing these sections. Edit the HHP file by hand to work on these sections.

9. Most of your MAP section entries are automatically generated by the compiler, as .HM files, which hold macros appropriate for the specific control in the right dialog. Simply include the right HM file, and all you will need to do is create the right ALIAS mappings.

10. The MFC calls to HtmlHelp discard error returns from the function, so there’s really no good troubleshooting to go on when debugging access to help file entries.

Let me know if any of these helpful hints prove to be of use to you, or if you need any further clarification.

One Response to HTML Help in MFC

Leave a Reply

Your email address will not be published. Required fields are marked *