Examining the Microsoft HTML Help Toolkit

Keith uses Microsoft's HTML Help 1.1 toolkit to develop an application that illustrates one approach to building HTML-based help files. Also, Max Fomitchev discusses HTML Help in distributed environments.


October 01, 1998
URL:http://www.drdobbs.com/web-development/examining-the-microsoft-html-help-toolki/184410692

Oct98: Examining the Microsoft HTML Help Toolkit

Max is a Ph.D. candidate at the University of Tulsa. He can be contacted at [email protected].


Sidebar: HTML Help in Distributed Environments

Over the past year or so, Microsoft has shifted to an HTML-based format for its help files. Although the company says it will continue to support Rich Text Format (RTF) help files, there are definite advantages to adopting the HTML standard sooner rather than later. There are a number of development tools available for implementing HTML-based help files, including Microsoft's HTML Help, Blue Sky's RoboHTML, WexTech's Doc-To-Help, and Forefront's ForeHTML Pro. In this article, I'll use HTML Help 1.1 to develop a sample application that illustrates one approach to building HTML-based help files. The project files for this application are available electronically (see "Resource Center," page 3).

Figure 1 is a typical HTML help file that consists of two panes and a menu bar. The left pane is the navigation pane, which is actually the table of contents wrapped in a tree view control. The right pane is the topic pane -- whenever a topic is selected in the navigation pane, its text appears here. This allows users to always see how they arrived at a topic; a feature missing from the RTF-style help files (where users had to click the Back button to trace their steps).

Perhaps the most important feature of this new standard is that it is write once, use everywhere. After you build an HTML help file, which is actually a compiled program, you can mount it on disk, the Internet, or an intranet. HTML files are also easier to work with than RTF files, which make use of curly braces, backslashes, and special compiler tokens. If you've ever written an RTF-based help file and misplaced a curly brace, you know what I mean. Also, you can easily add subtle features like Java applets and sound clips to your topics. Lastly, and this is the most-significant feature of all, in my opinion, HTML help files support the use of special tags that you can invent and assign to your topics. For example, you can tag topics as being conceptual, tutorial, procedural, or any other category you care to imagine. This makes it easier for you to guide users to the information they're seeking, and to support multiple products with the same help file. For example, suppose your company produces two similar products that differ only slightly. By using these tags, you could write one help file for both products. When users request information relevant to one or the other, your tags would filter out those topics that don't apply.

To develop HTML-based help files, the first thing you'll need is the development kit (available at no charge from Microsoft at http://www.microsoft.com/workshop/ author/htmlhelp/). Next, you'll need to have Microsoft's Internet Explorer 3.x (or higher), which has some DLLs and other components needed to run the help file. A yet-to-be-released Microsoft toolkit will obviate this requirement by allowing Netscape Navigator and other browsers to access your HTML help files. Finally, you'll need a Windows development tool if you're going to access the help file from an application. Here, I'll use Visual C++ 5.0, but any MFC-based compiler (Borland, Symantec, whatever) will work. The toolkit will supply you with two essential files: htmlhelp.h and hhctrl.lib. You'll need to #include the header file, and link with the library file. You'll probably want to move these files into your \include and \lib directories for future use. The development toolkit is itself a lot like the Wizards in Visual C++ and other tools. You simply fill in the blanks and the toolkit does the rest.

The HTMLHelp API

Interacting with an HTML help file from inside a Windows application is done using the HTMLHelp API, which is prototyped as in Example 1(a). The hwndCaller parameter is the handle of the window making the call. When the help window closes, the focus returns to this window unless it's the desktop window (in which case, the focus is set by the operating system). And if the help file window returns any messages, they likewise go to this window. The pszFile parameter is the name of your compiled help file. This could also be a URL or a window definition (which must be preceded by the ">" character, just like with secondary windows in the RTF-based WinHelp system). This parameter can be NULL if the command being used (the uCommand parameter, for example) does not need a file or URL. The uCommand parameter specifies the action to be performed. Example 1(b) shows some possible values.

You'll probably use the first two the most often when calling HTML help from an application. The last parameter, dwData, specifies any additional data needed, and depends on the value of the uCommand. This is all documented in the toolkit's help file, so I won't discuss it here.

