Delphi Chandler
Delphi Chandler
Delphi Programming
for the
HTML Help API
by Robert Chandler
The Helpware Group
http://www.helpware.net
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 2
Limitation of liability
No patent liability is assumed with respect to the use of the information contained
herein or accompanying sample files. Although every precaution has been taken in the
preparation of these materials, the publisher/author assumes no responsibility for errors
or omissions. Neither is any liability assumed for damages resulting from the use of the
information contained herein.
Trademarks
All terms mentioned in this book that are known to be trademarks or service marks have
been appropriately capitalized. Cheryl Lockett Zubak/ Work Write, Inc./Help Think Press
cannot attest to the accuracy of this information. Use of a term in this book should not
be regarded as affecting the validity of any trademark or service mark.
You can reach Cheryl Lockett Zubak at Work Write, Inc., 128 South Eastview Avenue,
Feasterville, PA 19053 USA. Phone: +1 (215) 357-3453; fax +1 (215) 357-0695; email
[email protected]; website http://www.workwrite.com.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 3
Table of contents
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 4
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 5
Delphi Programming
for the
HTML Help API
by Robert Chandler
The Helpware Group
http://www.helpware.net
T his chapter covers HTML Help programming using Borland’s 32-bit Delphi
(i.e., Delphi 2 and above). While Delphi does not support HTML Help
directly, Delphi is a very rich and flexible programming environment. We
will see that it takes very little effort to convert our WinHelp Delphi appli-
cations to HTML Help.
The chapter assumes that you have a basic working knowledge of Delphi
programming and have glanced at the HTML Help API reference in the
Microsoft HTML Help Workshop online help. In this chapter, we will cover
such subjects as:
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 6
http://msdn.microsoft.com/library/en-us/htmlhelp/html/vsconHH1Start.asp
http://www.helpware.net/delphi/
Joining the Helpware mailing list is the easiest way to keep up with all the
latest updates and news.
As we work through the chapter I will point you towards the appropriate
code examples.
Location Description
\Example 1 Accessing the HH API using static loading. Common HH API calls.
\Example 10 A Delphi port of Ralph Walden’s code that reads the file structure
of a CHM help file. This chapter will not cover this area..
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 7
Location Description
\Example12 Delphi 6 broke the OnHelp event used to trap all Delphi help
events. This example shows you how to fix this bug in Delphi 6.
All examples can be compiled under Delphi 3 or greater, except for: Example
5 contains Delph 3 and Delphi 4 and greater examples; Example 7 requires
Delphi 4 or greater; Example 12 is designed for Delph 6 only. Most examples
will compile under Delphi 2 if given a little push.
Getting started
While HTML Help requires that you install a minimum of Internet Explorer
3, Internet Explorer 5 or higher is highly recommended. In fact, some
HTML Help features, such as word search highlighting, only work if you
have Internet Explorer 4 or above. Versions of HTML Help earlier than 1.2
are not very compatible with Delphi due to window parenting problems
(more about this later). I also advise Delphi 3 users to upgrade to Delphi 4
or 5 to resolve other problems.
Installing the latest version of both Internet Explorer and HTML Help will
ensure that you have the latest bug fixes and optimizations. You will find
the latest versions of Internet Explorer, HTML Help, and HTML Help
Workshop programs on the Microsoft web site.
The following table will help you to check if your Windows operating
system requires an update.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 8
A few notes
u Windows 3.X and Windows NT 3 are not suitable for displaying HTML Help.
u Check the version of Internet Explorer by looking in the Help > About Box. Check the version of
HTML Help by opening the About box in the HTML Help Workshop. Alternatively open any CHM
file, click the system menu gadget in the top left corner of the window, and select version.
u For applications, the Internet Explorer version number can be read from shdocvw.dll, while the
HTML Help version number can be read from hhctrl.ocx. Both these files are installed into the
windows system folder. Be aware that hhctrl.ocx is an ActiveX control, and as such can be
installed to the windows ActiveX cache when a web page that uses the control is opened. I’ll
show you how to find hhctrl.ocx later.
Delphi does not ship with an HTML Help import unit, so the first thing we
must do is port the basic elements of the C++ header file, htmlhelp.h, to a
Delphi unit file. If you have installed the HTML Help Workshop, you can
find a copy of htmlhelp.h installed in the include folder. Here is the default
location of htmlhelp.h:
Note: I have already ported htmlhelp.h to Delphi for you. The import unit has the name hh.pas,
since a Delphi unit and function name cannot be the same. Hh.pas can be found with the other
examples code.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 9
Let’s look at both methods in detail and you can decide which you want to
use.
Static loading
Static loading, also known as implicit dynamic linking, is performed at
application load time by the operating system. It is the simplest and the
most common method of importing API functions under Delphi.
Here is the Delphi declaration for accessing the HTML Help API. The three
most common commands are also declared. Look inside any import unit
such as windows.pas and you will see this kind of code.
interface
uses Windows;
function HtmlHelpA(hwndCaller: HWND; pszFile: PAnsiChar;
uCommand: UINT; dwData: DWORD): HWND; stdcall;
function HtmlHelpW(hwndCaller: HWND; pszFile: PWideChar;
uCommand: UINT; dwData: DWORD): HWND; stdcall;
function HtmlHelp(hwndCaller: HWND; pszFile: PChar;
uCommand: UINT; dwData: DWORD): HWND; stdcall;
const
hhctrlLib = hhctrl.ocx;
const
{ Commands to pass to HtmlHelp() }
HH_DISPLAY_TOPIC = $0000;
HH_HELP_CONTEXT = $000F;
HH_CLOSE_ALL = $0012;
implementation
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 10
Three function names are declared: HtmlHelpA for the ansi-character version
of the function, HtmlHelpW for the wide-character (unicode) version, and
HtmlHelp. HtmlHelp currently uses the ansichar-version HtmlHelpA and is
the function we will use in all examples.
Dynamic loading
Dynamic loading, also known as explicit dynamic linking, is performed at run-
time by making calls to the operating system to load the DLL using the
LoadLibrary() and FreeLibrary() functions.
This approach is more complex but will produce a more robust application.
Let’s walk through the code (below).
It’s a bigger slab of code, but there is not much to it, really. It includes a
global variable called HHCtrlHandle. The variable is non-zero if the HTML
Help library was found and loaded successfully. The code also uses the
HTML Help function HtmlHelp(), which is valid only when HHCtrlHandle
is non-zero. The code also has two procedures, LoadHtmlHelp() and
UnloadHTMLHelp(), which can be called on module initialization and
finalization. The first function calls LoadLibrary(), while the other calls
FreeLibrary().
LoadLibrary() requires the full path to hhctrl.ocx. Ralph Walden, one of the
original authors of HTML Help, suggests that we can find the full path by
reading the default value of the following Windows registry key.
[HKEY_CLASSES_ROOT\CLSID\{adb880a6-d8ff-11cf-9377-
00aa003b7a11}\InprocServer32]
interface
var
{ =0 if HTML Help could not be loaded}
HHCtrlHandle: THandle = 0;
{ Externals from HHCTRL.OCX }
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 11
const
hhctrlLib = hhctrl.ocx;
const
{ Commands to pass to HtmlHelp() }
HH_DISPLAY_TOPIC = $0000;
HH_HELP_CONTEXT = $000F;
HH_CLOSE_ALL = $0012;
implementation
const hhPathRegKey =
CLSID\{adb880a6-d8ff-11cf-9377-00aa003b7a11}\InprocServer32;
{ Returns full path to hhctrl.ocx.
Returns empty string if file or registry entry not found.}
function GetPathToHHCtrlOCX: string;
var Reg: TRegistry;
begin
result := ; //default return
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CLASSES_ROOT;
if Reg.OpenKeyReadOnly(hhPathRegKey) then
begin
result := Reg.ReadString(); //default value
Reg.CloseKey;
if (result <> ) and (not FileExists(result)) then
result := ;
end;
Reg.Free;
end;
{setup HTML Help API function interface
HHCtrlHandle = 0 if API functions not available }
procedure LoadHtmlHelp;
var OcxPath: string;
begin
if HHCtrlHandle = 0 then //not already loaded
begin
OcxPath := GetPathToHHCtrlOCX;
if (OcxPath <> ) and FileExists(OcxPath) then
begin
HHCtrlHandle := LoadLibrary(PChar(OcxPath));
if HHCtrlHandle <> 0 then
begin
@HtmlHelpA := GetProcAddress(HHCtrlHandle, HtmlHelpA);
@HtmlHelpW := GetProcAddress(HHCtrlHandle, HtmlHelpW);
@HtmlHelp := GetProcAddress(HHCtrlHandle, HtmlHelpA);
end;
end;
end;
end;
procedure UnloadHtmlHelp;
begin
if HHCtrlHandle <> 0 then
begin
FreeLibrary(HHCtrlHandle);
HHCtrlHandle := 0;
end;
end;
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 12
While we are looking at the HtmlHelp() function and its parameters, I will
draw attention to a few problems we have using it under Delphi.
hwndCaller
Set this to zero. Some programmers use GetDesktopWindow() but zero will
do fine. To make the help window stay on top of the application, set
hwndCaller to the handle of the owner window. Some advanced HTML
Help commands also requires a window handle so that the HTML Help API
knows where to send notification messages. That brings us to problem one.
P roblem 1. Run example 1 or 2 and open help in stay on top mode, then
open a modal form and click on the help window. At this stage the Delphi
application gets confused and the modal form falls behind the main form.
Note that this works fine under C++ and VB. The problem is probably due
to the special way in which Delphi manages forms. I recommend that you
stick with zero or GetDesktopWindow. If you do need to specify an owner
window, then you should close the help window before opening modal
windows.
P roblem 2. The first problem is accentuated under HTML Help 1.0, where
the help window actually becomes locked between the main form and the
modal form. This happens even when using zero or GetDesktopWindow. I
recommend that you stick with HH 1.2 and above.
pszFile
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 13
uCommand
Specify an API command. Here are the three most commonly used com-
mands.
Command Description
HH_DISPLAY_TOPIC Opens a help file. Optionally you can specify a help topic and
help window. Set dwData to zero.
HH_HELP_CONTEXT Opens a help topic using a help context ID. Optionally you can
specify a help window. Set pszFile to the CHM file. Set dwData to
the help context ID.
HH_CLOSE_ALL Closes all help windows that have been opened by the applica-
tion. Set all other parameters to zero or nil.
dwData
Function return
Depends on the command. Normally returns the handle of the help win-
dow.
Using a help window’s handle, your application can use Windows API
functions to hide, show, position, resize, minimize, maximize, restore, or
close a help window. For example, you could tile the help and application
windows using Windows API function SetWindowPos(). Another example
is making the help window minimize and restore with the application
window. Code Example 8 contains these and several other examples.
But what if the user closes the help window? Before using a handle you
should check that it is still valid by calling Windows API function
IsWindow(hWnd).
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 14
The first two Delphi code examples demonstrate the three basic API com-
mands we have talked about so far. The examples programs contain a modal
dialog so you can experience the Delphi HTML Help modal window prob-
lem first hand.
Example 1 and 2 are actually the same, except that example 1 uses static
loading and example 2 uses dynamic loading.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 15
Each topic in a compressed help (.chm) file is actually a separate HTML file.
You can think of the CHM file as a mini file system. The help author
compiles a collection of HTML files into a single compressed help file using
some HTML Help authoring tool, such as Microsoft HTML Help Workshop.
Microsoft also provides a command line compiler called hhc.exe. The help
project (.hhp) file tells the compiler how to compile the help. When we
display a help topic, the API opens the specified CHM help file, decom-
presses the requested topic file, and then loads the file into the topic pane of
the help window.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 16
fn := c:\help\myfile.chm::/htm/intro.htm;
HtmlHelp(0, PChar(fn), HH_DISPLAY_TOPIC, 0);
If we supply only the path to the help file, the help window opens using
the default topic and default window type as defined in the help file.
fn := c:\help\myfile.chm;
HtmlHelp(0, PChar(fn), HH_DISPLAY_TOPIC, 0);
To display the topic using a window type called “main,” we would use the
following notation. Again we could omit the “::/htm/intro.htm” part to
display the default topic.
fn := c:\help\myfile.chm::/htm/intro.htm>main;
HtmlHelp(0, PChar(fn), HH_DISPLAY_TOPIC, 0);
I should mention that a fully qualified CHM path must include the
pluggable protocol prefix. This is optional for calls to the HTML Help API.
The protocol “mk:@MSITStore:” works with IE3 and greater, while “ms-
its:”, or “its:” for short, works with IE4 and greater. When would you need
to specify a full path? Opening a CHM topic in Internet Explorer is one
situation that comes to mind.
For example:
ms-its:c:\help\myfile.chm::/htm/intro.htm>main
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 17
Here is an example of a typical context help call. We specify the help file to
open and a help context ID of 1001.
fn := c:\help\myfile.chm;
HtmlHelp(0, PChar(fn), HH_HELP_CONTEXT, 1001);
fn := c:\help\myfile.chm>main;
HtmlHelp(0, PChar(fn), HH_HELP_CONTEXT, 1001);
Here is an example of a typical ALIAS and MAP section. The MAP section
defines an identifier and assigns our integer context ID to it. While the
ALIAS section associates that identifier with a help topic.
[ALIAS]
IDH_HomePage=default.htm
IDH_TestTopic1=htmlfiles\testtopic1.htm
IDH_TestTopic2=mychm::htmlfiles\testtopic2.htm
[MAP]
#define IDH_HomePage 1000
#define IDH_TestTopic1 1001
#define IDH_TestTopic2 1002
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 18
[ALIAS]
#include myhelp.ali
[MAP]
#include myhelp.h
IDH_HomePage=default.htm
IDH_TestTopic1=htmlfiles\testtopic1.htm
IDH_TestTopic2=mychm::htmlfiles\testtopic2.htm
Tip: You should add the header and alias files to the [FILES] section of the .hhp file to
ensure that the compiler finds the files.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 19
When F1 is pressed, Delphi grabs the HelpContext value of the control that
has the focus. If this value is zero then Delphi iterates down though the
layers of parent controls, right down to the form level. Delphi takes the
first non-zero HelpContext value found and makes the call to the WinHelp
API for you using that help context ID. If only zero context IDs are found
then the help call is not made. Refer to the Delphi online help if you need to
know more about how this all works.
We now have a problem because Delphi is setup to use the WinHelp API but
we want to use the HTML Help API.
type
TForm1 = class(TForm)
..
procedure HelpBtnClick(Sender: TObject);
private
FOldHelpEvent: THelpEvent;
function HelpHook(Command : Word; Data : Longint;
Var CallHelp : Boolean) : Boolean;
public
mHelpFile: String;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 20
Let’s walk through the code snippet above. We have created an event
handler called HelpHook(). We assign our function HelpHook() to
Application.OnHelp in the OnCreate event of our main form. All Delphi
HelpContext and the HelpJump methods will now trigger the HelpHook()
handler which converts the WinHelp context help calls to HTML Help.
The Data value contains our Help Context ID. We restore OnHelp in the
form’s OnDestroy() event.
Even the help call under the help button will pass though our handler. The
help button click event calls Application.HelpContext(HelpContext) which
also gets diverted to the HTML Help API via HelpHook().
To find the possible values of the Command and Data parameters, search
for WinHelp in the Win32 Developer ’s Reference Help (Win32.HLP) file,
which explains the WinHelp API. The possible values for the Data param-
eter depend upon the value of the Command parameter.
Code example 3
Code Example 3 uses the above code. Run the compiled executable, tab to
any control and press F1 to open HTML Help online help.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 21
Code example 12
The Delphi 6 release has broken the OnHelp event. Only a few help events
are not caught by the OnHelp event. Fortunately we can program the new
Delphi 6 Help Manager to catch these lost events and pass them correctly
onto either Form.OnHelp or Application.OnHelp. The fix is easy to imple-
ment. Simple USE the supplied unit “D6OnHelpFix.pas” anywhere in your
project. Example 12 demonstrates this fix. Try commenting out
“D6OnHelpFix” from the USES section and you will see that half of the
help events stop firing.
It takes a lot of work to setup a large application with field level contextual
help (Personally I don’t think that most users really gain much from having
field sensitive help. Help provided at the page or dialog level can provide a
more unified help solution for the user. But that’s just my opinion).
Note: The What’s This button in the title bar will not show if you have minimize or maximize
buttons.
Delphi provides limited support for What’s This help by placing the ques-
tion mark icon in the form’s title bar for us. When you click the icon, the
cursor changes to crHelp but everything else requires work from us.
To enable the title bar help icon, set the form’s BorderIcons property to
include biHelp. The button will be seen at run-time only if BorderStyle is
set to bsDialog or biMinimize, and biMaximize id excluded.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 22
Most applications will also require a “What’s This” toolbar button and help
menu item. To accomplish this, call the following code. Here is my “What’s
This” toolbar button click event code.
case Command of
HELP_CONTEXT: //help button - data = helpcontext ID
HtmlHelp(0, PChar(mHelpFile), HH_HELP_CONTEXT, Data);
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 23
else
CallHelp := TRUE; //default handling
end;
result := TRUE;
end; { THookHelpSystem.HelpHook }
To understand how Delphi manages the help events, checkout the Delphi
source code in Forms.pas. All WM_HELP events come through
TCustomForm.WMHelp. Notice that if biHelp border icon is set, two help
commands are called. The first contains the x,y coordinates of the control,
the second contains the controls helpcontext ID.
We now have all our help events coming through a single function. We have
the controls x,y coordinates and its helpcontext ID. All we need to do now
is make the call to the HTML Help API to display a popup window.
Code example 4
You can see the finished result by running the Example 4 demo. Click the
question mark then click one of the controls on the first page.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 24
This method is not too useful to us. It offers no control over popup
attributes. It does not allow line breaks. It requires the handle of the
control, which we do not have so far. Sure we could get the handle with
some work, but then why fight Delphi.
For completeness I’m going to quickly cover all these methods of displaying
a text popup. All these examples can be found in Example 4.
Both API commands can display text defined in a CHM help file so let’s see
how to do this first. Here is an example. Create a text file called cdhelp.txt
and type in the following popup window topics.
<file: cdhelp.txt>
.Topic 99
This is my test popup text with ID=99
The source lives in help.chm::/cshelp.txt
.Topic IDH_POPUP_NEWBTN
Click new to New to create a new file.
.Topic IDH_POPUP_OPENBTN
Click new to New to create a new file.
You can write the context ID number directly into the text file as seen
above with Topic 99. Or you can define identifiers in a separate C++
header file as I have done with the other 2 declarations.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 25
<file: cdhelp.h>
#define IDH_POPUP_NEWBTN 61
#define IDH_POPUP_OPENBTN 62
Lasty we need to add the following lines to our help project (.hhp) file and
compile it to a CHM file. Here is my help project file.
<file:help.hhp>
[MAP]
#include cshelp.h
[TEXT POPUPS]
cshelp.h
cshelp.txt
[FILES]
cshelp.h
cshelp.txt
Tip: Some people have found that including the name of the text and header files in the [FILES]
section fixes a bug where the mapping information sometimes cannot be found by the chm.
dwIDs[0] := ShowHHPopupBtn.Handle;
dwIDs[1] := 99;
dwIDs[2] := 0;
dwIDs[3] := 0;
HtmlHelp(ShowHHPopupBtn.Handle, PChar(c:\test\help.chm::/
cshelp.txt),
HH_TP_HELP_CONTEXTMENU, DWORD(@dwIDs[0]));
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 26
This is the more powerful of the two API popup commands. We simply fill
in a THHPopup structure and make the call.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 27
Finally the third and last example (below) tells the API to grab the popup
text from the text file in a chm, like we did in the
HH_TP_HELP_CONTEXTMENU example. Notice the second parameter is
now defined as the path to the topic text file in the chm.
clrForeground := COLORREF($000000FF);
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 28
clrForeground := COLORREF($00FF0000);
The pszFont parameter allows you to specify a font. Use an empty string
for the default font or specify ‘facename, point size, char set, BOLD ITALIC
UNDERLINE’. You can leave a parameter blank to specify that the default
value should be used.
Example: Char set is not specified so the default charset will be used:
More help on popups can be found in the API reference in Workshop online
help.
HTML Help 1.x provides plain text popups only. Some third party vendors
are developing Rich HTML popups. The best example is KeyHelp, devel-
oped by KeyWorks Software, a division of Work Write, Inc.:
http://www.keyworks.net/keyhelp.htm
u To make the application more robust. As you will soon see, playing host
to the HTML Help API can be dangerous. If help falls over it may take
your application with it.
u You may have a requirement to keep the help window opened when the
executable is closed. Normally all help windows opened by the execut-
able are closed automatically when the application shuts down.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 29
The HTML Help API is an OCX but we use it like a normal DLL. When a
process loads a DLL, the system maps the code and data for the DLL into
the address space of the process. For 32-bit Windows, DLLs become part of
the process that loads the DLL. Any memory allocation calls made by
functions in the DLL cause memory to be allocated from the process’s
address space.
Only one copy of a DLLs code and data is ever kept in memory. Since code
and data parts do not change it is safe for the operating system to simply
map them into the address space of each process that loads them.
So looking at the bigger picture… we have our application that plays host
to the HTML Help API. The HTML Help window itself plays host to the
Internet Explorer WebBrowser control, Shdocvw.dll. The WebBrowser
control in turn plays host to… well, think about all those things you can
run in Internet Explorer. Now think about the number of times your
browser crashes in a day. Okay so your online help is plain text and graph-
ics, in which case you have nothing to be nervous about, maybe?
u Your help topics can call external helper programs using HTML Help
shortcut commands. Not as flexible as ActiveX but very simple to
implement. See Workshop help for further info on using shortcuts.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 30
Write a small non-Delphi application that loads the help API and accepts
command line parameters to perform the required help commands. The
program should be run only when required. The main window should be
invisible. Remember that the help windows owned by the application will
close automatically when the application closes, so you must keep the
executable running until all its help windows are closed. A way to achieve
this is to store the window handles returned by API function calls, Imple-
ment a timer event and periodically check if the window handle is still valid
using windows API function IsWindow().
Mmm. This solution is probably more work than we expected. Never mind
there are two programs already available that will do the job. Both are
written in C++ and both are free.
HH.EXE ms-its::path/help.chm::/path/topic.htm
HH.EXE mk:@MSITStore::path/help.chm::/path/topic.htm
Note: The mk:@MSITStore protocol works with IE3 and above while ms-its works with IE4
and above. A shorter version of “ms-its” is to just use “its”. Actually, the later versions
of HH don’t even require the protocol prefix.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 31
You can get more information about KeyHH.EXE from the KeyWorks
web site at:
http://www.keyworks.net/keyhh.htm
u If you have a copy of MS Visual Basic then David Liske’s HTML Help
DLL makes creating a VB exe with HH support a snap. The DLL also
works with Delphi applications.
http://www.mvps.org/htmlhelpcenter/
HH.pas
This unit is a port of the C++ header file “htmlhelp.h”. It contains all the
HTML Help commands and data structures as well as an interface to the
API function HtmlHelp() using dynamic DLL loading. The LoadLibrary()
call is made during module initialization.
HH_Funcs.pas
This optional unit contains other HTML Help related functions:
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 32
Documentation for the units can be found in file hh_doc.txt found in the
same folder.
The latest version of these units are kept on my web site at:
http://helpware.net/delphi/
u Programming HH Windows
Code Example 4
Code Example 4 demonstrates the above topics. I don’t want to fill the
chapter with code, so I will refer to the source code in “Example
4\Unit1.pas” as we go along. The executable is called “Example
4\WhatsThis.exe”
HH_DISPLAY_TOC
s := c:\test\help.chm;
HtmlHelp(0, PChar(s), HH_DISPLAY_TOC, 0);
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 33
Optionally, you can open help at a specific topic. But this only works if the
help window is originally closed.
s := c:\test\help.chm::/htmlfiles\testtopic2.htm;
HtmlHelp(0, PChar(s), HH_DISPLAY_TOC, 0);
HH_DISPLAY_INDEX
HH_DISPLAY_SEARCH
This command opens help at the search tab. The command requires that we
fill in a THHFtsQuery record. Optionally you can perform a search, but this
appears to be broken under HH 1.x.
var q: THHFtsQuery;
begin
q.cbStruct := sizeof(q); //Sizeof structure in
//bytes.
q.fUniCodeStrings := FALSE; //all strings are
//unicode.
q.pszSearchQuery := test; // the search query text
//string.
q.iProximity := HH_FTS_DEFAULT_PROXIMITY;//Word
//proximity
q.fStemmedSearch := FALSE; //TRUE for Stemmed
//Search only.
q.fTitleOnly := FALSE; // TRUE for Title search
//only.
q.fExecute := TRUE; // TRUE to initiate the
//search.
q.pszWindow := nil; //Window to display in
//HtmlHelp(0,
//PChar(mHelpFile),
//HH_DISPLAY_SEARCH,
//DWORD(@q));
end;
The above opens help at the search tab and performs a search on the word
‘test’. The iProximity member must be always set to
HH_FTS_DEFAULT_PROXIMITY.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 34
To simply open at the search tab with no search, clear the following three
fields.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 35
Keyword searches
Both HH_ALINK_LOOKUP and HH_KEYWORD_LOOKUP commands use
the THHAKLink structure to search for ALinks and KLinks respectively. If
the search for a keyword is successful, a dialog appears listing the matching
ALinks or KLinks topics. If only one result is found the dialog is skipped
and the topic is immediately loaded. The following code searches for the
keyword ‘Agent’.
There are a few variations to the call we can make. We can get the API to
display a message box when the search fails:
s1 := KeyWord Search;
s2 := Keyword search failed. + #13#10 + Retype and try
again!;
link.pszMsgTitle := PChar(s1);
link.pszMsgText := PChar(s2);
link.fIndexOnFail := FALSE; // Set FALSE to see the
// message
We can get the API to display a URL when the search fails, say a topic in a
CHM. We can also specify the window type to use.
s1 := htmlfiles\FileNotFound.htm;
s2 := window2;
link.pszUrl := PChar(s1); // URL to jump to if keyword
// not found
link.pszWindow := PChar(s2); // Window to display URL in
link.fIndexOnFail := FALSE; // Set to FALSE to see the
// message
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 36
fn := mHelpFile + >main;
topic := mHelpFile + ::/mytopic.htm;
HtmlHelp(0, PChar(fn), HH_SYNC, DWord(PChar(topic)));
HH_GET_WIN_HANDLE
This command will retrieve the handle of a help window. The call returns
zero if the help window has not yet been created. Otherwise it returns the
handle of the requested window. The call requires the path to the CHM
help file and the name of the window type to find (in this case “main”).
HH_GET_WIN_TYPE
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 37
begin
fn := mHelpFile + >main;
h := HtmlHelp(0, PChar(fn), HH_GET_WIN_TYPE, DWORD(@pwintype));
if h = 0 then
ShowMessage(** Window help.chm>main not opened.)
else if h = -1 then
ShowMessage(** Window help.chm>main has not been defined.)
else if h < 0 then
ShowMessage(** Call failed. + GetLastHHError)
else
with pwintype^ do
begin
writeln(f, pszType, pszType); //IN/OUT: Name of
//window
writeln(f, inttostr(fsWinProperties); //IN/OUT:
//Properties
...
HH_SET_WIN_TYPE
The following code creates a window type called ‘mywindow’ for the CHM
file specified. It has no toolbar or navigational panes. Some window type
items cannot be modified, or will not change until the window is closed and
reopened.
Looking at the code below we have filled the THHWinType structure with
zeros, then filled in the record members. We set pszType to be the name of
the window type. This is the window type name we will use in future calls
to the HH API. Set pszCaption to specify what text to display in the help
window’s title bar. fsValidMembers tells the API which members we are
setting. In this example we are only setting three members,
fsWinProperties, rcWindowPos and nShowState.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 38
All windows types in HTML Help 1.0 and 1.1 were always global for a
process. Different processes cannot access each other ’s window type infor-
mation. HTML Help 1.2 changed the rules and attached each window type
to a specific chm file unless it was created as a global window type.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 39
Some items need further explanation. Also check the hh.pas comments for
further detail.
Structure Description
fUniCodeStrings IN. This setting is independent of whether you are calling the API
using HtmlHelpA or HtmlHelpW. If set TRUE the API treats all
strings as Unicode.
fsValidMembers IN. This bit field allows you specify which members you want to
set. For example HHWIN_PARAM_PROPERTIES bit means that the
fsWinProperties item is being set. Check out the comments in the
header file to see the relationship between bit flags and structure
members.
pszCaption IN/OUT. The caption text for the window title bar.
nShowState IN: Show state. Example: SW_SHOW. See the Win32 API help.
Structure Description
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 40
Structure Description
fNotExpanded IN: Hide or Show the navigation pane, OUT: current state.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 41
There are several ways we can get the application and help to work more
closely together.
u ActiveX
The most powerful way to extend help is to write ActiveX. Using script
the HTML document can call any Delphi ActiveX function you care to
write. The function may do some action, return a value, display a dialog
or create a new HTML topic on the fly. Note that in WinHelp we
created DLLs to extend help. In HTML Help we must create ActiveX. A
simple example follows later.
HTML Help Workshop gives you the ability to run external executables
from a help topic. See Workshop help for more information.
u Notification Messages
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 42
We covered this above. It’s a good way for the application to see what
is happening to a help window. Note that if you use Notification
messages then you will receive a pointer to the THHWinType data
structure when the HHN_TRACK notification message arrives.
u Training Cards
A very useful but little used command. Basically, in Workshop you setup
a help topic to send a WM_TCARD message to the application via some
action in a help topic. You can send a string or integer with the message.
The application receives the message and responds in whatever way you
want. An example follows.
Merge the help right into the application. This is exactly what HTML
Help window does. The Topic pane is simply a TWebBrowser control.
You get events from the browser and more or less total control over its
contents. More on this later.
You can embed the entire help window if you want. An example of this
is seen in HH Workshop. Click the help toolbar button and Workshop
embeds a HH window, which has just the contents and toolbar panes.
An example follows.
Message Description
HHN_NAVCOMPLETE Sent when the user navigates to a new topic. The URL is sent with
the message.
HHN_TRACK Sent when a user clicks a button on the toolbar. The message
contains the current topic URL, button ID and a pointer to the
windows THHWinType data structure. The message is sent just
before the action is taken.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 43
Message Description
idNotify Set this to some unique ID. When the application receives a
notification message it will know which help window sent the
message by this ID.
Once you have set up your data structure, call HtmlHelp() using the
HH_SET_WIN_TYPE command to create the window type. See the section
on HH_SET_WIN_TYPE above for more information.
When you open your help window, you must specify the handle of the
window that will receive the WM_NOTIFY messages.
fn := c:\test\help.chm::/Agent\Genie.htm>mywin;
HtmlHelp(Self.handle, PChar(fn), HH_DISPLAY_TOPIC, 0);
To see notification messages in action, see the Notify page tab of the Ex-
ample 4 sample application. Check out the code under the “Start Notify
Test” button.
type
TForm1 = class(TForm)
...
private
procedure WMNotify(var Message: TWMNotify); message
WM_NOTIFY;
...
end;
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 44
HHN_WINDOW_CREATE:
begin
phhn := PHHNNotify(NMHdr);
s := phhn^.pszUrl;
Memo.Lines.Add(HHN_WINDOW_CREATE - pszUrl =
%s,[s]));
end;
end; //case
end; //if
end; //with
The above example simply logs the notification events as they come in.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 45
Example 4 on the sample code CD shows you training cards in action. Open
the “Other” menu to run the training card example.
1. Open HTML Help Workshop. Select File > Open from the main menu and
open the document that will send the WM_TCARD message. Position the
cursor at the code insertion point. (You can place the insertion point
anywhere in the document, though obviously you must take care not to
insert code into the middle of another code block.)
2. Click the wizard’s hat in the toolbar
toolbar,, or choose Tags > HTML Help Control
from the main menu. When the HH ActiveX Control Commands dialog
appears, select the Training Card command. Hhctrl is always the default
prefix, but make sure you enter a unique ID for the control. If the docu-
ment contains other embedded commands make sure that they all have
unique IDs. Click Next
Next..
3. Select Hidden if you want to call the command using script (e.g. from a
hyperlink). Ignore the menus and popup settings. These are a cosmetic
bug in workshop 1.2 and have nothing to do with training cards. Click
Next
Next.. Fill in the button information if you selected the button option and
click Next
Next..
4. Fill in the WP aram and LP
WParam aram values. The LP
LParam aram can be a string or an
LParam
integer
integer.. Click Finished
Finished..
The object code is inserted into your document and looks something like
the following:
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 46
This won’t work. You will need to edit the code so that the two item values
are combined into one. This is a known bug with HH 1.2. The code should
look like the following.
Using Script
The above code does not display a visible button so we need to call it using
some script. To do this we need to use the HTML Help Click method. Here
is an example of a hyperlink calling the object code. Notice we gave the
object above an id=tcardtest. If we set id=fred then the code below would
need to say “fred.click()”.
The Workshop online help contains some inaccuracies. They mention using
the TCard(wparam,lparam) method. Unfortunately this stopped working in
HTML Help 1.1b. The only way to call the code via script is using the Click
method. This means you need a separate object code block for each training
card call you want to make.
Responding to a WM_TCARD
We now have our document with a link that will send a WM_TCARD card
message to our application. It’s important to note that this won’t work
unless the application opens the help topic using the application’s window
handle. Example: HtmlHelp(self.handle, chm, command,0); The HH API
only sends the WM_TCARD message to the application that owns the help
window.
To receive the WM_TCARD messages, insert the following code into your
form class.
Uses
..., Messages;
type
TForm1 = class(TForm)
...
private
procedure WMTCard(var Message: TMessage); message WM_TCARD;
end;
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 47
In this example the LParam sent with the message is a string. Notice that
we have used the window API function IsBadStringPrt() to ensure that we
have a string not an integer.
There were a few changes between IE3 and IE4. The IE4/5 shdocvw.dll
supplies two controls, TWebBrowser and TWebBrowser_V1. If you are
supporting IE3 users or are still using Delphi 3 then you need to use the
older version called TWebBrowser_V1. TWebBrowser_V1 has a few less
properties, methods and events than the newer TWebBrowser.
Can I install just the shdocvw.dll? MS do not allow you to install just the
TWebBrowser control. See the “HTML Help Installation” section of the
book for information on installing the Internet Explorer.
Example 5
You will find Delphi sample code that demonstrates using the
TWebBrowser control in the Example 5 folder of the CD. The example
comes in the form of a simple web browser so as to best demonstrate all the
main browser properties, methods and events.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 48
1. From the Delphi IDE main menu, select Component > Import ActiveX
Control
Control.
2. When the Import ActiveX dialog appears, select “Microsoft Internet Con-
trols”. It has DLL name %winsysdir%\SHDOCVW
%winsysdir%\SHDOCVW.DLL .DLL
.DLL.. Accept the defaults,
and click the Install button.
Notice the two class names. When you click install, two components
will appear in the ActiveX tab of the Delphi component palette,
WebBrowser_V1 and WebBrowser. Use the older WebBrowser_V1 if you
use Delphi 3 or for IE3 support.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 49
You are now ready to use the WebBrowser control. As with any of the
Delphi visual components you simply drop the component on the form and
use it. However there is one word of caution.
Warning: Do not drop the control onto a bare form otherwise resizing could cause access
violations. Instead, first drop on TPanel control onto the form and then drop the WebBrowser onto
the TPanel control. Even then you may still get a few access violations if you run your application
from the Delphi IDE and attempt to resize the window.
http://msdn.microsoft.com/workshop/browser/default.asp
http://msdn.microsoft.com/workshop/browser/webbrowser/WebBrowser.asp
Not all properties and methods can be used with WebBrowser control. For
example, the property TheaterMode cannot be used. The online help says,
“The WebBrowser object ignores the TheaterMode property.” So read the
online help carefully.
To open a HTML file in the control, use the Navigate2() method. You can
specify local files by using the “file://” prefix. You can open HTML file
topics from within compressed help files by using the “ms-
its:chmFilePath::TopicPath” type format. In fact you can open any file that
you can normally open with Internet Explorer.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 50
For example, the following document link when clicked will fire the
BeforeNavigate2 event.
In the event code, you would check if the URL parameter contains the text
_MY_COMMAND_. If it does, cancel the navigation and perform some
action. See Example 5 for more.
Some HTML Help commands that are embedded into a HTML file only
work when compiled to a CHM help file and displayed in a HH window.
These include - Alink, Close, KLink, Shortcut, TCard and WinHelp com-
mands. If you need these commands then you should embed an entire HH
window into your application. The following commands do work in
uncompressed form - Contents, HH Version, Index, Related Topics and the
Splash command.
Example 6
You will find Delphi sample code that demonstrates embedding a HTML
Help window in an application in the Example 6 folder of the CD.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 51
This sets the HH window to the same size and position as the owner
window.
Procedure TForm1.ShowEmbeddedHelp;
var wintypedef: THHWinType; fn, winName: String;
begin
winName := embedwindow;
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 52
The next part is important. When we open a help topic, we must specify
the window type we just defined called “embedwindow”. We must also
specify the owner as being the TPanel named Helppanel1. Now the
rcWindowPos above makes more sense.
fn := c:\test\help.chm::/Agent/Genie.htm>embedwindow;
mHelpWinHandle := HtmlHelp(HelpPanel1.Handle, PChar(fn),
HH_DISPLAY_TOPIC, 0);
The only other segment of code of interest is the TPanel OnResize event.
When we open the help window we keep the help window handle returned
to us via the HtmlHelp() API call. Using the handle we are able to resize the
help window to match the size of the owner window which is the TPanel
called HelpPanel1. The SWP_NOMOVE flag has been used so that the x and
y coordinates are ignored, since these were set to 0,0 when the help win-
dow was created.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 53
If you are having problems with your in-process ActiveX try writing out-of-
process server (EXE) instead. Out-of-process servers by their definition run
outside the applications address space.
Example 7
To register the server, simple run the helpx.exe. Once registered, you should
open the example help file help.chm and navigate to the ActiveX Test. Click
on the “Click me!” hyper-link and some JScript code is executed that will
create an instance of the helpx.helpExtend object and execute a server
function.
<html>
<head>
<title>Automation Test</title>
</head>
<body bgcolor=#FFFFFF>
<script language=JavaScript>
function DoTest() {
var xx = new ActiveXObject(Helpx.HelpExtend);
xx.testmsg(This message box is displayed by the Automation
server helpx.exe);
}
</script>
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 54
</body>
</html>
The above script can also be written in VBScript using the CreateObject()
function—e.g. xx = CreateObject(“helpx.HelpExtend”).
1. Open Delphi and create a new application. In this case the example
application is called helpx.dpr with a main form called unit1.pas
unit1.pas..
If you wanted to create an in-process server (DLL) instead, then you
would select F ile > New
New, select the ActiveX page tab, then the A ctiveX
Librar y
Library option.
2. Next we must add the automation server component. From the main menu
click File > New
New.. Select the ActiveX page tab, select Automation Object
Object,,
and then click OK
OK..
3. The Automation Object Wizard dialog will appear next. Enter a class name,
select Instancing as Multiple Instance and Thread Model as Apartment.
The class name combined with the exe name is used to identify the object
exename.classname. In our example 7, the class name is helpextend,
which makes the object name used in script helpx.helpextend.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 55
Click OK
OK, and Delphi will create a definition unit for the current project
that will contain the code for the Automation object. It also adds a type
library to the project. In the test application, the definition unit is called
unit2.pas and the type library is called helpx_TLB.pas
helpx_TLB.pas.
4. Next we need to create automation server properties and methods. TTo o do
this, open helpx_TLB.pas
helpx_TLB.pas,, and press F12 to open the TType
ype Library editor
editor..
(Using the editor is the only way you can edit the TLB file.) TTo
o add a
method we simply right-click the IHelpExtend tree item and select New >
Method from the popup menu. Fill in the method name and use the page
tabs on the right to add method parameters and a return value if re-
quired. Make sure you use only OLE safe parameters such as WideString,
Integer
Integer,, and UINT
UINT.. Once you have added a method, the stub will be
written to the definition unit, in this case Unit2.pas.
5. Edit Unit2.pas
Unit2.pas,, and fill in the stub functions. In the example project there
is only one ActiveX function and it simply shows a message box.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 56
Well that’s it. I don’t want to write a Delphi tutorial. If you want to learn
more about Delphi ActiveX you can read the online help or buy yourself one
of the many good Delphi textbooks.
All you need to do is add two registry items. Look at the registry dump
below. The first five entries are created when the activeX control is regis-
tered. It’s the last two entries under the key “Implemented Categories” that
tell Internet Explorer that the control is safe. The key
CLSID\{GUID}\Implemented Categories\{7DD95801-9882-11CF-9FA9-
00AA006C42C4} marks the control as being safe for scripting while the key
CLSID\{GUID}\Implemented Categories\{7DD95802-9882-11CF-9FA9-
00AA006C42C4} marks the control as being safe to initialize. Also Delphi 3
users will also need to add the line “ThreadingModel”=”Apartment” as this
was not implemented in Delphi 3.
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-444553540000}]
@=HelpX Object
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\InprocServer32]
@=C:\\PROJ\\_OTHER_\\HELPX\\BIN\\MMHELPX.DLL
ThreadingModel=Apartment
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\ProgID]
@=mmHelpX.HelpX
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\Version]
@=1.1"
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\TypeLib]
@={39B0C227-918C-11D2-96E3-444553540000}
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\Implemented Categories\{7DD95801-9882-11CF-9FA9-
00AA006C42C4}]
@=
[HKEY_CLASSES_ROOT\CLSID\{39B0C22C-918C-11D2-96E3-
444553540000}\Implemented Categories\{7DD95802-9882-11CF-9FA9-
00AA006C42C4}]
@=
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 57
Example 7 has a function in Unit2.pas that, given a class ID, will add these
two keys for you.
http://keyworks.net/keyhelp.htm
The help compiler creates the first several files in the CHM. These files
contain special information such as your window definitions, context help
mappings, full text search info and so on. These files all have paths that
start with the character “#” or “$”. Following these files are the help topics
and image files.
CHM files are stored in IStorage format. Ralph Walden has published a
C++ header file CITS.H on his web site that provides access to the IStorage
file structures. Example 10 provides a port of this file called HH_ITS.pas.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 58
I hope this chapter has provided some insight into how you can go about
programming HTML Help under Delphi. I will be happy to try and answer
questions if you have any. You can email me at [email protected]. n
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 59
Appendix 1
The following table shows the HTML Help commands available.
HH_DISPLAY_TEXT_POPUP Display text in a in a popup window. The last two commands are
HH_TP_HELP_CONTEXTMENU identical in behavior. HTML Help 1.x popups can only display
HH_TP_HELP_WM_HELP plain text at the moment.
HH_ALINK_LOOKUP Display a help topic using keyword lookup. HTML Help 1.x
HH_KEYWORD_LOOKUP supports ALinks and KLinks.
HH_INITIALIZE These functions are used to run a help window in the same
HH_PRETRANSLATEMESSAGE thread as the application. Useful for developers wanting a very
HH_UNINITIALIZE tight binding between application and help window. Example:
Embedded help systems.
The next table lists the WinHelp commands and how they relate to the
HTML Help.
HELP_COMMAND There are no help macros in HTML Help. Instead we use Script,
Java applets and ActiveX to extend help topics.
HELP_CONTENTS In HTML Help the contents and index are built into the help
HELP_INDEX window. The closest commands are HH_DISPLAY_TOC and
HELP_FINDER HH_DISPLAY_INDEX. A HH_FINDER is defined but this simply does
the same as the HH_DISPLAY_TOPIC command.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.
Delphi Programming for the HTML Help API n Page 60
HELP_QUIT HTML Help does not require you to terminate the help session.
Although you should call HH_CLOSE_ALL before you shut down
the application or risk access violations.
Copyright 2001, Help Think Press/Work Write, Inc. All rights reserved.