Context Sensitive help by context id

T

tbatwork828

If you were like me trying to figure out how to launch context
sensitive help topic by the context id, here is the link:

http://weblogs.asp.net/kencox/archive/2004/09/12/228349.aspx

and if link doesn't work, basically here is the article:

An Exploration Into Launching Context-Sensitive HTML Help with Topic
IDs in VB.NET
I spent this evening investigating the HTML Help API as implemented in
..NET. At work, I'm implementing HTML Help in a .NET 1.1 application.

It kept bugging me that I couldn't get any of the Help.ShowHelp
overloads to support context-sensitive Help that uses integers as
context/topic IDs. I'm referring to HTML Help projects that have a
[Map] section with declarations such as

[MAP]
#define HID_FIVE 5
#define HID_TEN 10

and an [ALIAS] section that turns the mapped values into topic names
like these

[ALIAS]
HID_FIVE=Topic_5.htm
HID_TEN=Topic_10.htm

When you use the HTML Help API in VB.NET, you can pass the Int32 value
to the HTML Help API (HtmlHelpA()) like this to launch a specific
topic:

Private Declare Function HTMLHelp_ContextId _
Lib "hhctrl.ocx" Alias "HtmlHelpA" _
(ByVal hWnd As IntPtr, _
ByVal lpHelpFile As String, _
ByVal wCommand As Int32, _
ByVal dwData As Int32) As Int32

Private Sub Button3_Click _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button3.Click
Dim RetVal As Int32
Const HH_HELP_CONTEXT = &HF
RetVal = HTMLHelp_ContextId _
(IntPtr.Zero, "CHM_Checker_Help.chm", _
HH_HELP_CONTEXT, 5)
End Sub

Likewise, if you use Interop, you can launch a specific topic like
this:

<System.Runtime.InteropServices.DllImport _
("hhctrl.ocx",
CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
Public Shared Function HtmlHelp _
(ByVal hwndCaller As System.Runtime.InteropServices.HandleRef, _
<System.Runtime.InteropServices.MarshalAs _
(System.Runtime.InteropServices.UnmanagedType.LPTStr)> _
ByVal pszFile As String, ByVal uCommand As Int32, _
ByVal dwData As Int32) As Int32
End Function

Private Sub Button1_Click _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim RetVal As Int32
Const HH_HELP_CONTEXT = &HF
Dim hr As New System.Runtime.InteropServices.HandleRef(Me,
Me.Handle)
RetVal = HtmlHelp(hr, "CHM_Checker_Help.chm", _
HH_HELP_CONTEXT, 10)
End Sub

When I looked at Help.ShowHelp in System.Windows.Forms using Reflector,
I saw that it is a wrapper around hhctrl.ocx as used in the preceding
InterOp sample. It takes diversions along the way through private
subroutines such as MapCommandToHTMLCommand and ShowHTML10Help.

But why couldn't I get ShowHelp to launch a specific topic? It seemed
like this should work:


Private Sub Button2_Click _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button2.Click
Dim intContextID As Integer
intContextID = 10
' Doesn't work!
Help.ShowHelp(Me, "CHM_Checker_Help.chm", _
HelpNavigator.Topic, intContextID)
End Sub

Then I realized that the command value for context ID Help calls needs
to be 15 but MapCommandToHTMLCommand was unable to return the command
value of 15 when it processed any of the HelpNavigator enum values,
including HelpNavigator.Topic. As it turns out, if you hardcode 15 into
the ShowHelp routine it works!:

Private Sub Button2_Click _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button2.Click
Dim intContextID As Integer
intContextID = 10
' This works but is slow
Help.ShowHelp(Me, "CHM_Checker_Help.chm", _
15, intContextID)
End Sub

When I compared the versions of MapCommandToHTMLCommand in .NET 1.1 and
the beta of .NET 2.0, I saw that this oversight/bug has been rectified.
The HelpNavigator enumeration in 2.0 includes a new value,
HelpNavigator.TopicId. And when MapCommandToHTMLCommand encounters it,
it now returns the value of 15 that we need.

BTW, the one thing you'll surely notice is how s-l-o-w Help.ShowHelp()
is when you open a context-sensitive topic by passing an integer. When
I get more time, I'm going to document the speed difference which
probably is caused by wrappers around wrappers and lots of Try/Catch
stuff to make sure the Help engine doesn't blow up.

Ken
Microsoft MVP [ASP.NET]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top