MS Help 2.x‎ > ‎H2 FAQ‎ > ‎

DExplore COM Interface

Interfacing to MS Help 2 DExplore Viewer using its undocumented COM Interface.
by Rob Chandler, MS Help MVP
Last Update: 24-May-2003

1. Introduction & Download

*** This API is Not Support by Microsoft ***

Dexplore is the document viewer that ships with VS and MSDN and is essentially MS's standard viewer for Help 2.x content. If you have ever looked at DExplore's limited set of command line parameters with disappointment then be disappointed no more. DExplore does have a rich (undocumented) COM interface. This document introduces you to that COM interface. And if this still does not satisfy then consider the two MVP H2 viewers that are available: Helpware viewer & HelpCenter viewer.

Most of the interface is obvious (if you are familiar with MS Help 2). Some corners of the interface are not so obvious and I invite anyone who wants to contribute to this document to please Contact me.

Demo source code is in Borland Delphi, however VB, C++, C# programmers who are familiar with COM should have no problems following and translating the code.

Download Demo: DExploreTest_exe.zip
Download Demo Delphi Source: DExploreTest_src.zip

2. Looking for Clues
  1. Import the type library for vshelp.tlb "VsHelp(Version 1.0)" from the following folder:
    c:\Program Files\Common Files\Microsoft Shared\MsEnv\

    Delphi 6: The import command is "Project > Import Type Library".
      After clicking "Create Unit" we now have vshelp_tlb.pas 
     
  2. Where did vshelp.tlb  come from? Search the registry for DExplore.exe:
     
    HKEY_CLASSES_ROOT\CLSID\{4A79114D-19E4-11d3-B86B-00C04F79F802}
    HKEY_CLASSES_ROOT\CLSID\{4A79114D-19E4-11d3-B86B-00C04F79F802}\TypeLib = {83285928-227C-11d3-B870-00C04F79F802}
    HKEY_CLASSES_ROOT\CLSID\{4A79114D-19E4-11d3-B86B-00C04F79F802}\LocalServer32 = c:\Program Files\Common Files\Microsoft Shared\Help\dexplore.exe
    HKEY_CLASSES_ROOT\CLSID\{4A79114D-19E4-11d3-B86B-00C04F79F802}\ProgID = DExplore.AppObj.7
    HKEY_CLASSES_ROOT\CLSID\{4A79114D-19E4-11d3-B86B-00C04F79F802}\VersionIndependentProgID = DExplore.AppObj

    HKEY_CLASSES_ROOT\TypeLib\{83285928-227C-11D3-B870-00C04F79F802}
    HKEY_CLASSES_ROOT\TypeLib\{83285928-227C-11D3-B870-00C04F79F802}\1.0\0\win32 = c:\Program Files\Common Files\Microsoft Shared\MSEnv\vshelp.tlb

    So vshelp.tlb is the Type Library file for DExplore. Note the COM Program ID = DExplore.AppObj.
    (note above is the VS 7.x DExplore GUID. VS 8.x has a different GUID)
     

  3. If you have .Net Framework SDK (.Net SDK) installed search the HTML files for DExplore.AppObj. This will show us some code and get us going. It's the only obvious code MS have left lying around that shows us how to use the interface.
     
    <SCRIPT language="jscript">
    var viewer;
    var helpHost;
    function Link(url)
    {
    viewer = new ActiveXObject("DExplore.AppObj.7");
    helpHost = viewer.Help;
    helpHost.SetCollection("ms-help://MS.NETFrameworkSDK", ".NET Framework SDK Documentation");
    helpHost.DisplayTopicFromURL(url);
    helpHost.SyncContents(url);
    }
    </SCRIPT>

    <A href="javascript:Link('ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpcongettingstartedwithnetframework.htm')">Getting Started with the .NET Framework </A>

    <A href="javascript:Link('ms-help://MS.NETFrameworkSDK/sdkstart/html/sdkstart.htm')">.NET Framework SDK documentation</A>

    This script simply loads the .NET SDK Collection into DExplore and displays and syncs a URL.

    helpHost = viewer.Help; This line is not clear since viewer.help normally contains the same thing as HelpHost anyway.

    Notice that DExplore is not marked Safe For Scripting (see 2. above) so opening DExplore via IE will cause a warning message to appear before executing the command.
     

3. Documentation

As stated there is no MS documentation so here's what we have found so far.

Special Note: Each call should be wrapped in a Try/Except block to trap errors (which occur if say a URL or collection parameter is not valid).

3.1 Base Commands

