在Windows中各种应用程序使用期间,我们可以通过按下F1键快速进入相关主题的帮助信息,从而获取帮助。在用户自己编写的Delphi应用程序里,对于chm格式的帮助文件,我们也可以编写自己的联机帮助。此功能主要是通过引用HHctrl.ocx文件的函数HtmlHelpA实现。
在阅读下面文字之前,请先确保自己会用MicroSoft的帮助文件制作工具HelpWorkshop制作chm格式帮助,如果不会,请参阅网上王寒晖写的文章《跟我学做chm帮助文件》。
以下是用Delphi实现联机帮助的过程:
1. 列出程序里需要用到的联机帮助主题,并分配主题号,以及对该主题进行解释的html文件;
如:控件Button1的帮助主题是ID_Button1_Help,主题号是10,帮助文件是sample1.htm。
对于需要联机帮助的所有控件或文字,按照Button1的方式依次列出帮助主题、主题号和帮助文件。
2. 在chm帮助文件所在目录下新建两个文件,Library.h和Library.txt;
打开Library.h进行编辑,按如下模式输入步骤1中列出的帮助主题,每行写一个帮助主题。
如:#DEFINE ID_Button1_Help 10
#DEFINE ID_Button2_Help 11;
打开Library.txt进行编辑,按如下模式输入步骤1中列出的帮助主题弹出文字。
如:.topic ID_Button1_Help
这是Button1的联机帮助!
.topic ID_Button2_Help
这是Button2的联机帮助!
3. 打开chm帮助文件的工程文件,进入Project(工程)页面,用鼠标左键单击左侧由上至下第四个按钮HtmlHelp API information(Html帮助API信息)。
1) 在弹出的HtmlHelp API information窗口中选择Alias(别名)页面,用鼠标左键单击右侧由上至下第一个按钮Add…(添加…),在弹出的Alias对话框中第一个编辑框内输入ID_Button1_Help,第二个下拉列表框内选择sample.htm,点击OK按钮插入该Alias(别名),重复此过程直至步骤 1中所有的主题均在此处列出,如下图所示。
2) 在HtmlHelp API information窗口中选择Map(映射)页面,用鼠标左键单击右侧由上至下第一个按钮Header File…(头文件…),在弹出的Include File(包含文件)对话框中,单击Browse…(浏览…)按钮,在弹出的打开…对话框中找到Library.h文件,单击打开返回Include File(包含文件)对话框,单击OK按钮返回Map(映射)页面,如下图所示。
3) 在HtmlHelp API information窗口中选择Text Pop-ups(弹出文字)页面,用鼠标左键单击右侧由上至下第一个按钮Header File…(头文件…),在弹出的Include File(包含文件)对话框中按步骤2)中方式指定Library.h文件;用鼠标左键单击右侧由上至下第二个按钮Text File…(文本文件…),在弹出的Include File(包含文件)对话框中按步骤2)中方式指定Library.txt文件,单击OK按钮返回Text Pop-ups(弹出文字)页面,如下图所示。
4. 在HtmlHelp API information(Html帮助API信息),点击确定按钮返回Project(工程)页面,选择File->Compile重新编译该帮助文件。
到现在为止,我们已经准备好了一个可以实现联机帮助的chm文件了,下面我们就可以编写delphi程序实现联机帮助功能了,过程如下。
1. 新建一个工程Project1,新建Unit,将该Unit保存为HtmlHelp_Declaration,打开HtmlHelp_Declaration,在此声明HtmlHelp函数及相关常量、类型。该文件内容如下所示:
unit HTMLHELP_Declaration;
interface
uses
Windows;
const
HH_HELP_CONTEXT = $0F;
HH_CLOSE_ALL = $12;
HH_INITIALIZE = $1C;
HH_UNINITIALIZE = $1D;
type
DWORD_PTR = ^DWORD;
function HtmlHelp( hwndCaller:HWND; strFile:String; uCommand:UINT; dwData:DWORD_PTR ):HWND; //实现启动联机帮助的函数
procedure CloseHtmlHelpSystem; //实现关闭帮助窗口的过程
implementation
uses
SysUtils;
const
HHControlInstance:THandle=0;
dwCookie :DWORD = 0;
var
HtmlHelpA:function ( hwndCaller:HWND; pszFile:PChar ; uCommand:UINT;
dwData:DWORD_PTR ):HWND;stdcall;
//引用HHCTRL.OCX中的启动帮助函数
(* 函数实现 *)
function HtmlHelp( hwndCaller:HWND; strFile:String; uCommand:UINT; dwData:DWORD_PTR ):HWND;
(*函数的实现过程:如果是第一次启动联机帮助,则载入库HHCTRL.OCX,并将启动帮助函数的地址赋给HtmlHelpA,然后通过传递参数 HH_INITIALIZE调用之来初始化联机帮助,最后通过调用该函数并传递适当的参数来实现联机帮助;如果不是第一次启动联机帮助,则直接调用该函数并传递适当的参数即可。*)
var
OcxFileName:String;
p:PChar;
begin
if HHControlInstance=0 then
begin
OcxFileName := StringOfChar( ' ', 256);
p := PChar( OcxFilename );
GetSystemDirectory(p,255);
StrCat(p,'\HHCTRL.OCX');
HHControlInstance := LoadLibrary( P );
if HHControlInstance = 0 then
raise exception.Create('HHCtrl.OCX not installed!'#13' HTMLHELP cannot displayed!');
@HtmlHelpA := GetProcAddress( HHControlInstance, 'HtmlHelpA');
if @HtmlHelpA = nil then
raise exception.Create('Function HTMLHELP cannot loaded!');
HtmlHelpA( 0, nil, HH_INITIALIZE, (@dwCookie));
end;
result := HtmlHelpA( hwndCaller, PChar( strFile ), uCommand, dwData );
end;
procedure CloseHtmlHelpSystem;
(*函数的实现过程:调用HtmlHelpA函数并传递参数HH_UNINITIALIZE来反初始化联机帮助,并释放前面载入的库HHCTRL.OCX。*)
begin
if HHControlInstance<>0 then
begin
HtmlHelpA( 0, nil, HH_UNINITIALIZE, DWORD_PTR(dwCookie));
FreeLibrary(HHControlInstance);
end;
end;
end.
2. 在Unit1保留字implementation后面添加上对HtmlHelp_Declaration的引用声明,如下所示:
uses
HTMLHELP_Declaration;
3. 修改Unit1窗体的HelpFile属性为上面重新编译过的chm文件,要写明路径及文件名,如帮助文件与工程文件在同一路径下,只需指定文件名即可。
4. 在Unit1窗体的事件onclose函数中添加如下代码:
HtmlHelp( 0,'',HH_CLOSE_ALL,nil);
CloseHtmlHelpSystem;
5. 在Unit1窗体的事件onhelp函数中添加如下代码:
Htmlhelp(Handle, HelpFile, HH_HELP_CONTEXT,
DWORD_PTR(ActiveControl.HelpContext));
CallHelp := False;
6. 在Unit1窗体中添加一个Button控件,设置该控件的HelpContext属性值为10。
编译运行Project1,在显示的窗口中利用Tab键使当前焦点为Button1,此时按下F1键,对Button1的联机帮助是不是出现了?对了,制作联机帮助就是这么简单!
以上程序在WinXP + Delphi5上调试通过,本人有上述程序的完整源码,有兴趣的同志可以email我(tr_xu@sina.com)索取。