Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Как использовать chm-файлы в своем проекте?

01.01.2007

Всё, что вам надо сделать, это сохранить ниже приведенный модуль на диске и добавить его в Uses вашего проекта. После этого Вы сможете использовать CHM файлы точно так же как и обычные HLP файлы.

unit StoHtmlHelp;
////////////////////////////////////////////////////////////////
// Implementation of context sensitive HTML help (.chm) for Delphi.
//
// Version:       1.2
// Author:        Martin Stoeckli
// Homepage:      www.martinstoeckli.ch/delphi
// Copyright(c):  Martin Stoeckli 2002
//
// Restrictions:  - Works only under the Windows platform.
//                - Is written for Delphi v7, should work from v6 up.
//
// Description
// ***********
// This unit enables you to call ".chm" files from your Delphi projects.
// You can use the normal Delphi VCL framework, write your projects the
// same way, as you would using normal ".hlp" files.
//
// Installation
// ************
// Simply add this unit to your project, that's all.
//
// If your help project contains files with the extension ".html"
// instead of ".htm", then you can either pass the filename with the
// extension to Application.HelpJump(), or you can set the property
// "HtmlExt" of the global object in this unit.
//   StoHelpViewer.HtmlExt := '.html';
//
// Examples
// ********
//   // assign a helpfile, you could also select the helpfile at the
//   // options dialog "Project/Options.../Application".
//   Application.HelpFile := 'C:\MyHelp.chm';
//   ...
//   // shows the contents of the helpfile
//   Application.HelpCommand(HELP_CONTENTS, 0);
//   // or
//   Application.HelpSystem.ShowTableOfContents;
//   ...
//   // opens the context sensitive help with a numerical id.
//   // you could do the same by setting the "HelpContext"
//   // property of a component and pressing the F1 key.
//   Application.HelpContext(1000);
//   // or with a string constant
//   Application.HelpJump('welcome');
//   ...
//   // opens the help index with a keyword.
//   // you could do the same by setting the "HelpKeyword"
//   // property of a component and pressing the F1 key.
//   Application.HelpKeyword('how to do');
//
 
interface
uses
Classes, Windows, HelpIntfs;
 
type
 
THtmlHelpA = function(hwndCaller: HWND; pszFile: LPCSTR; uCommand: UINT; dwData: DWORD): HWND; stdcall;
 
 
TStoHtmlHelpViewer = class(TInterfacedObject, ICustomHelpViewer,
                             
IExtendedHelpViewer, IHelpSelector)
 
private
   
FViewerID: Integer;
   
FViewerName: String;
   
FHtmlHelpFunction: THtmlHelpA;
 
protected
   
FHHCtrlHandle: THandle;
   
FHelpManager: IHelpManager;
   
FHtmlExt: String;
   
function  GetHelpFileName: String;
   
function  IsChmFile(const FileName: String): Boolean;
    procedure
InternalShutdown;
    procedure
CallHtmlHelp(const HelpFile: String; uCommand: UINT; dwData: DWORD);
   
// ICustomHelpViewer
   
function  GetViewerName: String;
   
function  UnderstandsKeyword(const HelpString: String): Integer;
   
function  GetHelpStrings(const HelpString: String): TStringList;
   
function  CanShowTableOfContents: Boolean;
    procedure
ShowTableOfContents;
    procedure
ShowHelp(const HelpString: String);
    procedure
NotifyID(const ViewerID: Integer);
    procedure
SoftShutDown;
    procedure
ShutDown;
   
// IExtendedHelpViewer
   
function  UnderstandsTopic(const Topic: String): Boolean;
    procedure
DisplayTopic(const Topic: String);
   
function  UnderstandsContext(const ContextID: Integer;
     
const HelpFileName: String): Boolean;
    procedure
DisplayHelpByContext(const ContextID: Integer;
     
const HelpFileName: String);
   
// IHelpSelector
   
function  SelectKeyword(Keywords: TStrings) : Integer;
   
function  TableOfContents(Contents: TStrings): Integer;
 
public
   
constructor Create; virtual;
    destructor
Destroy; override;
    property
HtmlExt: String read FHtmlExt write FHtmlExt;
 
end;
 
var
 
StoHelpViewer: TStoHtmlHelpViewer;
 
