Today our main app’s help system broke.  I hate that when it happens.  This app is built with Delphi, which supports WinHelp (*.hlp) files for context sensitive help.  A long time ago, I added some code to allow our apps to use HTML Help (*.chm).  It was fairly trivial to implement and once I got it working, we never had to look at that code again.

Until today.  The latest build of the help file didn’t work.  We pressed the help button and nothing happened.  Yet, if we ran the help file outside our app, it loaded up just fine.  Obviously something had changed, the question was what had changed.

The first step was to fire up the app and step through the code.  To use HTML Help with Delphi, I use some open source code that provides a Delphi wrapper for the function calls in hhctrl.ocx.  When I stepped through the code,   I ended up here:

h := HtmlHelp(0, PChar(mHelpFile), HH_HELP_CONTEXT, 5000);  // data = helpcontext id

The mHelpFile variable is the full path the .chm file.  HtmlHelp mapped to HtmlHelpA in hhctrl.ocx.  5000 the context id for the start page in the .chm.  It’s set to 5000 because nothing defaults to that value.  If the context id’s are not defined correctly, it wont have a context ID of 5000.  The code would call HtmlHelp and 0 was being returned.  In this context, 0 means that the context id of 5000 doesn’t exist in the .chm file.  It’s the same thing as calling the HtmlHelp executable, hh.exe, with the -mapid parameter.

hh.exe -mapid 5000 myfile.chm

So that’s my theory, next step is to prove that ID’s are missing or incorrect.  The guy who generated the .chm file was gone for the day and I don’t have to toys used to create the .chm file.  But I did have the .chm file.  Keyworks has a nice (and free) utility called KeyTools for working with HTML Help files.  One of the things it can do is to decompile the .chm file back to the source files.  I did that and opened up the .hhp file and sure enough the context id’s were all wrong.