Getting the Help interface (Delphi example).

var  _VSHelpObj, _Help: Variant;
begin
    _VSHelpObj := CreateOleObject('DExplore.AppObj');
   _Help := _VSHelpObj.Help;       //note: what's the point here? Normally _helpHost == _VSHelpObj.Help anyway.

After creating your main COM object (in this case "_Help"), the SetCollection() and DisplayTopicFromURL() methods are normally all you need to open a collection and display a URL while showing the DExplore window.

_Help.SetCollection(nsName: WideString, sFilter: WideString);

 

Description:
Loads a collection (via its namespace) into DExplore. This command does not show the window. Most other calls will show the DExplore window if it is not already showing.
Use the "Collection" property to get the name of the currently loaded collection.
Params:
nsName - Namespace for the collection. eg.'ms-help://ms.vscc'
sFilter - Name of filter or empty string for no filtering.
Example:
Help.SetCollection('ms-help://ms.vscc','')
Help.SetCollection('ms-help://ms.vscc','Visual C#')
Property _Help.function Collection: WideString;
Description: [ReadOnly Property]
Collection is the Property linked to method Get_Collection. Returns the Name of the current collection loaded. To set the collection use the SetCollection() method (above).
_HelpHost.DisplayTopicFromURL(sURL: WideString);
Description:
Displays a topic in DExplore's embedded browser pane. This will make the DExplore window visible if not already visible (as will the other display type commands).
Params:
sURL - Internet Explorer compatible URL address.
Example:
Help.DisplayTopicFromURL('ms-help://MS.VSCC/MS.MSDNVS/vsintro7/html/vxoriWhatsNewInVisualStudio.htm')

3.2 TOC Control

_Help.SyncContents(sURL: WideString);
Description:
Syncs the Table of Contents control to the supplied URL.
Params:
sURL - Internet Explorer compatible address.
Example:
Help.SyncContents('ms-help://MS.VSCC/MS.MSDNVS/vsintro7/html/vxoriWhatsNewInVisualStudio.htm')
_Help.GetNextTopic(sURL: WideString): WideString;
Description:
Given a URL returns the next URL in the TOC control.
Params:
sURL - Internet Explorer compatible address.
_Help.GetPrevTopic(sURL: WideString): WideString;
Description:
Given a URL returns the previous URL in the TOC control.
Params:
sURL - Internet Explorer compatible address.
_Help.CanSyncContents(sURLWideString);
Description: ??
This probably tells you if a URL can be synced to or not (ie. Is there a corresponding URL in the current TOC). But given a valid or Invalid URL the method seems to do nothing but return with no exception.

3.3 Context Help Commands (F Index)

VS .NET tend to keep its help context mapping table in the "F" Index table of the help collection. The alternative is to keep your help context mappings in say an INI file that the main application can read and then calls DisplayTopicFromURL().

_Help.DisplayTopicFromId(sFile: WideString; Id: LongWord);
Description:
Lookup and display first topic found defined by Keyword "sFile + ':' + inttostr(id)" from the the "F" Index of the current collection.
Params:
sFile - Keyword prefix string. 
Id - Context Help Id to lookup and display. If =0 then only the sFile part (no ':' is appended) is used in the lookup.
Example:
Help.DisplayTopicFromId("vbasic", 12345):
Simply creates a keyword string: "vbasic:12345" and passes this string to  DisplayTopicFromF1Keyword(), which does a standard Help 2.0 lookup using the "F" index of the current collection (defined with the SetCollection() method).

DisplayTopicFromId("vbasic", 0) simply passes the keyword string "vbasic".
which essentially is the same thing as calling DisplayTopicFromF1Keyword("vbasic") directly.
_Help.DisplayTopicFromF1Keyword(sKeyword: WideString);
Description:
Does a standard Help 2.0 lookup using the "F" index of the current collection (defined with the SetCollection() method).
Params:
sKeyword - "F" Index Keyword to lookup and display.
Example:
Help.DisplayTopicFromF1Keyword("MyKeyword");
_Help.DisplayTopicFrom_OLD_Help(sFile: WideString; Id: LongWord);
Description:
Support for older style .CHM and .HLP files.
Params:
sFile - Full path to the .CHM or .HLP file.
Id - Context HelpId to lookup and display. If sFile does contain this Context Id then no action is taken.

3.4 Keyword Commands (K Index)

Visible keywords, displayed in the Index Navigation pane of DExplore, live in the "K" Index.

_Help.DisplayTopicFromKeyword(sKeyword: WideString);
 
