Revisited: HtmlHelpTest and makehhp -



Click here for larger image



Click here for larger image

Documentation

Environment: MSVC++6.0 SP3, Win98/2000/NT4(SP5)

Introduction:

This article describes how to add HTML help to an existing project. Similar documentation has been produced by Joep Oude Veldhuis and Bill Sexton. I have added a valuable tool to automatically create a html help project skeleton together with all needed html templates, links, aliases and map definitions that can be directly used with the Microsoft Help Compiler.

Furthermore, I describe how to add context sensitive html help to dialog based applications.

This document is basically a html ported copy of the "manual.txt" file that comes with the makehhp package plus some added information.

What is the output of makehhp if you call it without any parameters?

This is makehhp V1.0 (C) 2001 by Reetcom R&D

Usage: makehhp <-f logfile> <-h> <-i> <-l> <-m> <-w> 
                resourcefile.h projectname.rc name.hhp
       -f logfile: redirects output to logfile
       -h: shows this help file
       -i: don't create index on HTML files in HTML 
              directory of project
       -l: activate console logging
       -m: show (this) detailed man page
       -w: don't create HHP workspace environment
       resourcefile.h: path (+ filename) to resourcefile 
                      (eg. resource.h)
       projectname.rc: path (+ filename) to project's 
                               resource file (*.rc)
       name.hhp: path (+ filename) to HTML help 
                           project file (*.hhp)

Written by VolkerBartheld@reetcom.de

Topics:

(1) What is "makehhp" good for?


makehhp analyzes a MSVC++ V6.0 generated application (no console stuff) and creates a skeleton HTML help workspace for it. The workspace contains
  • a HHP (H_TML H_ELP P_ROJECT) file to be compiled with the Microsoft HTML help compiler (hhc.exe)
  • an index (HHK) file
and all the corresponding HTML, CSS and text files from a template directory.

The CHM file you get by compiling the project with hhc.exe (the command line compiler) or hhw.exe (the Microsoft HTML workshop) can then be embedded in your application's help system. See chapter (6) for more details.

(2) What executables and sources do I need?


  • The Microsoft HTML Help Workshop (can be downloaded from Microsoft) with corresponding hhc.exe and hhw.exe made available in the standard path
  • MS Visual C++ Version 6.0 with service pack 5 (or better)
  • makehhp.exe including associated files _AND_ the HTML templates in the Templates\ directory
  • your MSVC++ project incl. source files - especially resource.h and *.rc
  • htmlhelp.h (if you plan to add help to document-view architectures)

(3) What input / environment does it require?