Suppose you want to open your HTML help file to a certain topic when the user starts your application. In your project's InitInstance() method, you would do something like Example 1(c) just prior to the return statement. In this example, the help file myhelp.chm is opened to a topic identified by the context string IDH_SOME_TOPIC. You should know that this opens only the topic portion of the help file. Normally, opening a .chm file causes both the navigation and topic panes to be displayed. Opening a help file in this fashion doesn't display the navigation pane, only the topic. If you want to open the file with the navigation pane open, you would do something along the lines of Example 1(d).

To open to a topic with the navigation pane visible, you must create and name a new window, then direct the output to this window. The code to do so would look something like Example 1(e). Creating new windows with the toolkit is as easy as clicking on a toolbar icon.

The Toolkit Environment

Once the toolkit is installed on your machine, starting it up leads you to the window in Figure 2. Conceptually, this is similar to the Windows 3.1 Help compiler toolkit, in that you have icons for compiling, viewing the file, and so on. This is actually a tabbed dialog box -- you click the tab for the object you wish to create (contents, an index, and the like). Creating a project is simply a matter of selecting New, and then Project. You'll actually be given a list of other types of files (such as new HTML topic files) to create, but you'll always start with a project. Just fill in the blanks provided by the Wizard. Projects can be recognized by their .hhp extension.

The next step is to create a table of contents; this will create a file in your project having the extension .hhc. Click the tab, and the window changes as shown in Figure 3. The toolbar on the left side is where you insert headings; the directional arrows let you move items around and establish indentation. Once you have a topic positioned in the hierarchy of the contents, you can double click it to bring up the dialog box shown in Figure 4. This is where you get down to the nitty-gritty and select the HTML/topic file that will open when the user selects this option. As you can see, there is a Browse button so you can select the appropriate file. For this reason, you'll probably find it easier to create the topic file first, then use the Browse button to associate it with the entry in the table of contents. Once you've gotten these simple elements inserted into your project, just click the Compile HTML File icon on the toolbar.

There are 42 built-in icons that you can use in your table of contents to give users a visual cue. Common examples include open/closed books. My sample file uses a custom icon for the Java Applet Demo topic as an illustration only. In a real help file, you'd want to use the same icon with topics in a consistent fashion. To view/select one of these 42 icons, click the Edit Selection icon in the Contents tab, then select Advanced. You'll see a spin control and your current icon, and you can scroll through the list to view your options. You can also create custom bitmaps if you don't see anything you like -- instructions are in the online help file. By the way, the help file for this toolkit is pretty far out -- it covers just about everything you'd ever want to know about HTML help files. Be sure to check out the section entitled "Designing a Help System," which contains useful tips to ease the migration. There's also a complete HTML reference with the toolkit, so if you don't know HTML, or you forget something, you can look it up and never leave your workspace.

The Sample Program

The program I present here consists of a Visual C++ 5.0 application and a sample HTML help project. (The Visual C++ and HTML help project files are available electronically.) If you use another development tool, you might still find the help file project useful as a starting point. It contains the ActiveX control for adding a Close button to your topic files and a Java applet. You must modify the file topic1.htm to point to the directory on your machine where the Java applet is stored. Also, the Java applet loads images from its own directory, so don't forget these. The sample program consists of only three topic files: hasclose.htm, default.htm, and topic1.htm. I've also added a special header file (HelpIDs.h) to my Visual C++ project. This is where I #define the topic IDs (IDH_SOME_TOPIC, for example). As you add topics to your project, the dialog box has an entry for the alias (the topic ID). Just as in the RTF-based WinHelp system, you should use the IDH_ prefix as recommended by Microsoft.

The sample program doesn't do any heavy lifting -- it just opens the sample HTML help file to a topic. I added a custom window to my help file to illustrate how to display the navigation pane, and synchronize it with the current topic. If you explore the sample HTML file, you should have no problem spotting where I've added these custom features. Creating a default HTML file is so simple I thought you'd feel cheated if I didn't give you a few bells and whistles.

Conclusion

New releases of the HTML Help toolkit are in the works -- there should be a true WYSIWYG HTML editor in the next version; the run-time kit will open up web access for Navigator and other browsers. Not only is it a great way to deliver some powerful online help, but you can use HTML help files to create all kinds of reference materials that support multiple links and hierarchies.