Description:
Does a standard Help 2.0 lookup using the "K" index of the current collection (defined with the SetCollection() method). Displays the Keyword results in the results pane. If only one result match is found then DExplore displays the topic in the VS Browser Pane. It does not show the Index Nav pane if it was hidden or closed. Use Help.SyncIndex() to show the index navigation pane and sync to the index item.
Params:
sKeyword - "K" Index Keyword to lookup and display.
Example:
Help.DisplayTopicFromF1Keyword("BOOL");
_Help.SyncIndex(sKeyword: WideString; iShow: Integer);
 
Description:
Similar to DisplayTopicFromKeyword() excepts never displays the topic in the browser pane. If the Index pane was closed then only shows if iShow = 1 (0 = don't force show). If Index Nav pane is hidden (iconised) on the side then it is moved into view.
Params:
sKeyword - "K" Index Keyword to lookup and display.
Example:
Help.DisplayTopicFromF1Keyword("BOOL");

3.5 Navigation and Result Pane Select Commands

_Help.Contents;
 
Description:
Select the Contents navigation pane. Opens if closed.
_Help.Index;
 
Description:
Select the Index navigation pane.  Opens if closed.
_Help.Search;
 
Description:
Select the Search navigation pane.  Opens if closed.
_Help.IndexResults;
Description:
Select the Index Results pane if visible.  Opens if closed.
_Help.SearchResults;
Description:
Select the Search Results pane if visible.  Opens if closed.
_Help.Close;
Description: ??
Close the Web Browser window pane and all of its pages.
To get this pane back select "View > Web Browser" from the DExplore menu.

Rob Comment: What's the point of this command? A closed browser window just creates errors for the other commands.

3.6 Filter Commands

Note there is no method to applying a filterquery string. Applying a filter by its filtername works but these predefined filters can be edited by the user. Note: Our H2Viewer can apply filterquery strings.

_Help.FilterUI();
 
Description:
Displays the Filter Edit Page for editing Collection Filters. Throws exception if no filters defined in the collection or if the collection does not contain VS Filter setup info.
Params:
None.
Property _Help.Filter: WideString;
Description: [Read/Write Property]
Filter property is used to get/set the collection filter. This is the Filter name that represents a Filter Query string.
Property _Help.FilterQuery: WideString;
Description: [ReadOnly Property]
FilterQuery property returns the actual Query string for the current collection filter.
_Help.CanShowFilterUI();
Description: ??
Your guess is as good as mine. I cannot make it do much at all.
Params:
None.

3.7 Other ?

These commands have not part of the Delphi Demo.

_Help.DisplayTopicFromURLEx(sURLWideString
pIVsHelpTopicShowEventsIVsHelpTopicShowEvents);
 
Description: ??
One assumes this is the same DisplayTopicFromURL() with extra param. Looks like you specify a COM event to be triggered once the Topic has been successfully loaded. DisplayTopicFromURL() probably calls this function with the second param = null (nil for Delphi);
Property _Help.HxSession: IDispatch;
Description: [ReadOnly Property]
Returns the IHxSession interface. Use this to run queries, get the IHxCollection interface which then allows you to get attribute info etc etc.
There is no demo provided with this property as Microsoft have not released the H2 API information to the public.

_Help.Help: IDispatch read Get_Help;

Description: [ReadOnly Property] ??
This property gives you access to Help interface (all the methods and properties above). I'm not sure why we need it as initially when the COM object is created its interface address is the same as this property. One assumes that more than one help window can be controlled?

_VSHelpObj := CreateOleObject('DExplore.AppObj');   //returns interface address value xyz
_Help := _VSHelpObj.Help;              //also has interface address value xyz

_Help.GetObject(const bstrMonikerWideString; const bstrOptionsWideString):IDispatch;
Description: ??
My guess is this is yet another way to get into H2 API interfaces.
Property HelpOwner: IVsHelpOwner
Description: [Read/Write Property]
What does this do? One might guess that the help owner could be either VS embedded help or Help in DExplore?

 


Topics in Bold show the methods or properties successfully exercised in the accompanying Delphi demo and documentation above.
Topics prefixed with ? I have no idea about.

procedure Contents; safecall;
procedure Index; safecall;
procedure Search; safecall;
procedure IndexResults; safecall;
procedure SearchResults; safecall;
procedure DisplayTopicFromId(const bstrFile: WideString; Id: LongWord); safecall;
procedure DisplayTopicFromURL(const pszURL: WideString); safecall;
? procedure DisplayTopicFromURLEx(const pszURL: WideString; const pIVsHelpTopicShowEvents: IVsHelpTopicShowEvents); safecall;
procedure DisplayTopicFromKeyword(const pszKeyword: WideString); safecall;
procedure DisplayTopicFromF1Keyword(const pszKeyword: WideString); safecall;
procedure DisplayTopicFrom_OLD_Help(const bstrFile: WideString; Id: LongWord); safecall;
procedure SyncContents(const bstrURL: WideString); safecall;
? procedure CanSyncContents(const bstrURL: WideString); safecall;
function GetNextTopic(const bstrURL: WideString): WideString; safecall;
function GetPrevTopic(const bstrURL: WideString): WideString; safecall;
procedure FilterUI; safecall;
? procedure CanShowFilterUI; safecall;
procedure Close; safecall;
procedure SyncIndex(const bstrKeyword: WideString; fShow: Integer); safecall;
procedure SetCollection(const bstrCollection: WideString; const bstrFilter: WideString); safecall;
function Get_Collection: WideString; safecall;
function Get_Filter: WideString; safecall;
procedure Set_Filter(const pbstrFilter: WideString); safecall;
function Get_FilterQuery: WideString; safecall;
? function Get_HelpOwner: IVsHelpOwner; safecall;
? procedure Set_HelpOwner(const ppObj: IVsHelpOwner); safecall;
function Get_HxSession: IDispatch; safecall;
function Get_Help_: IDispatch; safecall;
? function GetObject(const bstrMoniker: WideString; const bstrOptions: WideString): IDispatch; safecall;
property Collection: WideString read Get_Collection;
property Filter: WideString read Get_Filter write Set_Filter;
property FilterQuery: WideString read Get_FilterQuery;
? property HelpOwner: IVsHelpOwner read Get_HelpOwner write Set_HelpOwner;
property HxSession: IDispatch read Get_HxSession;
property Help_: IDispatch read Get_Help_;


 Others Say

Subject: VS .NET 2003 - Using VsHelp.tlb with C#.
From: 
by Michael Waltuch from ESRI
Date: 24-May-2003

VS .NET 2003 - Using VsHelp.tlb with C#.
  1. Create a new Windows Application project.
  2. In the Project menu, select Add Reference.
  3. In the Add Reference dialog, select the COM tab.
  4. Click the Browse button and locate vshelp.tlb.
  5. Click the Component Name VsHelp and then click Select. Click OK.

View code for the form (Form1.cs).

Add a using directive for VsHelp: 
   using VsHelp; //remember to be aware of case-sensitivity. First and third characters are upper case

Create a method to display the help, for example:

   private void DispHelp(String url)
   {
       //Help interface must be fully qualified because its ambiguous otherwise
       VsHelp.Help h = new VsHelp.DExploreAppObjClass();
       h.SetCollection("ms-help://ms.vscc.2003","");
       h.DisplayTopicFromURL(url);
       h.SyncContents(url);
   }

Add a button to the form. Double-click it to view its Click event. Call the method you created earlier, for example:

   private void button1_Click(object sender, System.EventArgs e)
   {
       DispHelp("ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/vsintro7/html/vxori WhatsNewInVisualStudio.htm");
   }

Subject: Call MSHelp2 topic from C# via DTE
From: Charles Lloyd <...@epicor.com>
Date: 5-March-2004

Rob: As Charles suggests you can also access VS .NET IDE via the DTE Object. For more info see VS: Referencing the DTE Object

Just in case anybody is interested in comparing examples of the Dexplore COM interface and referencing the DTE to do the same thing (call a Help2 topic via an "F" keyword from a custom C# form inside of Visual Studio).

Dexplore way (see Helpware site for details):

private void displaySDKF1(string F1Keyword)
{
VsHelp.Help h = new VsHelp.DExploreAppObjClass();
h.SetCollection("ms-help://MS.VSCC.2003","");
h.DisplayTopicFromF1Keyword(F1Keyword);
}

Cons: not officially supported. Error handling tougher. Pro: probably will
continue to work between changing versions of VS.

DTE way (add reference to envdte .NET dll):

private void displayViaDTE(string F1Keyword)
{
EnvDTE.DTE dte;
dte =
(EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualSt
udio.DTE.7.1");
dte.ExecuteCommand("Help.F1Help",F1Keyword);
}

Cons: must have an instance of VS running.

VS 2005 API

MVP Rob Cavicchio posts that VS 2005 now has its own Help 2 API which MS have published in MSDN.

http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vshelp80.help2(vs.80).aspx

Comments