How to use the unmanaged HTML Help API from a managed Visual C# application (317406)



The information in this article applies to:

  • Microsoft HTML Help 1.3
  • Microsoft Visual C# .NET (2002)
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition
  • Microsoft Visual C# 2005, Express Edition

This article was previously published under Q317406
This article refers to the following Microsoft .NET Framework Class Library namespaces:
  • System.Runtime.InteropServices
  • System.Reflection

IN THIS TASK

SUMMARY

This step-by-step article shows you how to use marshalling to call the unmanaged HTML Help API from a Visual C# application. Normally, it is unnecessary to call the unmanaged HTML Help API directly from a .NET application, because the .NET Framework provides the following two classes for this purpose:
  • System.Windows.Forms.Help
  • System.Windows.Forms.HelpProvider
However, there are times when you may need to call the HTML Help API directly.

This article assumes that the reader is familiar with the HTML Help API, Visual C# , Microsoft Visual Studio 2005, and the Microsoft Visual Studio .NET integrated development environment (IDE).

The HTML Help API is designed so that you can pass commands and data to it in the form of structures, arrays, or pointers. The exact requirements depend on the specific command used. To use the HTML Help API from Visual C# , these objects must first be marshalled. You can use the the System.Runtime.InteropServices namespace and the StructLayoutAttribute class to accomplish the marshalling process.

back to the top

Marshall the HTML Help APIs

