1
votes

How to add support of HTML help files (.chm) on Delphi XE2? We need to use A-links (A-keywords) on HelpContext property of every control to lookup help pages. Delphi XE2 has native support of HTML help files by unit HTMLHelpViewer. But how to use it?

3
Thanks, but if you use HTMLHelpViewer unit the help stops working on Delphi IDE.Dmitry
have you set Application.HelpFile := 'sample.chm'; pointing to an existing .chm file??moskito-x
BPLs don't know where is .chm file.Dmitry
To get sample.chm, there is a download link in my answer !!moskito-x

3 Answers

2
votes

It's not hard with F1 jump to a context.

Select Edit1 and press F1 . Help opens and Overview.htm is shown.

enter image description here

Prerequisite.

enter image description here

Edit1 Help settings:

enter image description here

sample.chm source settings.

sample.ali

IDH_Overview=Overview.htm
IDH_welcom=FirstTopic.htm
IDH_UsingtheMenus=Overview.htm

sample.h

#define IDH_Creating_Projects_and_Topics 1005
#define IDH_Overview 1003
#define IDH_UsingtheMenus 1009

Unit1.pas

unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, HTMLHelpViewer, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    HHALINKLOOKUP: TButton;
    JumpAnchor: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure HHALINKLOOKUPClick(Sender: TObject);
    procedure JumpAnchorClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
hpPath : string;
link : HH_AKLINK;

procedure TForm1.FormCreate(Sender: TObject);
begin
  hpPath := ExtractFilePath(Application.ExeName) +
    'HelpFile\sample.chm';
  Application.HelpFile := hpPath;
end;

procedure TForm1.HHALINKLOOKUPClick(Sender: TObject);
var
link : HH_AKLINK;
szUrl,szKey,szMsgText,szMsgTitle,szWindow : AnsiString;
begin
   szKey      := Edit1.Text; // 'UsingtheMenus';
   szUrl      :='Overview.htm';
   szMsgText  :='Error: Can''t find "'+Edit1.Text+'"!';
   szMsgTitle :='Error: HH_ALINK_LOOKUP';
   szWindow   :='main';

   with link do begin
   cbStruct    := sizeof(HH_AKLINK) ;
   fReserved   := False;
   pszKeywords := PChar(szKey);
   pszUrl      := nil;
   pszMsgText  := PChar(szMsgText);
   pszMsgTitle := PChar(szMsgTitle);
   pszWindow   := PChar(szWindow);
   fIndexOnFail:= False;
   end;
   HtmlHelpW(0, hpPath+'>main', HH_DISPLAY_TOPIC, DWORD_PTR(nil));
   HtmlHelpW(0, hpPath, HH_ALINK_LOOKUP, DWORD_PTR(@link));
end;

procedure TForm1.JumpAnchorClick(Sender: TObject);
begin
  HtmlHelpW(0, hpPath+'::/Overview.htm#'+Edit1.Text+'>main', HH_DISPLAY_TOPIC, DWORD(nil));
end;
end.

Here is a ready to use sample.chm and the source Download

There is a trick how to easily, to jump, not only to the .htm file but jumps directly to an anchor.

Change sample.ali

IDH_Overview=Overview.htm
IDH_welcom=FirstTopic.htm
IDH_UsingtheMenus=Overview.htm#UsingtheMenus

Insert an anchor at the place, you want to jump to in Overview.htm

[...]
<A NAME="UsingtheMenus" </A>
<P><STRONG>Using the Menus and Toolbars</STRONG>
<P>The menus and toolbars provide a complete set of tools 
[...]

Now it is possible with F1, jump directly to the desired point in overview.htm.

enter image description here

1
votes

I suspect that to use A-links you need to do the following:

  1. Assign an Application.OnHelp handler as described below.
  2. Assign Application.HelpFile during program startup.
  3. Call Application.HelpKeyword if you wish to invoke the help system with an A-link.
  4. Set the HelpKeyword property for any GUI controls that you wish to respond to context sensitive F1 key presses.

The OnHelp handler looks like this:

function TMainForm.ApplicationHelp(Command: Word; 
  Data: THelpEventData; var CallHelp: Boolean): Boolean;
var
  Link: THH_AKLink;
  ALink: string;
begin
  CallHelp := False;
  Result := True;
  //argh, WinHelp commands
  case Command of
  HELP_COMMAND:
    begin
      ZeroMemory(@Link, SizeOf(Link));
      Link.cbStruct := SizeOf(Link);
      ALink := PChar(Data); // we are going to re-purpose the keyword as an A-link
      Link.pszKeywords := PChar(AnsiString(ALink)); // seems we have to pass a PAnsiChar ..
      Link.fIndexOnFail := True;
      HtmlHelp(GetDesktopWindow, Application.HelpFile, HH_ALINK_LOOKUP, 
        DWORD_PTR(@Link));
    end;
  end;
end;

The HtmlHelpViewer unit contains methods named LookupALink which do the same. But I don't see how they could ever be called.

The above approach is a little bit hacky because it interprets keywords as A-Links. If you want context sensitive help, I can't see what else you can do.

0
votes

Not sure how Xe2 viewer works (I'm on 2007) but I just use Eric Granges port of the Microsoft HTML help API, which unsurprisingly, is called HTMLhelpAPI.pas.

You can call an Alink using the function

ChmShowTopic(const filename,atopic:string):HWND;