This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


January 1998

Microsoft Systems Journal Homepage

The New HTML Help System Extends Online Help From the Desktop to the Web

Download HTMLhelp.exe (52KB)

Ted Faison has written extensively on Windows, Java, Delphi, and C++. He is president of Faison Computing Inc., a firm that develops software components and applications for Windows. Ted can be reached at ted.faison@computer.org.

The new HTML Help system represents an evolutionary step in online documentation systems. Until the advent of Web browsers, Microsoft relied on essentially two methods for displaying documentation. The most common used the WinHelp engine, which was adequate for simple systems. the Other system used a Microsoft program called InfoView, and was developed to satisfy users who needed to locate help documentation on the numerous Microsoft® Developer Network CDs.
      All of the basic features in WinHelp 4.0 were ported to the new system and the user interface has been completely redesigned. Apart from the switch to HTML, a number of new features were added. When you open a typical HTML Help window, you immediately see something that looks like a mix between the Windows® Explorer and Microsoft Internet Explorer. A typical help window is shown in Figure 1. By default, the window opens in the upper-right corner of the screen. The height of the window is set to display all the text available, if possible. If there is too much text, a vertical scrollbar is added automatically.
Figure 1  A Typical HTML Help Window
Figure 1  A Typical HTML Help Window

      The HTML Help system lets users locate information either through a table of contents (TOC) or through an index. HTML Help windows are usually tri-pane, meaning they contain three standard panes. There are ways to control the Overall appearance of your help window, so it doesn't necessarily have to contain all three panes, but the tri-pane arrangement is the default. The top pane is for the ToolBar, the bottom-left pane is for the TOC, and the bottom-right is where the help topics are displayed.
      The navigation and topic panes both use COM objects to display their contents. The navigation pane is painted using code provided by the new HTML Help ActiveX control, HHCTRL.OCX, which supports all the navigation controls for the system, including the TOC and index. Navigation controls are based on new sitemap files, which are HTML files containing the text to display and additional information for hyperlinks, layout controls, fonts, bitmaps, and so on.
      The topic pane is implemented with the same MSHTML ActiveX object used in Internet Explorer. MSHTML parses HTML streams and displays the text, graphics, Java applets, or ActiveX controls. MSHTML is hosted by another ActiveX control, SHDOCVW, also known as the Layout Manager. SHDOCVW is essentially a wrapper that adds a number of high-level functions, including navigation functions. SHDOCVW doesn't actually know how to travel through hyperlinks—it leaves that task to lower-level COM objects contained in HLINK.DLL, URL.DLL, URLMON.DLL, and other DLLs.

HTML Help Workshop
      The Microsoft tool for developing HTML Help systems is HTML Help Workshop (HHW), which is available at http://msdn.microsoft.com/workshop/author/htmlhelp. It is a fairly bare-bones MFC application, and Microsoft deliberately left the door open for third-party tools. HHW lets you create TOCs, indexes, compiled files, and HTML files. It also allows you to test your documents by displaying the M in a minibrowser. Figure 2 shows a typical HHW session. The left pane uses the same HHCTRL ActiveX control you'll use in your own help windows.

Figure 2 An HTML Help Workshop Session
Figure 2 An HTML Help Workshop Session

      HHW has a number of wizards to simplify common tasks like embedding the HHCTRL ActiveX control in HTML documents. Most of the Se wizards become available after at least one HTML file is associated with a project. Once this is done, the wizards are available from the HHW toolbar or the Tags menu. The Compile command compiles an entire HTML Help project into a single file. Compiled files are useful for several reasons. First, they are small, so they are well-suited for Web deployment. Second, certain features such as full-text searching are available only with compiled files.
      Once you create your help files with HHW, there are two ways for users to view the M. The simplest is with a standard Web browser. Because all the files are written in HTML, any browser that supports ActiveX can be used. And if you really want to support browsers that aren't ActiveX-aware, you can instead embed the navigation controls as Java applets, a process I'll describe later. The most typical way users get to your HTML Help system is through a Help menu in your application. Menu commands can be used to programmatically create a help window using an HtmlHelp API function.