DDJ

Listing One

// dwData - Help Topic ID// Base - HTML base URL (such as http://corpweb/app/help/)
void OpenHelp(DWORD dwData, LPCSTR Base) {
COleException e;
CLSID clsid;
// Get Internet Explorer's CLSID
if ( CLSIDFromProgID(OLESTR("InternetExplorer.Application"), 
                                                 &clsid) == S_OK ) {
        TRY {
        // Check if the browser window was already destroyed
            WebBrowser.GetHwnd();
    }
        CATCH_ALL(e) {
            // Browser must've been closed
        WebBrowser.DetachDispatch();
            WebBrowser.m_lpDispatch = NULL;
    }
        END_CATCH_ALL
// If dispatch ptr not attached yet, need to create one
    if ( WebBrowser.m_lpDispatch != NULL || 
                         WebBrowser.CreateDispatch(clsid, &e) ) {
            WebBrowser.SetMenuBar(FALSE);
            WebBrowser.SetToolBar(TRUE);
        WebBrowser.SetStatusBar(FALSE);
            WebBrowser.SetVisible(TRUE);
        COleVariant Flags = 0L, Param;
            CString URL;
            URL.Format("%s%s.html", Base, MapID(dwData));
        WebBrowser.Navigate(URL, &Flags, &Param, &Param, &Param);
            ::SetForegroundWindow((HWND)WebBrowser.GetHwnd());
    }
        else
            AfxMessageBox(IDS_BROWSER_FAILED);
}
else
       AfxMessageBox(IDS_BROWSER_FAILED);
}


Back to Article

Listing Two

void CloseHelp() {    TRY {
        WebBrowser.Quit();
        WebBrowser.ReleaseDispatch();
    }
    CATCH_ALL(e) {
        // Browser must've been closed
        WebBrowser.DetachDispatch();
        WebBrowser.m_lpDispatch = NULL;
    }
    END_CATCH_ALL
}


Back to Article

Listing Three

// DocCount - # of distinct help topics// DocID - array of help topic IDs
// DocName - array of HTML file names
LPCSTR MapID(int ID) {
    for ( int i = 0; i < DocCount; i++ )
        if ( DocID[i] == ID ) return DocName[i];
    return "Index"; // Display Index, if no help topic found
}

Back to Article

Listing Four

void CMyApp::WinHelp(DWORD dwData, UINT nCmd) {if ( m_bUseHtml )
// Display HTML help
OpenHelp(dwData, "http://corpweb/app/help");
else
    // Display HLP-file
CWinApp::WinHelp(dwData, nCmd);
}

Back to Article


Copyright © 1998, Dr. Dobb's Journal
Oct98: Examining the Microsoft HTML Help Toolkit

Examining the Microsoft HTML Help Toolkit

By Keith Bugg

Dr. Dobb's Journal October 1998

(a)
HWND HtmlHelp(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD dwData);
(b)
HH_DISPLAY_TOPIC
HH_HELP_CONTEXT
HH_DISPLAY_TEXT_POPUP
HH_SET_WIN_TYPE
HH_GET_WIN_TYPE
HH_GET_WIN_HANDLE
HH_TP_HELP_CONTEXTMENU
HH_TP_HELP_WM_HELP
(c)
HWND hwndCaller= AfxGetApp()->m_pMainWnd->GetSafeHwnd();	
                                      // handle to your app window
HtmlHelp(hwndCaller,"myhelp.chm",HH_HELP_CONTEXT,IDH_SOME_TOPIC);
                                      // start HTML Help
(d)
HWND hwnd= AfxGetApp()->m_pMainWnd->GetSafeHwnd();	
                                     // handle to your app window
ShellExecute(hwnd,"open", "myhelp.chm",NULL,NULL,SW_SHOWNORMAL);
(e)
HtmlHelp(hwndCaller,"myhelp.chm > mywindow",HH_HELP_CONTEXT,IDH_SOME_TOPIC);

Example 1: Using the HTMLHelp API.


Copyright © 1998, Dr. Dobb's Journal
Oct98: Examining the Microsoft HTML Help Toolkit