implementation
uses
Forms, SysUtils, WinHelpViewer;
 
const
 
// imported from HTML Help Workshop
  HH_DISPLAY_TOPIC        
= $0000;
  HH_HELP_FINDER          
= $0000; // WinHelp equivalent
  HH_DISPLAY_TOC          
= $0001;
  HH_DISPLAY_INDEX        
= $0002;
  HH_DISPLAY_SEARCH      
= $0003;
  HH_KEYWORD_LOOKUP      
= $000D;
  HH_DISPLAY_TEXT_POPUP  
= $000E; // display string resource id or text in a popup window
  HH_HELP_CONTEXT        
= $000F; // display mapped numeric value in dwData
  HH_TP_HELP_CONTEXTMENU  
= $0010; // text popup help, same as WinHelp HELP_CONTEXTMENU
  HH_TP_HELP_WM_HELP      
= $0011; // text popup help, same as WinHelp HELP_WM_HELP
  HH_CLOSE_ALL            
= $0012; // close all windows opened directly or indirectly by the caller
  HH_ALINK_LOOKUP        
= $0013; // ALink version of HH_KEYWORD_LOOKUP
  HH_GET_LAST_ERROR      
= $0014; // not currently implemented // See HHERROR.h
 
type
 
TStoWinHelpTester = class(TInterfacedObject, IWinHelpTester)
 
protected
   
// IWinHelpTester
   
function CanShowALink(const ALink, FileName: String): Boolean;
   
function CanShowTopic(const Topic, FileName: String): Boolean;
   
function CanShowContext(const Context: Integer;
                           
const FileName: String): Boolean;
   
function GetHelpStrings(const ALink: String): TStringList;
   
function GetHelpPath : String;
   
function GetDefaultHelpFile: String;
   
function IsHlpFile(const FileName: String): Boolean;
 
end;
 
////////////////////////////////////////////////////////////////
// like "Application.ExeName", but in a DLL you get the name of
// the DLL instead of the application name
function Sto_GetModuleName: String;
var
  szFileName
: array[0..MAX_PATH] of Char;
begin
 