The following sample code demonstrates the use of the HTML Help API for the HH_GET_WIN_TYPE and HH_SET_WIN_TYPE commands. To download a more robust sample that contains many of the marshalled HTML Help APIs, see the "Sample Download" section of this article.
  1. Create a new C# Windows application named "Demo."
  2. Add a new C# class to Demo. Name it "hhinterop" and use the default values.
  3. Remove all of the code in hhinterop.cs, and then insert the following code:
    using System;
    using System.Runtime.InteropServices;
    using System.Reflection;
    
    
    public class HHInterop
    {
       // Constants
       const int HH_MAX_TABS = 19; // maximum number of tabs
    
       // commands
       protected const int HH_DISPLAY_TOPIC      = 0x0000; 
       protected const int HH_SET_WIN_TYPE       = 0x0004;  // [Use HtmlHelp_SetWinType()]
       protected const int HH_GET_WIN_TYPE       = 0x0005;  // 
    
       // parameter info used with HH_WINTYPE struct
       public const int HHWIN_PARAM_PROPERTIES      = (1 << 1);    // valid fsWinProperties
       public const int HHWIN_PARAM_STYLES          = (1 << 2);    // valid dwStyles
       public const int HHWIN_PARAM_EXSTYLES        = (1 << 3);    // valid dwExStyles
       public const int HHWIN_PARAM_RECT            = (1 << 4);    // valid rcWindowPos
       public const int HHWIN_PARAM_NAV_WIDTH       = (1 << 5);    // valid iNavWidth
       public const int HHWIN_PARAM_SHOWSTATE       = (1 << 6);    // valid nShowState
       public const int HHWIN_PARAM_INFOTYPES       = (1 << 7);    // valid apInfoTypes
       public const int HHWIN_PARAM_TB_FLAGS        = (1 << 8);    // valid fsToolBarFlags
       public const int HHWIN_PARAM_EXPANSION       = (1 << 9);    // valid fNotExpanded
       public const int HHWIN_PARAM_TABPOS          = (1 << 10);   // valid tabpos
       public const int HHWIN_PARAM_TABORDER        = (1 << 11);   // valid taborder
       public const int HHWIN_PARAM_HISTORY_COUNT   = (1 << 12);   // valid cHistory
       public const int HHWIN_PARAM_CUR_TAB         = (1 << 13);   // valid curNavType
    
       // property values used with HH_WINTYPE struct
       public const int HHWIN_PROP_TAB_AUTOHIDESHOW = (1 << 0);    // Automatically hide/show tri-pane window
       public const int HHWIN_PROP_ONTOP            = (1 << 1);    // Topmost window
       public const int HHWIN_PROP_NOTITLEBAR       = (1 << 2);    // no title bar
       public const int HHWIN_PROP_NODEF_STYLES     = (1 << 3);    // no default window styles (only HH_WINTYPE.dwStyles)
       public const int HHWIN_PROP_NODEF_EXSTYLES   = (1 << 4);    // no default extended window styles (only HH_WINTYPE.dwExStyles)
       public const int HHWIN_PROP_TRI_PANE         = (1 << 5);    // use a tri-pane window
       public const int HHWIN_PROP_NOTB_TEXT        = (1 << 6);    // no text on toolbar buttons
       public const int HHWIN_PROP_POST_QUIT        = (1 << 7);    // post WM_QUIT message when window closes
       public const int HHWIN_PROP_AUTO_SYNC        = (1 << 8);    // automatically ssync contents and index
       public const int HHWIN_PROP_TRACKING         = (1 << 9);    // send tracking notification messages
       public const int HHWIN_PROP_TAB_SEARCH       = (1 << 10);   // include search tab in navigation pane
       public const int HHWIN_PROP_TAB_HISTORY      = (1 << 11);   // include history tab in navigation pane
       public const int HHWIN_PROP_TAB_FAVORITES    = (1 << 12);   // include favorites tab in navigation pane
       public const int HHWIN_PROP_CHANGE_TITLE     = (1 << 13);   // Put current HTML title in title bar
       public const int HHWIN_PROP_NAV_ONLY_WIN     = (1 << 14);   // Only display the navigation window
       public const int HHWIN_PROP_NO_TOOLBAR       = (1 << 15);   // Don't display a toolbar
       public const int HHWIN_PROP_MENU             = (1 << 16);   // Menu
       public const int HHWIN_PROP_TAB_ADVSEARCH    = (1 << 17);   // Advanced FTS UI.
       public const int HHWIN_PROP_USER_POS         = (1 << 18);   // After initial creation, user controls window size/position
       public const int HHWIN_PROP_TAB_CUSTOM1      = (1 << 19);   // Use custom tab #1
       public const int HHWIN_PROP_TAB_CUSTOM2      = (1 << 20);   // Use custom tab #2
       public const int HHWIN_PROP_TAB_CUSTOM3      = (1 << 21);   // Use custom tab #3
       public const int HHWIN_PROP_TAB_CUSTOM4      = (1 << 22);   // Use custom tab #4
       public const int HHWIN_PROP_TAB_CUSTOM5      = (1 << 23);   // Use custom tab #5
       public const int HHWIN_PROP_TAB_CUSTOM6      = (1 << 24);   // Use custom tab #6
       public const int HHWIN_PROP_TAB_CUSTOM7      = (1 << 25);   // Use custom tab #7
       public const int HHWIN_PROP_TAB_CUSTOM8      = (1 << 26);   // Use custom tab #8
       public const int HHWIN_PROP_TAB_CUSTOM9      = (1 << 27);   // Use custom tab #9
       public const int HHWIN_TB_MARGIN             = (1 << 28);   // the window type has a margin
    
    
       public const int HHWIN_BUTTON_EXPAND         = (1 << 1);    // Expand/contract button
       public const int HHWIN_BUTTON_BACK           = (1 << 2);    // Back button
       public const int HHWIN_BUTTON_FORWARD        = (1 << 3);    // Forward button
       public const int HHWIN_BUTTON_STOP           = (1 << 4);    // Stop button
       public const int HHWIN_BUTTON_REFRESH        = (1 << 5);    // Refresh button
       public const int HHWIN_BUTTON_HOME           = (1 << 6);    // Home button
    
       public const int HHWIN_BUTTON_SYNC           = (1 << 11);   // Sync button
       public const int HHWIN_BUTTON_OPTIONS        = (1 << 12);   // Options button
       public const int HHWIN_BUTTON_PRINT          = (1 << 13);   // Print button
    
       public const int HHWIN_BUTTON_JUMP1          = (1 << 18);
       public const int HHWIN_BUTTON_JUMP2          = (1 << 19);
       public const int HHWIN_BUTTON_ZOOM           = (1 << 20);
       public const int HHWIN_BUTTON_TOC_NEXT       = (1 << 21);
       public const int HHWIN_BUTTON_TOC_PREV       = (1 << 22);
    
       public const int HHWIN_DEF_BUTTONS = HHWIN_BUTTON_EXPAND | HHWIN_BUTTON_BACK | 
          HHWIN_BUTTON_OPTIONS | HHWIN_BUTTON_PRINT;
    
          	
    
       // Structures
       [StructLayout(LayoutKind.Sequential)]
       public struct Point 
       {
          public int x;
          public int y;
       };   
    
       [StructLayout(LayoutKind.Sequential)]
       public struct Rect 
       {
          public int left;
          public int top;
          public int right;
          public int bottom;
       };   
    
       [StructLayout(LayoutKind.Sequential)]
       public struct HH_WINTYPE 
       {
          public int     cbStruct;        // IN: size of this structure including all Information Types
    
          [MarshalAs(UnmanagedType.Bool)]
          public bool   fUniCodeStrings; // IN/OUT: TRUE if all strings are in Unicode
    
          [MarshalAs(UnmanagedType.LPStr)]
          public String pszType;         // IN/OUT: Name of a type of window
          public uint   fsValidMembers;  // IN: Bit flag of valid members (HHWIN_PARAM_)
          public uint   fsWinProperties; // IN/OUT: Properties/attributes of the window (HHWIN_)
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszCaption;      // IN/OUT: Window title
          public uint   dwStyles;        // IN/OUT: Window styles
          public uint   dwExStyles;      // IN/OUT: Extended Window styles
          public Rect    rcWindowPos;     // IN: Starting position, OUT: current position
          public int     nShowState;      // IN: show state (for example, SW_SHOW)
    
          public int  hwndHelp;          // OUT: window handle
          public int  hwndCaller;        // OUT: who called this window
    
          //			HH_INFOTYPE* paInfoTypes;  // IN: Pointer to an array of Information Types
          public int  paInfoTypes; // WARNING: this array is not marshalled!
    
          // The following members are only valid if HHWIN_PROP_TRI_PANE is set:
    
          public int  hwndToolBar;      // OUT: toolbar window in tri-pane window
          public int  hwndNavigation;   // OUT: navigation window in tri-pane window
          public int  hwndHTML;         // OUT: window displaying HTML in tri-pane window
          public int   iNavWidth;        // IN/OUT: width of navigation window
          public Rect  rcHTML;           // OUT: HTML window coordinates
    
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszToc;         // IN: Location of the table of contents file
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszIndex;       // IN: Location of the index file
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszFile;        // IN: Default location of the html file
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszHome;        // IN/OUT: html file to display when Home button is clicked
          public uint   fsToolBarFlags; // IN: flags controlling the appearance of the toolbar
          [MarshalAs(UnmanagedType.Bool)]
          public bool    fNotExpanded;   // IN: TRUE/FALSE to contract or expand, OUT: current state
          public int     curNavType;     // IN/OUT: UI to display in the navigational pane
          public int     tabpos;         // IN/OUT: HHWIN_NAVTAB_TOP, HHWIN_NAVTAB_LEFT, or HHWIN_NAVTAB_BOTTOM
          public int     idNotify;       // IN: ID to use for WM_NOTIFY messages
    
          [MarshalAs(UnmanagedType.ByValArray, SizeConst= HH_MAX_TABS + 1, ArraySubType = UnmanagedType.U1)]
          public byte    [] tabOrder;    // IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs
    
          public int     cHistory;       // IN/OUT: number of history items to keep (default is 30)
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszJump1;       // Text for HHWIN_BUTTON_JUMP1
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszJump2;       // Text for HHWIN_BUTTON_JUMP2
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszUrlJump1;    // URL for HHWIN_BUTTON_JUMP1
          [MarshalAs(UnmanagedType.LPStr)] 
          public String pszUrlJump2;    // URL for HHWIN_BUTTON_JUMP2
          public Rect    rcMinSize;      // Minimum size for window (ignored in version 1)
          public int     cbInfoTypes;    // size of paInfoTypes;
    
          // WARNING: this undocumented field is not marshalled
          public int pszCustomTabs;  // multiple zero-terminated strings
       };
    
          	
       // Function calls
    
       // internal interop helpers
       public static int HtmlHelp_DisplayTopic(
          int caller,
          String file)
       {
          return HtmlHelp(caller, file, HH_DISPLAY_TOPIC, 0);
       }
    
       // This helper is for getting a ptr to an HH_WINTYPE struct OUT as the dwData parameter. This is
       // used with the HH_GET_WIN_TYPE command.
       [DllImport("hhctrl.ocx", CharSet=CharSet.Unicode, EntryPoint="HtmlHelpW")]
       protected static extern int HtmlHelp_IntPtr_Helper(
          int caller,
          String file,
          uint command,
          ref IntPtr ps
          );
    
       // This overload is for performing the HH_SET_WIN_TYPE command, which passes an 
       // HH_WINTYPE value IN as the dwData parameter.
       [DllImport("hhctrl.ocx", CharSet=CharSet.Unicode, EntryPoint="HtmlHelpW")]
       protected static extern int HtmlHelp_SetWinType_Helper(
          int caller,
          String file,
          uint command,
          ref HH_WINTYPE wintype
          );
    
    
       // This overload is for passing a single uint value as the dwData parameter.
       [DllImport("hhctrl.ocx", CharSet=CharSet.Unicode, EntryPoint="HtmlHelpW")]
       protected static extern int HtmlHelp(
          int caller,
          String file,
          uint command,
          uint data
          );
    
       // This overload is for passing a string as the dwData parameter (for example, for the HH_DISPLAY_INDEX command)
       [DllImport("hhctrl.ocx", CharSet=CharSet.Unicode, EntryPoint="HtmlHelpW")]
       protected static extern int HtmlHelp(
          int caller,
          String file,
          uint command,
          String str
          );
         	
       // public entrypoints
    
       // This overload is for performing the HH_SET_WIN_TYPE command, which passes an 
       // HH_WINTYPE value IN as the dwData parameter.
       public static int HtmlHelp_SetWinType(
          int caller,
          String file,
          ref HH_WINTYPE wintype
          )
       {
          wintype.cbStruct = Marshal.SizeOf(wintype);
          wintype.fUniCodeStrings = false; // NOTE: this should be set to zero for proper 2-way marshalling
    
          return HtmlHelp_SetWinType_Helper(
             caller,
             file,
             HH_SET_WIN_TYPE,
             ref wintype);
       }
    
       public static int HtmlHelp_GetWinType(
          int caller,
          String file,
          ref HH_WINTYPE wintype)
       {
          IntPtr pwt = new IntPtr(0);
    
          int retval = HtmlHelp_IntPtr_Helper(
             caller,
             file,
             HH_GET_WIN_TYPE,
             ref pwt);
    
          // otherwise, let's try to marshal it
    
          wintype = (HH_WINTYPE)Marshal.PtrToStructure(pwt, typeof(HH_WINTYPE));
    
          return retval;
       }
    } 
    					
  4. Save the class.
