|
-
Feb 7th, 2012, 10:55 AM
#1
Thread Starter
Junior Member
HTML Help Time Bomb
I am attempting to implement HTML Help into my application. I am working with a sub in a common class, in which the calling form sends its hWnd and a specific topic ID, and the help topic is shown. I also added a function to the class to call HH_CLOSE_ALL.
What I am trying to do is set up a reference to the class in any forms that need a help topic. I could set up a button or catch the F1 key to display a help topic, and then call the method to close the help when the form is unloaded.
The problem is that VB will almost always crash after I close the running application--sometimes immediately after execution ends, and sometimes it takes as much as 15 minutes before VB suddenly shows fatally shuts down.
Any thoughts on what I'm doing wrong?
I'll include a condensed version of what I am doing.
My class (clsHTMLHelp):
Code:
Option Explicit
Private Const HELP_FILE = "MyHelpFile.chm"
Private Const HH_HELP_CONTEXT = &HF
Private Const HH_CLOSE_ALL = &H12
Private Declare Function HTMLHelp Lib "hhctrl.ocx" Alias "HtmlHelpA" (ByVal hwnd As Long, _
ByVal lpHelpFile As String, ByVal wCommand As Long, ByVal dwData As Long) As Long
Public Sub ShowHelp(ByVal hwnd As Long, ByVal plngTopicID As Long)
Dim strHelpFile As String
Dim lngAPIResult As Long
strHelpFile = App.Path & "\Help\" & HELP_FILE
lngAPIResult = HTMLHelp(hwnd, strHelpFile, HH_HELP_CONTEXT, CLng(plngTopicID))
End Sub
Public Sub ShutDownHelp(ByVal hwnd As Long)
HTMLHelp hwnd, "", HH_CLOSE_ALL, CLng(0)
End Sub
A form refrencing the class:
Code:
Option Explicit
Private mclsHelp As clsHTMLHelp
Private Sub cmdShowHelp_Click()
mclsHelp.ShowHelp Me.hwnd, 1
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyF1 Then
mclsHelp.ShowHelp Me.hwnd, 1
End If
End Sub
Private Sub Form_Load()
Set mclsHelp = New clsHTMLHelp
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
mclsHelp.ShutDownHelp Me.hwnd
Set mclsHelp = Nothing
End Sub
-
Feb 7th, 2012, 11:18 AM
#2
Re: HTML Help Time Bomb
See HH_CLOSE_ALL Bug and HH_INITIALIZE.
Also:
You should not create a bunch of these class instances, you want a singleton.
The best way to do this is to have one global instance of the class. This can be created in Sub Main() or it can be done through other techniques such as editing the .CLS file outside the IDE and setting Attribute VB_PredeclaredId = True in it and then re-opening your Project in the IDE.
In the Form_Load of your main Form you would make a call with HH_INITIALIZE and retain the result (which is a window handle). You would pass the hWnd of your main Form when making this and any other calls, so this should be cached inside your class when you make this (separate) INIT call.
Beyond this follow the suggestions at the link above to close HTML Help's window properly when the main Form closes.
-
Feb 7th, 2012, 03:53 PM
#3
Thread Starter
Junior Member
Re: HTML Help Time Bomb
Thanks for the link. I will try it out and see how it works in my application.
 Originally Posted by dilettante
You should not create a bunch of these class instances, you want a singleton.
The best way to do this is to have one global instance of the class. This can be created in Sub Main() or it can be done through other techniques such as editing the .CLS file outside the IDE and setting Attribute VB_PredeclaredId = True in it and then re-opening your Project in the IDE.
I don't believe my actual application is set up to create a separate instance of the class for each form, like it is on the demo I posted. Looking at the class where we're adding the HTML Help routines, I notice it is instanced as GlobalMultiUse.
-
Feb 9th, 2012, 05:12 PM
#4
Thread Starter
Junior Member
Re: HTML Help Time Bomb
I've tried a modification to my previous code that uses HH_INITIALIZE and HH_UNINITIALIZE, based on what I've found by Googling the two constants. Is something like this what you had in mind, dilettante? So far, VB hasn't crashed (knock on wood). 
Changes to clsHTMLHelp:
Code:
...
Private Const HH_HELP_CONTEXT = &HF
Private Const HH_CLOSE_ALL = &H12
Private Const HH_INITIALIZE = &H1C
Private Const HH_UNINITIALIZE = &H1D
Private Declare Function HTMLHelp Lib "hhctrl.ocx" Alias "HtmlHelpA" (ByVal hwnd As Long, _
ByVal lpHelpFile As String, ByVal wCommand As Long, _
dwData As Long) As Long 'Previously ByVal.
Public Sub InitializeHelp(ByRef plngCookie As Long)
HTMLHelp 0, "", HH_INITIALIZE, plngCookie
End Sub
Public Sub UninitializeHelp(ByRef plngCookie As Long)
HTMLHelp 0, "", HH_UNINITIALIZE, plngCookie
End Sub
...
Changes to the form:
Code:
Option Explicit
Private mclsHelp As clsHTMLHelp
Private mlngCookie As Long
...
Private Sub Form_Load()
Set mclsHelp = New clsHTMLHelp
mclsHelp.InitializeHelp mlngCookie
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
mclsHelp.ShutDownHelp Me.hwnd
mclsHelp.UninitializeHelp mlngCookie
Set mclsHelp = Nothing
End Sub
Of course, I'm keeping in mind your earlier comment about having only one instance of the help class. The demo program I'm trying this on only has this one form, but my thought is to place the calls to my Initialize and Uninitialize onto the Load and QueryUnload of the main form for my actual application.
-
Feb 9th, 2012, 08:31 PM
#5
Re: HTML Help Time Bomb
This looks pretty good to me.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|