FillChar(szFileName, SizeOf(szFileName), #0);
 
GetModuleFileName(hInstance, szFileName, MAX_PATH);
 
Result := szFileName;
end;
 
////////////////////////////////////////////////////////////////
{ TStoHtmlHelpViewer }
////////////////////////////////////////////////////////////////
 
procedure
TStoHtmlHelpViewer.CallHtmlHelp(const HelpFile: String; uCommand: UINT; dwData: DWORD);
begin
 
if Assigned(FHtmlHelpFunction) then
 
begin
   
case uCommand of
    HH_CLOSE_ALL
: FHtmlHelpFunction(0, nil, uCommand, dwData); // special parameters
    HH_GET_LAST_ERROR
: ; // ignore
   
else
     
FHtmlHelpFunction(FHelpManager.GetHandle, PChar(HelpFile), uCommand, dwData);
   
end;
 
end;
end;
 
function TStoHtmlHelpViewer.CanShowTableOfContents: Boolean;
begin
 
Result := True;
end;
 
constructor TStoHtmlHelpViewer.Create;
begin
  inherited
Create;
 
FViewerName := 'StoHtmlHelp';
 
FHtmlExt := '.htm';
 
// load dll
 
FHHCtrlHandle := LoadLibrary('HHCtrl.ocx');
 
if (FHHCtrlHandle <> 0) then
   
FHtmlHelpFunction := GetProcAddress(FHHCtrlHandle, 'HtmlHelpA');
end;
 
destructor
TStoHtmlHelpViewer.Destroy;
begin
 
StoHelpViewer := nil;
 
// free dll
 
FHtmlHelpFunction := nil;
 
if (FHHCtrlHandle <> 0) then
   
FreeLibrary(FHHCtrlHandle);
  inherited
Destroy;
end;
 
procedure
TStoHtmlHelpViewer.DisplayHelpByContext(const ContextID: Integer;
 
const HelpFileName: String);
var
  sHelpFile
: String;
begin
  sHelpFile
:= GetHelpFileName;
 
if IsChmFile(sHelpFile) then
   
CallHtmlHelp(sHelpFile, HH_HELP_CONTEXT, ContextID);
end;
 
procedure
TStoHtmlHelpViewer.DisplayTopic(const Topic: String);
var
  sHelpFile
: String;
  sTopic
: String;
  sFileExt
: String;
begin
  sHelpFile
:= GetHelpFileName;
 
if IsChmFile(sHelpFile) then
 
begin
   
// prepare topicname as a html page
    sTopic
:= Topic;
    sFileExt
:= LowerCase(ExtractFileExt(sTopic));
   
if (sFileExt <> '.htm') and (sFileExt <> '.html') then
      sTopic
:= sTopic + FHtmlExt;
   
CallHtmlHelp(sHelpFile + '::/' + sTopic, HH_DISPLAY_TOPIC, 0);
 
end;
end;
 
function TStoHtmlHelpViewer.GetHelpFileName: String;
var
  sPath
: String;
begin
 
Result := '';
 
// ask for the helpfile name
 
if Assigned(FHelpManager) then
   
Result := FHelpManager.GetHelpFile;
 
if (Result = '') then
   
Result := Application.CurrentHelpFile;
 
// if no path is specified, then add the application path
 
// (otherwise the file won't be found if the current directory is wrong).
 
if (Result <> '') then
 
begin
    sPath
:= ExtractFilePath(Result);
   
if (sPath = '') then
     
Result := ExtractFilePath(Sto_GetModuleName) + Result;
 
end;
end;
 
function TStoHtmlHelpViewer.GetHelpStrings(const HelpString: String): TStringList;
begin
 
// create a tagged keyword
 
Result := TStringList.Create;
 
Result.Add(Format('%s: %s', [FViewerName, HelpString]));
end;
 
function TStoHtmlHelpViewer.GetViewerName: String;
begin
 
Result := FViewerName;
end;
 
procedure
TStoHtmlHelpViewer.InternalShutdown;
begin
 
if Assigned(FHelpManager) then
 
begin
   
FHelpManager.Release(FViewerID);
   
FHelpManager := nil;
 
end;
end;
 
function TStoHtmlHelpViewer.IsChmFile(const FileName: String): Boolean;
var
  iPos
: Integer;
  sFileExt
: String;
begin
 
// find extension
  iPos
:= LastDelimiter('.', FileName);
 
if (iPos > 0) then
 
begin
    sFileExt
:= Copy(FileName, iPos, Length(FileName));
   
Result := CompareText(sFileExt, '.chm') = 0;
 
end
 
else
   
Result := False;
end;
 
procedure
TStoHtmlHelpViewer.NotifyID(const ViewerID: Integer);
begin
 
FViewerID := ViewerID;
end;
 
function TStoHtmlHelpViewer.SelectKeyword(Keywords: TStrings): Integer;
var
  i
: Integer;
  sViewerName
: String;
begin
 
Result := 0;
  i
:= 0;
 
// find first tagged line (see GetHelpStrings)
 
while (Result = 0) and (i <= Keywords.Count - 1) do
 
begin
    sViewerName
:= Keywords.Strings[i];
   
Delete(sViewerName, Pos(':', sViewerName), Length(sViewerName));
   
if (FViewerName = sViewerName) then
     
Result := i
   
else
     
Inc(i);
 
end;
end;
 
procedure
TStoHtmlHelpViewer.ShowHelp(const HelpString: String);
var
  sHelpFile
: String;
  sHelpString
: String;
begin
  sHelpFile
:= GetHelpFileName;
 
if IsChmFile(sHelpFile) then
 
begin
   
// remove the tag if necessary (see GetHelpStrings)
    sHelpString
:= HelpString;
   
Delete(sHelpString, 1, Pos(':', sHelpString));
    sHelpString
:= Trim(sHelpString);
   
CallHtmlHelp(sHelpFile, HH_DISPLAY_INDEX, DWORD(Pchar(sHelpString)));
 
end;
end;
 
procedure
TStoHtmlHelpViewer.ShowTableOfContents;
var
  sHelpFile
: String;
begin
  sHelpFile
:= GetHelpFileName;
 
if IsChmFile(sHelpFile) then
   
CallHtmlHelp(sHelpFile, HH_DISPLAY_TOC, 0);
end;
 
procedure
TStoHtmlHelpViewer.ShutDown;
begin
 
SoftShutDown;
 
if Assigned(FHelpManager) then
   
FHelpManager := nil;
end;
 
procedure
TStoHtmlHelpViewer.SoftShutDown;
begin
 
CallHtmlHelp('', HH_CLOSE_ALL, 0);
end;
 
function TStoHtmlHelpViewer.TableOfContents(Contents: TStrings): Integer;
begin
 
// find line with viewer name
 
Result := Contents.IndexOf(FViewerName);
end;
 
function TStoHtmlHelpViewer.UnderstandsContext(const ContextID: Integer;
 
const HelpFileName: String): Boolean;
begin
 
Result := IsChmFile(HelpFileName);
end;
 
function TStoHtmlHelpViewer.UnderstandsKeyword(const HelpString: String): Integer;
begin
 
if IsChmFile(GetHelpFileName) then
   
Result := 1
 
else
   
Result := 0;
end;
 
function TStoHtmlHelpViewer.UnderstandsTopic(const Topic: String): Boolean;
begin
 
Result := IsChmFile(GetHelpFileName);
end;
 
////////////////////////////////////////////////////////////////
{ TStoWinHelpTester }
//
// delphi will call the WinHelpTester to determine, if the default
// winhelp should handle the requests.
// don't allow anything, because delphi (v7) will create an invalid
// helpfile path, calling GetHelpPath (it puts a pathdelimiter
// before the filename in "TWinHelpViewer.HelpFile").
////////////////////////////////////////////////////////////////
 
function TStoWinHelpTester.CanShowALink(const ALink,
 
FileName: String): Boolean;
begin
 
Result := False;
//  Result := IsHlpFile(FileName);
end;
 
function TStoWinHelpTester.CanShowContext(const Context: Integer;
 
const FileName: String): Boolean;
begin
 
Result := False;
//  Result := IsHlpFile(FileName);
end;
 
function TStoWinHelpTester.CanShowTopic(const Topic,
 
FileName: String): Boolean;
begin
 
Result := False;
//  Result := IsHlpFile(FileName);
end;
 
function TStoWinHelpTester.GetDefaultHelpFile: String;
begin
 
Result := '';
end;
 
function TStoWinHelpTester.GetHelpPath: String;
begin
 
Result := '';
end;
 
function TStoWinHelpTester.GetHelpStrings(
 
const ALink: String): TStringList;
begin
 
// as TWinHelpViewer would do it
 
Result := TStringList.Create;
 
Result.Add(': ' + ALink);
end;
 
function TStoWinHelpTester.IsHlpFile(const FileName: String): Boolean;
var
  iPos
: Integer;
  sFileExt
: String;
begin
 
// file has extension '.hlp' ?
  iPos
:= LastDelimiter('.', FileName);
 
if (iPos > 0) then
 
begin
    sFileExt
:= Copy(FileName, iPos, Length(FileName));
   
Result := CompareText(sFileExt, '.hlp') = 0;
 
end
 
else
   
Result := False;
end;
 
initialization
 
StoHelpViewer := TStoHtmlHelpViewer.Create;
 
RegisterViewer(StoHelpViewer, StoHelpViewer.FHelpManager);
 
Application.HelpSystem.AssignHelpSelector(StoHelpViewer);
 
WinHelpTester := TStoWinHelpTester.Create;
 
finalization
 
// do not free StoHelpViewer, because the object is referenced by the
 
// interface and will be freed automatically by releasing the last reference
 
if Assigned(StoHelpViewer) then
   
StoHelpViewer.InternalShutdown;
end.

Взято с сайта https://www.swissdelphicenter.ch/en/tipsindex.php


unit HtmlHelp; 
 
interface
 
uses
 
Windows, Graphics;
 
const
  HH_DISPLAY_TOPIC  
= $0000;
  HH_DISPLAY_TOC    
= $0001;
  HH_DISPLAY_INDEX  
= $0002;
  HH_DISPLAY_SEARCH
= $0003;
  HH_SET_WIN_TYPE  
= $0004;
  HH_GET_WIN_TYPE  
= $0005;
  HH_GET_WIN_HANDLE
= $0006;
  HH_GET_INFO_TYPES
= $0007;
  HH_SET_INFO_TYPES
= $0008;
  HH_SYNC          
= $0009;
  HH_ADD_NAV_UI    
= $000A;
  HH_ADD_BUTTON    
= $000B;
  HH_GETBROWSER_APP
= $000C;
  HH_KEYWORD_LOOKUP
= $000D;
  HH_DISPLAY_TEXT_POPUP
= $000E;
  HH_HELP_CONTEXT  
= $000F;
 
const
  HHWIN_PROP_ONTOP          
= 2;
  HHWIN_PROP_NOTITLEBAR    
= 4;
  HHWIN_PROP_NODEF_STYLES  
= 8;
  HHWIN_PROP_NODEF_EXSTYLES
= 16;
  HHWIN_PROP_TRI_PANE      
= 32;
  HHWIN_PROP_NOTB_TEXT      
= 64;
  HHWIN_PROP_POST_QUIT      
= 128;
  HHWIN_PROP_AUTO_SYNC      
= 256;
  HHWIN_PROP_TRACKING      
= 512;
  HHWIN_PROP_TAB_SEARCH    
= 1024;
  HHWIN_PROP_TAB_HISTORY    
= 2048;
  HHWIN_PROP_TAB_FAVORITES  
= 4096;
  HHWIN_PROP_CHANGE_TITLE  
= 8192;
  HHWIN_PROP_NAV_ONLY_WIN  
= 16384;
  HHWIN_PROP_NO_TOOLBAR    
= 32768;
 
const
  HHWIN_PARAM_PROPERTIES    
= 2;
  HHWIN_PARAM_STYLES        
= 4;
  HHWIN_PARAM_EXSTYLES      
= 8;
  HHWIN_PARAM_RECT          
= 16;
  HHWIN_PARAM_NAV_WIDTH    
= 32;
  HHWIN_PARAM_SHOWSTATE    
= 64;
  HHWIN_PARAM_INFOTYPES    
= 128;
  HHWIN_PARAM_TB_FLAGS      
= 256;
  HHWIN_PARAM_EXPANSION    
= 512;
  HHWIN_PARAM_TABPOS        
= 1024;
  HHWIN_PARAM_TABORDER      
= 2048;
  HHWIN_PARAM_HISTORY_COUNT
= 4096;
  HHWIN_PARAM_CUR_TAB      
= 8192;
 
const
  HHWIN_BUTTON_EXPAND    
= 2;
  HHWIN_BUTTON_BACK      
= 4;
  HHWIN_BUTTON_FORWARD    
= 8;
  HHWIN_BUTTON_STOP      
= 16;
  HHWIN_BUTTON_REFRESH    
= 32;
  HHWIN_BUTTON_HOME      
= 64;
  HHWIN_BUTTON_BROWSE_FWD
= 128;
  HHWIN_BUTTON_BROWSE_BCK
= 256;
  HHWIN_BUTTON_NOTES      
= 512;
  HHWIN_BUTTON_CONTENTS  
= 1024;
  HHWIN_BUTTON_SYNC      
= 2048;
  HHWIN_BUTTON_OPTIONS    
= 4096;
  HHWIN_BUTTON_PRINT      
= 8192;
  HHWIN_BUTTON_INDEX      
= 16384;
  HHWIN_BUTTON_SEARCH    
= 32768;
  HHWIN_BUTTON_HISTORY    
= 65536;
  HHWIN_BUTTON_FAVORITES  
= 131072;
  HHWIN_BUTTON_JUMP1      
= 262144;
  HHWIN_BUTTON_JUMP2      
= 524288;
  HHWIN_BUTTON_ZOOM      
= HHWIN_Button_Jump2 * 2;
  HHWIN_BUTTON_TOC_NEXT  
= HHWIN_Button_Zoom * 2;
  HHWIN_BUTTON_TOC_PREV  
= HHWIN_Button_Toc_Next * 2;
 
const
  HHWIN_DEF_Buttons
= HHWIN_Button_Expand or HHWIN_Button_Back or
    HHWIN_Button_Options
or HHWIN_Button_Print;
 
const
  IDTB_EXPAND      
= 200;
  IDTB_CONTRACT    
= 201;
  IDTB_STOP        
= 202;
  IDTB_REFRESH    
= 203;
  IDTB_BACK        
= 204;
  IDTB_HOME        
= 205;
  IDTB_SYNC        
= 206;
  IDTB_PRINT      
= 207;
  IDTB_OPTIONS    
= 208;
  IDTB_FORWARD    
= 209;
  IDTB_NOTES      
= 210;
  IDTB_BROWSE_FWD  
= 211;
  IDTB_BROWSE_BACK
= 212;
  IDTB_CONTENTS    
= 213;
  IDTB_INDEX      
= 214;
  IDTB_SEARCH      
= 215;
  IDTB_HISTORY    
= 216;
  IDTB_FAVORITES  
= 217;
  IDTB_JUMP1      
= 218;
  IDTB_JUMP2      
= 219;
  IDTB_CUSTOMIZE  
= 221;
  IDTB_ZOOM        
= 222;
  IDTB_TOC_NEXT    
= 223;
  IDTB_TOC_PREV    
= 224;
 
const
  HHN_First
= Cardinal(-860);
  HHN_Last  
= Cardinal(-879);
 
  HHN_NavComplete
= HHN_First - 0;
  HHN_Track      
= HHN_First - 1;
 
type
  HHN_Notify
= record
    hdr
: Pointer;
    pszUrl
: PWideChar;
 
end;
 
  HH_Popup
= record
    cbStruct
: Integer;
    hinst
: THandle;
    idString
: Cardinal;
    pszText
: PChar;
    pt
: TPoint;
    clrForeground
: TColor;
    clrBackground
: TColor;
    rcMargins
: TRect;
    pszFont
: PChar;
 
end;
 
  HH_AKLINK
= record
    cbStruct
: Integer;
    fReserved
: bool;
    pszKeywords
: PChar;
    pszUrl
: PChar;
    pszMsgText
: PChar;
    pszMsgTitle
: PChar;
    pszWindow
: PChar;
    fIndexOnFail
: bool;
 
end;
 
type
  HHWin_NavTypes
= (HHWIN_NAVTYPE_TOC,
    HHWIN_NAVTYPE_INDEX
,
    HHWIN_NAVTYPE_SEARCH
,
    HHWIN_NAVTYPE_HISTORY
,
    HHWIN_NAVTYPE_FAVOURITES
);
 
type
  HH_InfoType  
= Longint;
  PHH_InfoType
= ^ HH_InfoType;
 
type
  HHWin_NavTabs
= (HHWIN_NavTab_Top,
    HHWIN_NavTab_Left
,
    HHWIN_NavTab_Bottom
);
 
const
  HH_Max_Tabs
= 19;
 
type
  HH_Tabs
= (HH_TAB_CONTENTS,
    HH_TAB_INDEX
,
    HH_TAB_SEARCH
,
    HH_TAB_HISTORY
,
    HH_TAB_FAVORITES
   
);
 
const
  HH_FTS_DEFAULT_PROXIMITY
= (-1);
 
type
  HH_FTS_Query
= record
    cbStruct
: Integer;
    fUniCodeStrings
: bool;
    pszSearchQuery
: PChar;
    iProximity
: Longint;
    fStemmedSearch
: bool;
    fTitleOnly
: bool;
    fExecute
: bool;
    pszWindow
: PChar;
 
end;
 
type
  HH_WinType
= record
    cbStruct
: Integer;
    fUniCodeStrings
: bool;
    pszType
: PChar;
    fsValidMembers
: Longint;
    fsWinProperties
: Longint;
    pszCaption
: PChar;
    dwStyles
: Longint;
    dwExStyles
: Longint;
    rcWindowPos
: TRect;
    nShowState
: Integer;
    hwndHelp
: THandle;
    hwndCaller
: THandle;
    paInfoTypes
: ^ HH_InfoType;
    hwndToolbar
: THandle;
    hwndNavigation
: THandle;
    hwndHTML
: THandle;
    iNavWidth
: Integer;
    rcHTML
: TRect;
    pszToc
: PChar;
    pszIndex
: PChar;
    pszFile
: PChar;
    pszHome
: PChar;
    fsToolbarFlags
: Longint;
    fNotExpanded
: bool;
    curNavType
: Integer;
    tabPos
: Integer;
    idNotify
: Integer;
   
TabOrder: array[0..HH_Max_Tabs + 1] of Byte;
    cHistory
: Integer;
    pszJump1
: PChar;
    pszJump2
: PChar;
    pszUrlJump1
: PChar;
    pszUrlJump2
: PChar;
    rcMinSize
: TRect;
 
end;
 
  PHH_WinType
= ^ HH_WinType;
 
type
 
HHACTTYpes = (HHACT_TAB_CONTENTS,
    HHACT_TAB_INDEX
,
    HHACT_TAB_SEARCH
,
    HHACT_TAB_HISTORY
,
    HHACT_TAB_FAVORITES
,
 
    HHACT_EXPAND
,
    HHACT_CONTRACT
,
    HHACT_BACK
,
    HHACT_FORWARD
,
    HHACT_STOP
,
    HHACT_REFRESH
,
    HHACT_HOME
,
    HHACT_SYNC
,
    HHACT_OPTIONS
,
    HHACT_PRINT
,
    HHACT_HIGHLIGHT
,
    HHACT_CUSTOMIZE
,
    HHACT_JUMP1
,
    HHACT_JUMP2
,
    HHACT_ZOOM
,
    HHACT_TOC_NEXT
,
    HHACT_TOC_PREV
,
    HHACT_NOTES
,
 
    HHACT_LAST_ENUM
   
);
 
type
  HHNTRACK
= record
    hdr
: TNMHDR;
    pszCurUrl
: PWideChar;
    idAction
: Integer;
    phhWinType
: ^ HH_WinType;
 
end;
  PHHNTRACK
= ^ HHNTRACK;
 
  HHNNAVCOMPLETE
= record
    hdr
: TNMHDR;
    pszUrl
: PChar;
 
end;
  PHHNNAVCOMPLETE
= ^ HHNNAVCOMPLETE;
 
type
 
THtmlHelpA = function(hwndCaller: THandle; pszFile: PChar;
    uCommand
: Cardinal; dwData: Longint): THandle;  
  stdCall
;
 
THtmlHelpW = function(hwndCaller: THandle; pszFile: PChar;
    uCommand
: Cardinal; dwData: Longint): THandle;  
  stdCall
;
 
function HH(hwndCaller: THandle; pszFile: PChar; uCommand: Cardinal;
  dwData
: Longint): THandle;
function HtmlHelpInstalled: Boolean;
 
implementation
 
const
  ATOM_HTMLHELP_API_ANSI
= #14#0;
  ATOM_HTMLHELP_API_UNICODE
= #15#0;
 
var
 
HtmlHelpA: THtmlHelpA;
 
OCXHandle: THandle;
 
function HH;
begin
 
Result := 0;
 
if (Assigned(HtmlHelpA)) then  
 
begin
   
Result := HtmlHelpA(hwndCaller, pszFile, uCommand, dwData);
 
end;
end;
 
function HtmlHelpInstalled: Boolean;
begin
 
Result := (Assigned(HtmlHelpA));
end;
 
initialization
 
begin
   
HtmlHelpA := nil;
   
OCXHandle := LoadLibrary('HHCtrl.OCX');
   
if (OCXHandle <> 0) then  
   
begin
     
HtmlHelpA := GetProcAddress(OCXHandle, 'HtmlHelpA');
   
end;
 
end;
 
finalization
 
begin
   
if (OCXHandle <> 0) then
     
FreeLibrary(OCXHandle);
 
end;
end.
//-----------------------------------------------
unit Unit1; 
 
{....}
 
implementation
 
uses
 
HtmlHelp;
 
const
  HH_HELP_CONTEXT
= $F;
  MYHELP_FILE
= 'DualHelp.chm' + Chr(0);
var
 
RetCode: LongInt;
 
 
{$R *.DFM}
 
procedure TForm1
.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 
if Key = vk_f1 then
 
begin
   
if HtmlHelpInstalled = True then
   
begin
     
RetCode := HH(Form1.Handle, PChar(MYHELP_FILE), HH_HELP_CONTEXT,
       
ActiveControl.HelpContext);
     
Key     := 0; //eat it!
   
end  
   
else
      helpfile
:= 'hhtest.hlp';
 
end;
end;

Взято с сайта https://www.swissdelphicenter.ch/en/tipsindex.php