Creating a Help System
      HTML Help systems often display a TOC on the left side and a topic window on the right. To accomplish this layout, you use frames. You simply create a two-frame document and give the frames names like left and right. You'll refer to the Se names later to designate which frame your commands should apply to. The following code will create a two-frame window:


 <HTML>
 <HEAD>
 <TITLE>HtmlHelp sample pages</TITLE>
 </HEAD>
 <FRAMESET COLS="260,100%" framespacing=0 frameborder=0> 
     <FRAME SRC="TableOfContents.htm" name="left" 
     scrolling="no">
     <FRAME SRC="TitlePage.htm" name="right" 
     scrolling="yes">
 </FRAMESET>
      The frames also designate which HTML file is loaded by default. The left pane loads a file that uses an embedded HHCTRL ActiveX control to support navigation features. Having created a new TOC, you can use HHW to add entries and customize it. Indexes are created and managed in a similar manner. At any time you can click the Display In Browser button to preview how your HTML pages will look.
      You can structure the entries shown in the TOC to support different classes of users with Information Types (IT). HHW also comes with a built-in tool, called the HTML Help Image Editor, to capture and view screen images. It supports common image formats like BMP, GIF, and JPEG. The Image Editor lets you manage the images used in your help system, but keep in mind that it wasn't designed to be a full-blown graphics production system.

Compiled Files
      Certain HTML Help features are best implemented when all the information in your help system is stored in a single file. Because HTML Help systems use URLs as links, a single system could reference documents scattered all over the Internet. To support those features that need to access all your topics at once—like full-text search—you must use compiled files.
      Compiled files are nothing more than CAB files that store a compressed version of all your project files in a single file with a .chm extension. Compiled files contain the text of multiple HTML files. You can assign an alias to each file and use this alias in some of the commands in the HtmlHelp API function call. The aliases are used only in compiled files. To assign an alias, click the HtmlHelp API Information button in the HHW Project pane and select the Alias tab, then click the Add button.
      Aliases are just numeric values that represent HTML files. For example, the HH_HELP_CONTEXT command can be used to display a single topic in a compiled file:


 HtmlHelp(HH_HELP_CONTEXT, "MYCOMPILEDFILE.CHM", 100);
The second parameter is the name of the compiled file that contains the topics. The third parameter is the alias number of the topic.

Navigating HTML Help Content
      Online documentation systems require a way to show the user the layout and organization of the documents and a way to get around in the system. Users need the same kinds of features found in printed documentation, such as a TOC and index. But online systems can do better, giving users the ability to do full-text searches and queries to locate words or phrases anywhere in the documentation system.
      HTML Help documents are designed to be viewable with a Web browser, but HTML itself doesn't support navigation control except for hyperlinks. The solution was to create a special control that could be embedded in HTML documents. Microsoft initially created it as an ActiveX control, but since not all browsers support ActiveX, there's also a Java applet that provides similar functionality.
      Many of the HTML Help features are provided by the HHCTRL ActiveX control. If you plan to use any of the Se features, you need to embed the control on an HTML page. You can do it the hard way or the easy way. The hard way entails writing HTML code to hook in the ActiveX control, plus additional code for optional parameters. The easy way is to use the HHW Wizard.
      The HHCTRL ActiveX control supports a whole slew of features, but not all can be accessed through HTML parameters. To access all the ActiveX features you need to programmatically call the HtmlHelp API function, which is exported from HHCTRL.OCX. Figure 3 shows the features you can access using the HHW Wizard.
      As a simple example, you can add a button to a topic page that displays a small message box with the version of the HHCTRL ActiveX control. Using the HHW Wizard, inserting the button is trivial. You can choose to have the button display whatever caption you want. The wizard generates the following HTML code and inserts it in the selected HTML file:


 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="hhctrl.ocx#Version=4,71,1111,0"
         width=100
         height=100>
     <PARAM name="Command" value="HH Version">
     <PARAM name="Button" value="Text:HHCTRL Version">
 </OBJECT>