back to the top

Call the HTML Help APIs

After they have been marshalled, you can call the HH_GET_WIN_TYPE and HH_SET_WIN_TYPE commands from the C# application. To do this, follow these steps:
  1. Open form1.cs in design mode, and then add two command buttons. Change the text of the button1 to Get Win Type and button2 to Set Win Type.
  2. Double-click the buttons to add button handlers, and then change the code to the following:
    //Call the HH_GET_WIN_TYPE API with a window type named 
    //"windefault" and a .chm file named, "notepad.chm".
    private void button1_Click(object sender, System.EventArgs e)
    {
       HHInterop.HH_WINTYPE w = new HHInterop.HH_WINTYPE();
       HHInterop.HtmlHelp_GetWinType(0,"notepad.chm>windefault",
          ref w); 
    
       // Display the window information.
       MessageBox.Show("Type = " + w.pszType +	"\nCaption = " +         
          w.pszCaption + "\n\nright= " +	w.rcWindowPos.right.ToString("D") +		
          "\nleft= " + w.rcWindowPos.left.ToString("D") +	"\nbottom = " +      
          w.rcWindowPos.bottom.ToString("D") + "\ntop = " +         
          w.rcWindowPos.top.ToString("D") + "\n\nTOC = " + w.pszToc +
          "\nIndex = " + w.pszIndex +"\nDefault File = " + w.pszFile +
          "\nHome = " + w.pszHome	);
    }
    
    // Call the HH_SET_WIN_TYPE API after setting various 
    // options in the HH_WINTYPE structure.
    private void button2_Click(object sender, System.EventArgs e)
    {
       HHInterop.HH_WINTYPE wt = new HHInterop.HH_WINTYPE();
    
       wt.pszType = "type1";  // This is the name of the window.
       wt.pszCaption = "Custom window type caption"; // window title
       wt.rcWindowPos.left = 500;
       wt.rcWindowPos.right = wt.rcWindowPos.left + 400;
       wt.rcWindowPos.top = 200;
       wt.rcWindowPos.bottom = wt.rcWindowPos.top + 600;
    
       wt.pszJump1 = "MSN";
       wt.pszUrlJump1 = "http://www.msn.com";
       wt.fsToolBarFlags = HHInterop.HHWIN_BUTTON_JUMP1;
       wt.fsWinProperties = HHInterop.HHWIN_PROP_TRI_PANE;
    
       wt.fsValidMembers = HHInterop.HHWIN_PARAM_PROPERTIES | 
          HHInterop.HHWIN_PARAM_RECT | HHInterop.HHWIN_PARAM_TB_FLAGS;
    
       int res = HHInterop.HtmlHelp_SetWinType(0,"notepad.chm",
          ref wt);
    
       res = HHInterop.HtmlHelp_DisplayTopic(0,"notepad.chm>type1");
    }
    					
  3. Save and build the solution.
  4. Click the Get Win Type button to see information about the Notepad window, and then click the Set Win Type button to change the window and display it.
back to the top

Sample download

The following sample is a Visual C# project that provides a more complete HTML Help Interop example and demonstrates other types of calls as well.

The following file is available for download from the Microsoft Download Center:
DownloadDownload the HHInterohttp://download.microsoft.com/download//VisualCSharp.netStan/Sample/2.0/NT5XP/EN-US/HHInterop1.exe.exe package now. Release Date: March 15, 2002

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to obtain Microsoft support files from online services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file. The hhinterop1.exe sample contains the following files:
   hhinterop1.csproj.user
   hhinterop1.sln
   hhinterop1.suo
   hhinterop1.cs
   hhinterop1.csproj
   AssemblyInfo.cs
   App.ico
   Form1.cx
   Form1.resx
				
back to the top

REFERENCES

For more information about how to use unmanaged code from Visual Studio .NET, visit the following MSDN Web site: back to the top

Modification Type:MajorLast Reviewed:12/29/2005
Keywords:kbAPI kbHOWTOmaster kbinterop KB317406 kbAudDeveloper