Examining the Microsoft HTML Help Toolkit

By Keith Bugg

Dr. Dobb's Journal October 1998

Figure 1: A sample HTML file.


Copyright © 1998, Dr. Dobb's Journal
Oct98: Examining the Microsoft HTML Help Toolkit

Examining the Microsoft HTML Help Toolkit

By Keith Bugg

Dr. Dobb's Journal October 1998

Figure 2: The HTML toolkit with open project.


Copyright © 1998, Dr. Dobb's Journal
Oct98: Examining the Microsoft HTML Help Toolkit

Examining the Microsoft HTML Help Toolkit

By Keith Bugg

Dr. Dobb's Journal October 1998

Figure 3: The Contents tab and icons.


Copyright © 1998, Dr. Dobb's Journal
Oct98: Examining the Microsoft HTML Help Toolkit

Examining the Microsoft HTML Help Toolkit

By Keith Bugg

Dr. Dobb's Journal October 1998

Figure 4: Assigning topic files to contents.


Copyright © 1998, Dr. Dobb's Journal
Oct98: HTML Help in Distributed Environments

Dr. Dobb's Journal October 1998

HTML Help in Distributed Environments

By Max I. Fomitchev


Upgrading client-server applications designed for distributed multiuser environments can be an arduous task because each workstation has to be upgraded individually. Even if you have an automated process that performs upgrades, help files and supporting documentation can change more frequently than the application itself. In such cases, it seems reasonable to have a single up-to-date copy of the help files and other documentation accessible to users. One way to do this is to place HTML help files on the corporate intranet web site or Internet server. Even if the network is slow, HTML files will be delivered quickly because each help screen is generally small. Moreover, after the first access, HTML help pages will be cached locally. This can significantly improve performance and reduce the load on the web server. Since help information is viewed relatively rarely and help pages are generally small, it doesn't take much in the way of server resources to support the feature. In fact, in tests I've conducted, it takes longer to launch the Internet Explorer (IE) browser than to display the request help page (the average help page size was 20 KB, and the total size of all help files was only 600 KB -- almost five times less than the size of the original .HLP file). It is also easier to publish HTML files than Windows standard .HLP files because most tools allow export in HTML.

HTML help files must be viewed in a browser window. Microsoft provides the IWebBrowser2 interface object (IWebBrowser and IWebBrowserApp in earlier releases of SHVDOC.DLL) to automate the IE part. For displaying the help screen, either the browser's ActiveX component or the IE frame can be used. IE can also display a variety of files such as Word documents, Excel files, and so on, provided corresponding components are installed on the client's workstation. In addition, HTML help pages can contain links to a corporate help desk and e-mail feedback to tech support.

Using the IE frame to display help information provides more flexibility, since all the functionality of the browser is available (for example, users can adjust font sizes and make bookmarks). When the WebBrowser object is used as an ActiveX control, some IE functions are inaccessible and others require coding.

To use the IE frame to display HTML help pages, the IWebBrowserApp object must be initialized. In the example presented here, the WebBrowser object is created from the IWebBrowserApp interface with the help of Visual C++ class wizard. This object launches IE by means of OLE Automation; see Listing One This operation must be done each time users request a help page since, after viewing, users might close the IE window and destroy the IWebBrowserApp dispatch handle. (It is easy to test if the handle was destroyed by calling IWebBrowserApp::GetHwnd. This call will throw an exception indicating that the dispatch handle is no longer valid.)

The IE frame must be closed when the application that requested help page terminates. Listing Two must be placed in OnExitInstance or OnClose handlers.

If users have closed the IE frame by the time the application is terminated, the dispatch handle of the IWebBrowserApp has already been released and an exception will occur (because the framework will attempt to release the handle again).

You can also map UI help IDs into the HTML help pages. At first glance, a simple integer-to-string mapping routine (like Listing Three) will do.

In the MFC application presented here, it is sufficient to overwrite the CWinApp::WinHelp() method and add some of the code in Listing Three. CWinApp::WinHelp() handles all help messages sent by UI elements and dialogs. This routine can be configured to display HTML help pages, standard HLP-files, or both; see Listing Four.


Copyright © 1998, Dr. Dobb's Journal

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.