Version information is designed primarily to aid developers during debugging, not for users to see.
      To demonstrate the features on the HTML Help system, I created a small documentation system for a fictitious travel agency called Your Travels. I'll be using code fragments from this example throughout the article.
      To display an index in an HTML file, you need an index sitemap file, which has an .hhk extension. You embed the HHCTRL ActiveX control on the page and pass it the name of the sitemap. You can create .hhk files manually with a tool like Notepad or with HHW. Building an index is not automatic. You have to add entries to it, declaring keywords and the topics they are linked to. You add entries by clicking the "Insert a keyword" button on the index pane in HHW.
      For each index entry, the wizard adds a record to the sitemap, like this:

 <UL>
     <LI> <OBJECT type="text/sitemap">
         <param name="Name" value="Italy">
         <param name="Name" value="Italian vacations">
         <param name="Local" value="Italy.htm">
         </OBJECT>
 </UL>
The ITs in the dialog box are not supported for indexes under HTML Help 1.0. ITs are a way to categorize the contents of your Help system, allowing users to obtain customized information based on the selected ITs.
      Once you have a sitemap with indexed entries, creating an index is a matter of using the HHW Wizard to insert the HHCTRL ActiveX control into the document. Clicking keywords in the index displays the linked topic in the right pane.

 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="file:hhctrl.ocx#Version=4,0,0,20"
         width=248
         height=300>
     <PARAM name="Command" value="Index">
     <PARAM name="Item1" value="file:index.hhk">
 </OBJECT>
You can put objects on a page so users can click on the M to see links to other topics. the Se objects are normally used as references to related topics, or "see also" features. If all you want is a link to another topic, just use a simple hyperlink.
      The HHW Wizard lets you create lists of related topics as buttons, popup menus, or dialog boxes. Buttons act just like ordinary hyperlinked text: you click the M and the browser goes to the linked page. Popup menus are useful for short lists. The popup window will automatically get scrollbars if the list doesn't fit in the window, so it can handle any number of items.
      Dialog boxes are useful when the number of topics to display is long. Links to related topics are encoded as URLs. You can mix local and remote URLs, significantly blurring the boundaries of your help system. The wizard lets you insert the HHCTRL ActiveX control into an HTML document with parameters to support related topics. Your HTML document will have a button embedded on it. If you requested a popup menu, the code will look like this:

 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="file:hhctrl.ocx#Version=4,0,0,24"
         width=80
         height=20>
     <PARAM name="Command" value="Related Topics, MENU">
     <PARAM name="Button" value="Text:Related Topics">
     <PARAM name="Item1" 
         value="EN_CHANGE;c:\MyTopics\OurMailingAddress.Htm">
     <PARAM name="Item2" 
     value="WM_COMMAND;c:\MyTopics\OurWebAddress.Htm">
 </OBJECT>
Shortcuts
      A shortcut is a button users can click on to launch a secondary program. Say you want to open a form that collects information from the user. A shortcut button could launch a standalone program to get the user data and send it to your Web server. Shortcuts appear as buttons, with optional text or a bitmap for the caption. To add a shortcut to an HTML page, you need to embed the HHCTRL ActiveX control on the page and pass it three parameters, like this:

 <OBJECT id=hhctrl type="application/x-    
                 oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="hhctrl.ocx#Version=4,71,1111,0"
         width=100
         height=100>
     <PARAM name="Command" value="ShortCut">
     <PARAM name="Button" 
     value="Text:Tell us about yourself">
     <PARAM name="Item1" 
     value=",C:/MyTopics/TellUs.exe,">
 </OBJECT>
Keep in mind that programs launched by a shortcut can't return a status code to their caller like modal dialog boxes do. The programs execute independently of your help window and don't close automatically when your help window closes.
      

Splash Images
      When the user accesses your documentation system, you might want to display a splash window. The HHCTRL ActiveX control allows you to display a splash window anytime a given document is displayed. Using HHW, select the HTML document that will have the splash window, then use the wizard to add the HTML code. The wizard lets you specify the file name of the splash image and the length of time to show it.

Figure 4 A Splash Window
Figure 4 A Splash Window

      I captured an image off the screen using HTML Help Image Editor, then saved it as SPLASH.GIF in the directory with the rest of my documentation files. When I ran the HHW Wizard, I embedded the HHCTRL ActiveX control on my title page, selected the Splash option with my GIF file, and requested a three-second duration. That's it. Loading the title page with a browser causes the splash window to appear (see Figure 4). Here's the code the wizard generated to create the three-second splash window:

 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="hhctrl.ocx#Version=4,7,1,630">
     <PARAM name="Command" value="Splash">
     <PARAM name="Item1"  
     value="Splash.gif">
     <PARAM name="Item2" value="3000">
 </OBJECT>
The splash duration is measured in milliseconds. You can use GIF or BMP images.

Tables of Contents
      HTML Help TOCs are special HTML files with .hhc extensions. the Se files represent sitemaps. Although you obviously can create a TOC by hand using a text editor like Notepad, the easy way is with HHW. To use a sitemap in your documentation system, create an HTML page and embed the HHCTRL ActiveX control, passing it the name of the sitemap. The HHW TOC wizard makes the process simple, creating HTML code that looks like this:


 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="file:hhctrl.ocx#Version=4,0,0,20"
         width=250
         height=270>
     <PARAM name="Command" value="Contents">
     <PARAM name="Item1"      
     value="file:TableOfContents.hhc">
 </OBJECT>
The preferred way to show a TOC is in the left pane of a multipane window.
      Clicking entries in the TOC changes the topic shown in the right pane. You can change this arrangement by indicating the name of the topic pane in the sitemap file. You could even make the TOC appear by itself, or in a pane at the top of the window.
      Using the Table of Contents Properties dialog box in HHW, you can customize the way the TOC appears, including its font, treeview styles, and bitmaps. The HHCTRL ActiveX control that displays the TOC uses an image list to display bitmaps for each entry in the TOC. The built-in image list looks like Figure 5. Each bitmap is 16 X 16 pixels.
Figure 5 HHCTRL Built-in Image List
Figure 5 HHCTRL Built-in Image List

      To select a bitmap for a TOC entry using HHW, click the Edit Selection button in the Contents pane. In the Advanced tab there is a spinner edit control for selecting the image index. The spinner uses a 1-based image index. You can customize the TOC by creating your own image list as a BMP file using a tool like Microsoft Developer Studio. The image list must consist of a series of bitmaps. To select your image list, click the Contents Properties button on the Contents pane in HHW and enter your image list file name.

Information Types
      Documentation systems are often created to support different kinds of users. For example, a financial system might have information designed for accountants, analysts, and executives. Each group should see only those entries created for the M. Accountants should be able to filter out the entries created for analysts and executives.
      HTML Help systems accomplish this kind of filtering by grouping topics together using ITs. When the user selects an IT, the TOC only displays topics that belong to that IT. An IT is just a string that you use to group your topics. You might want to organize topics by the level of experience of the user, so you would have types like Beginner or Advanced. Useful types might also be What's New, How-To, Overview, FAQ, or On the Web. For even more control, you can group ITs into Categories. In my Travel Agency example, I could have used categories to distinguish topics by destination, by length of travel, and by cost of travel (see Figure 6).
Figure 6 IT Categories
Figure 6 IT Categories
      To create ITs in HHW, click the Contents properties in the Contents pane and select the Information Types tab. When you add a new IT, you have the choice of making it inclusive or exclusive. The former allows the user to choose topics from that IT along with others. The latter allows the user to see the topic in the IT, excluding other ITs.
      You use ITs with TOC entries. Using HHW, select an entry in the TOC, then click the Edit Selection button. The Information Types tab lets you associate the entry with one or more ITs. When the user opens the help window, the TOC displays entries for all the ITs. To select a subset, the user right-clicks the TOC and selects the Customize command. This launches a wizard.
      The HtmlHelp API is also designed so you can select ITs programmatically, but the feature wasn't quite ready in time for the release of version 1.0.
      You aren't required to use ITs in your HTML Help projects. If a topic doesn't reference one, it will always be displayed, regardless of the IT selected.

The Java Applet
      If you want to allow users to view your HTML Help system with browsers that don't support ActiveX, you can embed the HHCTRL control as a Java applet. Keep in mind that the Java version doesn't support all the features you'll get with the ActiveX control, and it's much slower, too.
      The Java version supports TOCs, indexes, and related topics. To use the applet, create your sitemap (TOC and index files) using HHW in the usual manner. There is no wizard to insert a Java applet into an HTML file, so you have to type the code in yourself. The following will create a TOC:


 <APPLET code="HHCtrl.class" width=200 height=200>
     <PARAM name="Command" value="Contents">
     <PARAM name="Item1" value="TableOfContents.hhc">
 </APPLET> 
      Make sure you type HHCtrl.class with the exact upper and lower case, otherwise you'll get a "class not found" error when the Java Runtime Environment tries to load it. The HTML Help documentation says to include a codebase directive in the APPLET statement, but I wasn't able to get it to work. Using a codebase directive seems to interfere with the applet's ability to find and load the sitemap files. You need to copy all the Java support files contained in the HHW java subdirectory to the directory that contains your HTML documents. Make sure that your .hhc and .hhk sitemap files, plus all your other help files, are in the same directory.

Creating HTML Help Windows Programmatically
      You can view HTML Help topics either using a browser or programmatically. The first approach displays your documents within the context of the browser, so the user gets whatever toolbar the browser provides. The second approach does away with the browser, creating a standalone window. The advantage of this approach is that the help documents are displayed in a window you have control over, so you can set the toolbar buttons, receive notifications, and control the exact appearance of the window.
      Programmatic access to the HTML Help system is implemented by the HtmlHelp API function through an extensive list of commands and parameters. This essential function is exported from HHCTRL.OCX and declared like this:


 HWND HtmlHelp(HWDN hwndCaller, LPCTSTR pszTitle, 
               UINT iCommand, DWORD dwData);
      There are two versions of the declaration: HtmlHelpA for ANSI strings and HtmlHelpW for Unicode (wide) strings. Other than the character set they are identical, so I'll describe the ANSI version. A #define statement in HTMLHELP.H selects one function or the Other:

 #ifdef UNICODE
 #define HtmlHelp  HtmlHelpW
 #else
 #define HtmlHelp  HtmlHelpA
 #endif // !UNICODE

 HWND WINAPI HtmlHelpA(HWND hwndCaller, LPCSTR pszFile,
                       UINT uCommand, DWORD dwData);

 HWND WINAPI HtmlHelpW(HWND hwndCaller, LPCWSTR pszFile,
                       UINT uCommand, DWORD dwData);
Before using HtmlHelp in your program, you need to include HTMLHELP.H, which contains the definitions for the commands and parameters you can use.
      As with any function exported from a DLL, you can load it implicitly or explicitly. To load implicitly, you link your application with the import library HHCTRL.LIB and just use HtmlHelp in your code as a regular function. When your application loads, the Windows loader will automatically load HHCTRL.OCX, so you'll call the API function like this:

 #include "HtmlHelp.h"
 •
 •
 •
 HWND wnd = HtmlHelp(…);
      To load explicitly, you use GetProcAddress and access the API through the returned function pointer. You can load either by name or ordinal. To load by name, use the string HtmlHelpA or HtmlHelpW. To load the ANSI function, you would write something like this:

 #include "HtmlHelp.h"
 •
 •
 •
 typedef HWND (WINAPI *FPHH) (HWND, LPCSTR, UINT, 
                              DWORD);
 FPHH htmlHelp;
 
 HINSTANCE inst = LoadLibrary("HHCTRL.OCX");
 (FARPROC&) htmlHelp = GetProcAddress(inst, 
                                      "HtmlHelpA");
 HWND wnd = htmlHelp(m_hWnd,
                     "file://C:/MyFile.htm", 
                     HH_DISPLAY_TOPIC, NULL);
To load by ordinal, you should use the symbolic names ATOM_HTMLHELP_API_ANSI or ATOM_HTMLHELP_ API_UNICODE, like this:

 (FARPROC&) htmlHelp = GetProcAddress(inst,
                                      ATOM_HTMLHELP_API_ANSI);
      When calling HtmlHelp, the first parameter is the handle of the calling window. Some help windows you create can send messages, and the calling window will receive the M. For example, if you create a help system that has a toolbar, the help window can send WM_NOTIFY messages to the calling window when the user clicks a button. The calling window also owns and controls the visibility of the help window. This is an important new feature because WinHelp windows were owned by the Desktop and their visibility was not controlled by the calling app. With HTML Help windows, the Owner is generally your application. When you switch to another app, the Help window is hidden. If you hide or minimize your app, the Help window is also hidden or minimized. If you close your app, the Help window is closed.
      The HtmlHelp API is a versatile function and accepts all kinds of commands and parameters to create and manipulate help windows. Figure 7 describes the commands. I'll get to the parameters shortly.
      Normally, the first call you make to the HtmlHelp API is to create a help window. There are several ways to create windows, based on what you want to display. The simplest is to use the HH_DISPLAY_TOPIC command, which will create a window with formatted HTML text in it. If the text contains links, the user can click on the M to navigate to linked documents, just as with a regular Web browser.

 HWND wnd = HtmlHelp(m_hWnd, 
     "file://C:/MyTopics/TravelPackages.htm", 
     HH_DISPLAY_TOPIC, NULL);
 if (wnd == NULL) MessageBox("No window created.");
      This code displays the contents of the file TravelPackages.htm from the local file system in a default window. The window will have the styles WS_THICKFRAME | WS_OVERLAPPED | WS_VISIBLE, which is just a resizable window with a blank caption bar, as shown in Figure 8. For the HTML file name in the second parameter, you can also use Web URLs—in fact, the default is an HTTP URL. The file name www.microsoft.com/default.htm would default to http://www.microsoft.com/default.htm and display the Microsoft home page. You can subsequently use the HH_SET_WIN_TYPE command to customize the location, size, title, color, and font of the help window.
Figure 8 Default Window
Figure 8 Default Window
      Sometimes you need to open a small window containing only text. Maybe you want to describe a word or command. The text doesn't need to have any special formatting, pictures, or links. This kind of window gets created very quickly compared to a full-blown, tri-pane window with toolbar and TOC. Text-only windows are created by using the HH_DISPLAY_TEXT_POPUP command with an HH_ POPUP structure. You can display text contained in a resource file or in a char array, but HTML Help 1.0 doesn't support displaying text from a text file in a text popup.
      Here's how you would use HH_DISPLAY_TEXT_POPUP to display a char array:

 #include "HtmlHelp.h"
 •
 •
 •
 HH_POPUP popupText = {
     sizeof(HH_POPUP),   // cbStruct;     
  NULL,              // hinst;        
  NULL,              // idString;     
  "Check this out!", // pszText;      
  {100, 100},        // pt;           
  (DWORD) -1,     // default
                  // clrForeground;
  (DWORD) -1,     // default 
                  // clrBackground;
  {-1, -1, -1, -1},  // default 
                     // rcMargins;    
  NULL      // default pszFont;
 };
 
 HWND wnd = HtmlHelp(m_hWnd, NULL, 
             HH_DISPLAY_TEXT_POPUP,
             (DWORD) &popupText);
The HH_POPUP structure allows you to set the foreground and background colors of the window. Using -1 selects the default colors. The pt field specifies the coordinates of the top-left corner of the window. (The HTML Help documentation incorrectly states that pt refers to the top-center point of the window.) You can also set margins around the text by using the rcMargins field.
      To display text from a resource file, set the HH_POPUP fields hinst and idString. The hinst field is the instance handle used to load string resources. idString is the resource ID of the string. Here's how you would set up the HH_POPUP structure to display text from a resource:

 HH_POPUP popupText = {
     sizeof(HH_POPUP),        // cbStruct;     
     AfxGetInstanceHandle(),  // hinst for this module     
     IDS_STRING_CHECKTHISOUT, // idString;     
     NULL,                    // pszText;      
     {100, 100},              // pt;           
     (DWORD) -1,              // default clrForeground;
     (DWORD) -1,              // default clrBackground;
     {-1, -1, -1, -1},        // default rcMargins;    
     NULL                     // default pszFont;
 };
      Text popups stay on the screen until you press a key or click the mouse. The MFC function AfxGetInstanceHandle returns the instance handle for the currently executing module. If your app is not written using MFC, you can get the instance handle by calling the GetModuleHandle API function with a NULL argument. You can also use the instance handle of a DLL if your resources are stored there.
      The most elaborate type of help window is the tri-pane variety described earlier. Showing a tri-pane window requires two steps: creating it and displaying something in it. Creating the window is a matter of setting up an HH_WINTYPE structure and passing it to HtmlHelp with an HH_SET_WIN_TYPE command. The structure is complex, allowing you to specify almost every possible option for the tri-pane window, including the number and appearance of toolbar buttons, the size of the three panes, the window style, the ITs supported by the HHCTRL ActiveX navigation control, and so on.
      The HTMLHELP.H include file has comments for each field. Because the structure is complex and the comments rather concise, I decided to provide additional information about each field, as shown in Figure 9.
      To see how everything fits together, you really need to see some code. Figure 10 creates a fairly complete tri-pane help window, with tabs in the navigation pane and all the toolbar buttons available. The button glyphs are fixed—take 'em or leave 'em. The code produces the window shown in Figure 11.
Figure 11 Tri-pane Help Window
Figure 11 Tri-pane Help Window

The last two buttons on the right are custom buttons, referred to as Jump1 and Jump2, that you can tie to your own URLs. Notice that the first call to HtmlHelp creates the window and the second one displays it. The first call creates a window with the type name of MyWindow, which is used in the second call, preceded by the > character.

Commands and Parameters
      Creating a standalone help window programmatically is just a matter of calling a single API function, but the number and combination of possible parameters makes the task sometimes less than trivial. Figure 7 briefly describes the commands accepted by the HtmlHelp API. The parameters required by each command are described in Figures 12, 13, and 14.

Figure 14  HH_WINTYPE Structure
Figure 14 HH_WINTYPE Structure

      Although HHCTRL.OCX contains bitmaps for all the bitmaps shown in Figure 14, not all of the M are supported in the code, as indicated. If you don't specify any tool-bar buttons in the HH_WINTYPE structure, a default toolbar will be created with the Expand, Back, Options, and Print buttons.
      There are a number of situations in which you might want to receive notification events from the help window: you might want to do something special when the user goes to a certain topic or when a certain toolbar button is pressed. The help window has the Option of sending you notifications to tell you what the user does. Although full notification support was planned, only HHN_NAVCOMPLETE, described below, was finished in time for the release. Because an update to HTML Help will appear soon, I'll describe all the event notifications.
      To receive notifications, you must set the idNotify field in HH_WINTYPE. Once set, you'll receive all kinds of notifications, but you can ignore those you're not interested in. Handling notifications is a matter of processing WM_ NOTIFY messages. The wParam parameter carries the value of the idNotify field you set in the HH_WINTYPE structure. It corresponds to the ID of the control sending the notify message (in this case the help window), so you can distinguish different senders from each other.
      The lParam is a pointer to an HHN_NOTIFY structure, which looks like this:

 typedef struct tagHHN_NOTIFY
 {
   NMHDR   hdr;
   PCSTR   pszUrl;
 } HHN_NOTIFY;
hdr contains a standard NMHDR structure, used in all Windows notification messages. pszUrl contains a string pointer used with HHN_NAVCOMPLETE notifications to indicate the URL the user switched to.
      The NMHDR structure looks like this:

 typedef struct tagNMHDR {
     HWND hwndFrom;
     UINT idFrom;
     UINT code;
 } NMHDR;
hwndFrom is the handle of the Help window, idFrom is the notification ID you set with the idNotify field of the HH_WINTYPE structure. This same ID is also in the wParam parameter of the WM_NOTIFY message. The code field contains either the value HHN_NAVCOMPLETE or HHN_TRACK.
      An HHN_NAVCOMPLETE notification message is sent after a new topic has been loaded. An HHN_ TRACK notification is sent immediately when the user clicks a button. Figure 15 shows the code for handling notifications.
      If you try this code with the current HtmlHelp API, you won't receive HHN_TRACK events. When the event is eventually supported, the idAction field of the HHNTRACK structure will contain the ID of the button that was pressed.

Search Support
      HHW can automatically generate support for full-text search. The catch is you must use compiled HTML. You enable full-text search before compiling. In HHW, select the Project Tab, then click the Project Options button to get the dialog box. Check the "Compile full-text search information" check box, then compile the project. When you click the Compile button on the toolbar, the right pane of HHW shows the compilation progress, including a list of all the files compiled, the amount of compression achieved, and a few other statistics.
      To view a compiled HTML file, click the View button on the toolbar. This opens a help window, but this time a Search tab appears next to the Contents tab. The tab displays a page that users can fill in to find specific words in the help system. The beauty of full-text search is that it doesn't require any work on your part. You just write your topic files, compile the M with full-text search enabled, and go.

Training Cards
      A training card is a window that helps the user accomplish a specific task. Training cards were first introduced with Windows 95, and have buttons that send WM_TCARD messages to the Owner when clicked.
      With HTML Help 1.0, you can't create training cards that act exactly as in WinHelp, but you aren't completely out of luck. You can use shortcuts to achieve a similar effect. To get shortcut buttons that look like their WinHelp counterparts—with the little arrow bitmap—create the M with the HHW Shortcut Wizard. Select the "Create as a bitmap" option, and set the bitmap name to SHORTCUT.
      The wizard also asks for the name of the program to invoke when the button is clicked. As an example, I chose a program called TellUs.Exe, which I wrote for the Your Travels system. What I got in my HTML file was the following entry:


 <OBJECT id=hhctrl type="application/x-oleobject"
 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
 codebase="hhctrl.ocx#Version=4,71,1111,0"
          width=100
          height=100>
     <PARAM name="Command" value="ShortCut">
     <PARAM name="Button" value="Bitmap:SHORTCUT">
     <PARAM name="Item1" 
     value=",C:/MyTopics/TellUs.Exe,">
 </OBJECT>
The SHORTCUT image is a built-in bitmap. The file HHCTRL.DLL contains resources used by the HHCTRL ActiveX control, and one of the M is the SHORTCUT bitmap. Incidentally, the DLL also contains the image list used with TOC entries and the toolbar button images shown in Figure 5.
      The HHW Wizard allows you to specify a message to send to the program the button launches. If you specify WM_ TCARD, then your program will get WM_TCARD messages in a manner similar to WinHelp. The main difference is that this approach sends WM_TCARDs to your standalone program, while WinHelp training cards send WM_TCARDs to the Owner window. I created a simple topic page that looks a lot like a WinHelp training card, with a shortcut button showing the SHORTCUT bitmap (see Figure 16).
Figure 16 HTML Help Shortcut Button
Figure 16 HTML Help Shortcut Button

      I created the TOC using HHW. The topic was created using plain old Word 97 and saved as an HTML file. Then I embedded the HHCTRL ActiveX control to support the shortcut button. For the window background color I used the value 0xFFFFEF, which corresponds to the default Windows 95 training card color. The HTML code for the topic pane in Figure 16 is shown in Figure 17.

Converting an Existing WinHelp Project
      There are many existing WinHelp projects out there, and a natural question is: "can I easily port my old projects to HTML Help?" In fact, HHW has a built-in wizard that can convert your WinHelp projects. The wizard essentially translates files from WinHelp to HTML Help formats. Figure 18 shows the files that are converted.
      To take advantage of the new HTML Help features such as tri-pane windows, you'll need to roll up your sleeves and get your hands dirty because the conversion wizard doesn't create tri-pane windows. But even then, you won't get that dirty for most projects. The various wizards in HHW help you embed the HHCTRL ActiveX control to support shortcuts, TOCs, indexes, and other common features.

Conclusion
      HTML Help is a major shift in concept for documentation systems, allowing the seamless integration of local and remote files. Moreover, because the system is based on HTML, you have the Option of providing active content and using embedded ActiveX controls or Java applets. With remote links you can have users connect directly to your Web site for up-to-the-minute documentation. Users are no longer constrained to using the proprietary WinHelp engine to read the documentation—any standard Web browser can be used.
      I've covered a lot of ground here, and I would need quite a bit more room to completely describe every feature in the new HTML Help system. But I hope I've given you a good idea of what's in the new product.

From the January 1998 issue of Microsoft Systems Journal.