makehhp works in four steps:
  1. The resource.h file is scanned for resources found in "#define ID..." commands whose names (e. g. IDC_BUTTON1, IDM_ABOUTBOX, etc.) are added to an internal list.
  2. makehhp tries to resolve the resource names in the corresponding <my_project>.rc file to find the correct template type it should use for the associated HTML help file.

    [Example]: Lets assume that the entry in <my_project>.rc that correlates with '#define IDC_BUTTON1' in resource.h is 'PUSHBUTTON "Button1",IDC_BUTTON1,7,7,50,14'. By compareing/matching the ID, we know that the control associated with IDC_BUTTON1 is a pushbutton. makehhp then copies a file named "pushbutton.htm" (if it doesn't already exist) from the templates dircetory to the HTML help directory (usually Help\Html\) and names it after the resource's ID - in our case IDC_BUTTON1.HTM.

  3. An entry is made in the HTML help project (HHP) file [ALIAS] section to create an alias that maps to the relevant resource ID and adds the HTML file created in step 2 to [FILES] section - if that file does not already have an entry.
  4. All HTML files in the HTML help directory (Help\Html\) are scanned for <a name="<tag>">Tag_Value</a> tags and an alphabetically sorted list is built. Then, a search index file (IDX.HHK) containing all tags in the list is created and copied into the \Help directory. The HHP file is modified in order to work with this newly created HHK file.
In order to work correctly, makehhp expects (at least) three command line arguments:
  • the path including filename to the project's resource file (usually resource.h)
  • the path including filename to the project's resource description file (usually <projectname>.rc) and
  • the path to the HTML help project file
The paths can be full paths or abbreviated/relative paths. Relative paths are assumed to start in the current working directory.

[Example]: Let's say, your project (and working) dir is c:\work\htmlhelptest\. Then "makehhp resource.h htmlhelptest.rc htmlhelptest.hhp" would be OK to create the following directories:

  • c:\work\htmlhelptest\help containing htmlhelptest.hhp, idx.hhk, (a copy of) resource.h and toc.hhc
  • c:\work\htmlhelptest\help\html containing all HTML, CSS and Readme files necessary to build the help system.

(4) What output does it produce?


Depending on the command line flags <-f logfile> <-h> <-i> <-l> <-m> <-w> various outputs are available.
  • <-f logfile> directs the standard output of makehhp to a log file
  • <-h> shows a short help/usage message
  • <-i> skips step 4 mentioned in (3). Thus, no index file is created automatically
  • <-l> activates logging to the system console. "Quiet" mode is the default setting.
  • <-m> shows this (more detailed manual page
  • <-w> doesn't create the HHP workspace. This also skips directory creation, copying of HTML templates and modifications of the associated HHP file

(5) How can the user modify the generated files?


Since makehhp doesn't overwrite HTML and other files it has copied once, the user is free to modify the HTML templates to match his requirements. If HTML and other files are added manually, they have to be included into the HTML help project by the HTML help workshop (hhw.exe) or by editing the HHP file's [FILES], [ALIAS] and [MAP] section. New entries in the HHP file are _NOT_ overwritten by future executions of makehhp.

[Example 1]: If you don't like the way, the table of contents is automatically generated by hhw.exe or hhc.exe, just edit the toc.hhc file to show

<BODY>
<OBJECT type="text/site properties">
  <param name="ImageType" value="Folder">
</OBJECT>
<UL>
  <UL>
    <LI> <OBJECT type="text/sitemap">
      <param name="Name" value="User Interface">
      </OBJECT>
    <UL>
      <LI> <OBJECT type="text/sitemap">
        <param name="Name" value="Default Document">
        <param name="Local" value="Html\Default.htm">
        </OBJECT>
    </UL>
  </UL>
</UL>
</BODY></HTML>

instead of

<BODY>
<OBJECT type="text/site properties">
  <param name="ImageType" value="Folder">
</OBJECT>
<UL>
  <LI> <OBJECT type="text/sitemap">
    <param name="Name" value="User Interface">
    </OBJECT>
  <UL>
    <LI> <OBJECT type="text/sitemap">
      <param name="Name" value="Default Document">
      <param name="Local" value="Html\Default.htm">
      </OBJECT>
  </UL>
</UL>
</BODY></HTML>

This modification shows all help entries that deal with dialog controls in a separate folder to give your help system a more compact design.

Note: If the "Auto TOC=9" entry is still present in the [OPTIONS] section of the HHP file, the above changes to the table of contents (TOC) file are overwritten when you call hhc.exe or compile the project with hhw.exe again.

[Example 2]: If you want to add indexes to HTML files (no matter if they have been automatically created by makehhp or have been manually added to the project) just change the desired HTML file - let's assume \Help\Html\Default.htm from

<body class="htmlbody" background="rc_bg.gif">
  <table class="main" width="100%" border="0" 
         cellpadding="0" cellspacing="0">
  <tr>
    <td>
    <h1>Default Document Title</h1>
    <h2>Default Document Section</h2>
    <h3>Default Document SubSection</h3>
    Any descriptive text on a default control

to
<body class="htmlbody" background="rc_bg.gif">
  <table class="main" width="100%" border="0" 
         cellpadding="0" cellspacing="0">
  <tr>
    <td>
    <h1>Default Document Title</h1>
    <h2>Default Document Section</h2>
    <h3>Default Document SubSection</h3>
    <a name="default">Any descriptive text on a 
                         default control</a>
to have the "default" index automatically added to idx.hhk file (located in \Help\) by calling makehhp with the following options (paths analog to the example in (3)).

"makehhp -w resource.h htmlhelptest.rc htmlhelptest.hhp"

(6) How can the help system be included into MSVC++ V6.0 projects?


  1. Dialog based applications (we assume, your app is called "HtmlHelpTest")
    1. Make sure that makehhp.exe and hhc.exe can be found in the standard search path.
    2. Include <htmlhelp.h> in HtmlHelpTestDlg.cpp if not already present
    3. Link with htmlhelp.lib e. g. by adding the following lines to HtmlHelpTestDlg.h:
        #pragma message(
      "library is linking with \"htmlhelp.lib \"") #pragma comment(lib, "htmlhelp.lib")
    4. Add a message handler for the WM_HELPINFO message to your dialog based application (a 2nd entry is needed for the "Aboutbox").

      * This would be the message map entry as done by the wizard:

         <HtmlHelpTestDlg.cpp>
        BEGIN_MESSAGE_MAP(CHtmlhelptestDlg, CDialog)
          //{{AFX_MSG_MAP(CHtmlhelptestDlg)
          // [...]
          ON_WM_HELPINFO()
          // [...]
          //}}AFX_MSG_MAP
        END_MESSAGE_MAP()    
      * Implement the message handling procedure:
        // [...]
        BOOL CHtmlhelptestDlg::OnHelpInfo(
                             HELPINFO* pHelpInfo) 
        {
          TCHAR szPath[_MAX_PATH],
            szFname[_MAX_FNAME],
            szDir[_MAX_DIR],
            szDrive[_MAX_DRIVE];
          if( 0 == GetModuleFileName(NULL, 
                                     szPath, 
                                     sizeof(szPath)) )
          {
          DWORD dwError = GetLastError();
          TRACE("Error 0x%08X\n", dwError);
          return CDialog::OnHelpInfo(pHelpInfo);
          }
      
          _splitpath(szPath, szDrive, 
                     szDir, szFname, NULL);
          _makepath(szPath, szDrive, szDir, 
                            szFname, "chm");
      
          if(NULL==HtmlHelp(this->m_hWnd, 
            szPath, 
            HH_HELP_CONTEXT,
            pHelpInfo->iCtrlId)) 
               HtmlHelp(this->m_hWnd, 
                        szPath,
                        HH_HELP_FINDER, 
                        0 );
      
          return(true);
        }
      * Declare the message map entry:
         <HtmlHelpTestDlg.h>
        class CHtmlhelptestDlg : public CDialog
        {
        // [...]
        protected:
        // [...]
          afx_msg BOOL OnHelpInfo(
      HELPINFO* pHelpInfo); // [...] //}}AFX_MSG DECLARE_MESSAGE_MAP() };
      1. Create an empty HHP file in the \Help directory or
      2. run makehhp once manually to create the workspace or
      3. copy the default HHP file from the \Templates\ directory of makehhp.
      Of course, you should rename the HHP file after your app's .EXE - in our example htmlhelptest.hhp.
    5. Make some changes to your project workspace:
      1. add the HHP file created in step 3 to your project source files
      2. change the settings for the HHP file:
          Custom Build (Debug _AND_ Release)
          Description: Compiling HTML Help 
                       File: $(InputPath).hhp...
          Commands:
            hhc.exe help\$(InputName).hhp 
            echo. 
            copy help\$(InputName).chm $
              (OutDir)\$(InputName).chm
          Outputs:
            help\$(InputName).chm
      3. change the settings for the resource.h file:
          Custom Build (Debug _AND_ Release)
          Description: Generating HTML Help 
                        File: $(TargetName).hhp...
          Commands:
            makehhp resource.h $(TargetName).rc $
               (TargetName).hhp
          Outputs:
            help\$(TargetName).hhp
      This activates an automatic rebuild of all help system associated files each time your project changes. If you don't like automatic indexing or the quiet mode list any command line options in the "makehhp resource.h $(TargetName).rc $(TargetName).hhp" custom build command for resource.h.
    6. "Fine tune" your help project by adding custom HTML files and index markers (<a name="..."</a> constructs) and/or add useful descriptions/help text to the dialog control templates.

  2. Applications with document-view architecture (courtesy of Joep Oude Veldhuis)
    1. Change the default file extension for the help file from .hlp to .chm in InitInstance():
        // Change extension for help file
          CString strHelpFile = m_pszHelpFilePath;
          strHelpFile.Replace(".HLP", ".chm");
          free((void*)m_pszHelpFilePath);
          m_pszHelpFilePath = _tcsdup(strHelpFile);
      Of course, you can find a non-MFC solution without CString by using _splitpath() and _makepath and/or strstr().
    2. Add a help handler in CMainFrame. Put the following in CMainFrame just before END_MESSAGE_MAP and outside the AFX_MSG_MAP tags:
      * ON_COMMAND(ID_HELP, CMDIFrameWnd::OnHelp)
      or with single doc-view:
      * ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
    3. Use the class wizard to add an override for WinHelp. Replace the contents of WinHelp() by:
      * HtmlHelp(m_hWnd, 
              AfxGetApp()->m_pszHelpFilePath, 
              HH_HELP_CONTEXT,
              nCmd == HELP_CONTEXT ? dwData : 0);
      Or even better (courtesy of Bill Sexton):
       * if( HtmlHelp(m_hWnd, 
            AfxGetApp()->m_pszHelpFilePath,
            HH_HELP_CONTEXT, 
            nCmd == HELP_CONTEXT ? dwData : 0) ==  NULL ) 
               HtmlHelp(m_hWnd, 
                       AfxGetApp()->m_pszHelpFilePath, 
                       HH_HELP_FINDER, 0 );
      To show up the standard topic if no help is available (see A.2 for dialog based applications).
Remarks:
  • You can always use your own mapping by executing makehhp with e. g. makehhp <mymapping>.h <myproject>.rc <myproject>.hhp where you enter just the mappings you need in a separate .h-file named <myproject>.rc.
  • Remember, that each line must look like #define ID..... I prefer "IDH_" for help IDs.

(7) Shareware/freeware/copying notice


  1. Standard Disclaimer

    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.

    You can redistribute/copy/include the binary forms of makehhp at any time and in any application provided that the binary executable is kept without modifications.

  2. To obtain the source code of the binary file mentioned above, you should contact the author (VolkerBartheld@reetcom.de) for details.

(8) Credits


Credits go to Christian Windmueller and Stefan Henkelmann from the Reetcom R&D software development team.
Many thanks to Joep Oude Veldhuis and Bill Sexton for pointing out the basics on HTML help.

(9) Version


This is version 1.0 of this manual from june 15th 2001 by VolkerBartheld@reetcom.de

Downloads

htmlhelptest_exe.zip (demo project executable)- 20 kB
htmlhelptest_src.zip (demo project workspace) - 47 kB
htmlhelpmakehhp.zip (makehhp tool) - 66 kB


Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The latest release of SugarCRM's flagship product gives users new tools to build extraordinary customer relationships. Read an in-depth analysis of SugarCRM's enhanced ability to help companies execute their customer-facing initiatives from Ovum, a leading technology research firm.

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds