function THTMLhelpRouter.CurrentForm: TForm;
begin
if Screen.ActiveForm <> NIL then
Result:= Screen.ActiveForm
else Result:= Owner as TForm;
end;
procedure THTMLhelpRouter.SetHelpType(value: THelpType);
begin
if value <> fHelpType then
begin
fHelpType := value;
if fHelpType in [htAuto,htHTMLhelp] then LoadHHCTRL;
end;
end;
function THTMLhelpRouter.HTMLhelpInstalled: boolean;
begin
if HHCTRL = 0 then LoadHHCTRL;
result := assigned(HtmlHelpA);
end;
function THTMLhelpRouter.FindHandle(var Helphandle: HWND; var Hfile: string): boolean;
begin
result := false;
case HelpType of
htWinhelp: result := false;
htHTMLhelp: result := true;
htAuto: result := HTMLhelpInstalled;
end;
HFile := Application.helpfile;
HelpHandle := Application.handle;
{$IFDEF VER100}
CForm := CurrentForm;
if Assigned(CForm) and CForm.HandleAllocated and (CForm.HelpFile <> '') then
begin
HelpHandle := CForm.Handle;
HFile := CForm.HelpFile;
end;
{$ENDIF}
if fHelpFile <> '' then
begin
HFile := fhelpfile;
HelpHandle := Application.handle;
end;
end;
function THTMLhelpRouter.OnRouteHelp(Command: Word; Data: Longint; var CallHelp: Boolean): Boolean;
var
showHTML: boolean;
rHandle: integer;
HelpHandle: HWND;
HFile: string;
begin
Result := False;
if assigned(fOnHelp) then result := fOnHelp(command, data, callhelp);
if not callHelp then exit;
if assigned(fAppOnHelp) then result := fAppOnHelp(command, data, callhelp);
if not callHelp then exit;
showHTML := FindHandle(HelpHandle, HFile);
if showHTML then
begin
rHandle := 0;
HFile := changefileext(Hfile,'.chm');
case Command of
HELP_FINDER, HELP_CONTENTS: rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_DISPLAY_TOC, 0); //show table of contents
HELP_KEY: rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_DISPLAY_INDEX, data); //display keywordshow table of contens
HELP_QUIT: rHandle := HtmlHelpA(helphandle, nil, HH_CLOSE_ALL, 0);
HELP_CONTEXT: rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_HELP_CONTEXT, data); //display help context
HELP_CONTEXTPOPUP: rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_HELP_CONTEXT, data);
end;
Result := rHandle <> 0;
end;
if (not result) and (fHelpType <> htHTMLhelp) then
begin
case Command of
HELP_SETPOPUP_POS: if fShowType = stMain then Command := 0;
HELP_CONTEXTPOPUP: if fShowType = stMain then Command := HELP_CONTEXT; //no popup
end;
if Command <> 0 then Result := WinHelp(HelpHandle, PChar(changefileext(HFile,'.hlp')), Command, Data)
else Result := true;
end;
CallHelp := false;
end;
function THTMLhelpRouter.HelpContent: boolean;
begin
result := application.helpcommand(HELP_FINDER, 0);
end;
function THTMLhelpRouter.ValidateHTMLID(link: string): string;
var
I: integer;
begin
result := '';
for I := 1 to length(link) do
case link[i] of
' ': result := result + '_';
'.': result := result + '_';
'\': result := result + '';
'/': result := result + '';
':': result := result + '';
'%': result := result + '_';
'"': result := result + '';
'<': result := result + '~';
'>': result := result + '~';
'|': result := result + '';
',': result := result + '';
'*': result := result + '+';
'?': result := result + '';
'?: result := result + '';
'[': result := result + '(';
']': result := result + ')';
'&': result := result + '+';
else result := result + link[i];
end;
end;
function THTMLhelpRouter.HelpJump(hfile, topicid: string): boolean;
var
Command: array[0..255] of Char;
showHTML: boolean;
rHandle: integer;
HelpHandle: HWND;
HF, HID: string;
begin
result := false;
showHTML := FindHandle(HelpHandle, HF);
if Hfile <> '' then
begin
HF := HFile;
HelpHandle := 0;
end;
if showHTML then
begin
HFile := changefileext(HF,'.chm');
HID := TopicID;
if copy(lowercase(extractfileext(HID)),1,4) <> '.htm' then
begin
if fValidateID then HID := ValidateHTMLID(HID);
HID := HID + '.htm';
end;
rHandle := HtmlHelpA(helphandle, pchar(Hfile+'::/'+HID), HH_DISPLAY_TOPIC, 0); //show table of contents
Result := rHandle <> 0;
end;
if (not result) and (fHelpType <> htHTMLhelp) then
begin
hfile := changefileext(HF,'.hlp');
StrLFmt(Command, SizeOf(Command) - 1, 'JumpID("","%s")', [TopicID]);
Result := WinHelp(HelpHandle, PChar(Hfile), HELP_CONTENTS, 0);
if Result then Result := WinHelp(HelpHandle, PChar(hfile), HELP_COMMAND, Longint(@Command));
end;
end;
function THTMLhelpRouter.HelpPopup(X,Y: integer; text: string): boolean;
var
CForm: TForm;
HP: THH_Popup;
begin
if (fHelpType <> htWinhelp) and HTMLhelpInstalled then
begin
CForm := CurrentForm;
with HP do
begin
cbStruct := sizeof(HP);
hInstance := 0;
idString := 0;
pszText := PChar(text);
pt.x := X;
pt.y := Y;
ClientToScreen(CForm.handle, pt);
clrForeground := -1;
clrBackground := -1;
rcMargins.Left := -1;
rcMargins.Right := -1;
rcMargins.Top := -1;
rcMargins.Bottom := -1;
pszFont := PChar('宋体, 9');
end;
result := HtmlHelpA(CForm.handle, nil, HH_DISPLAY_TEXT_POPUP, longint(@HP)) <> 0;
end
else result := false;
end;
function THTMLhelpRouter.HelpKeyword(keyword: string): boolean;
var
Command: array[0..255] of Char;
begin
StrLcopy(Command, pchar(keyword), SizeOf(Command) - 1);
result := application.helpcommand(HELP_KEY, Longint(@Command));
end;
function THTMLhelpRouter.HelpKLink(keyword: string): boolean;
var
Command: array[0..255] of Char;
showHTML: boolean;
rHandle: integer;
HelpHandle: HWND;
HF, Hfile: string;
HA: THH_AKLINK;
begin
result := false;
showHTML := FindHandle(HelpHandle, HF);
if showHTML then
begin
HFile := changefileext(HF,'.chm');
with HA do
begin
cbStruct := sizeof(HA);
fReserved := false;
pszKeywords := pchar(keyword);
pszUrl := '';
pszMsgText := '';
pszMsgTitle := '';
pszMsgWindow := '';
fIndexOnFail := true;
end;
rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_DISPLAY_TOPIC, 0); //create window
if rHandle <> 0 then rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_KEYWORD_LOOKUP, longint(@HA));
Result := rHandle <> 0;
end;
if (not result) and (fHelpType <> htHTMLhelp) then
begin
HFile := changefileext(HF,'.hlp');
StrLFmt(Command, SizeOf(Command) - 1, 'KL("%s",1)', [keyword]);
Result := WinHelp(HelpHandle, PChar(Hfile), HELP_CONTENTS, 0);
if Result then Result := WinHelp(HelpHandle, PChar(hfile), HELP_COMMAND, Longint(@Command));
end;
end;
function THTMLhelpRouter.HelpALink(akeyword: string): boolean;
var
Command: array[0..255] of Char;
showHTML: boolean;
rHandle: integer;
HelpHandle: HWND;
HF, Hfile: string;
HA: THH_AKLINK;
begin
result := false;
showHTML := FindHandle(HelpHandle, HF);
if showHTML then
begin
HFile := changefileext(HF,'.chm');
with HA do
begin
cbStruct := sizeof(HA);
fReserved := false;
pszKeywords := pchar(akeyword);
pszUrl := '';
pszMsgText := '';
pszMsgTitle := '';
pszMsgWindow := '';
fIndexOnFail := true;
end;
rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_DISPLAY_TOPIC, 0); //create window
if rHandle <> 0 then rHandle := HtmlHelpA(helphandle, pchar(Hfile), HH_ALINK_LOOKUP, longint(@HA));
Result := rHandle <> 0;
end;
if (not result) and (fHelpType <> htHTMLhelp) then
begin
hfile := changefileext(HF,'.hlp');
StrLFmt(Command, SizeOf(Command) - 1, 'AL("%s",1)', [akeyword]);
Result := WinHelp(HelpHandle, PChar(Hfile), HELP_CONTENTS, 0);
if Result then Result := WinHelp(HelpHandle, PChar(hfile), HELP_COMMAND, Longint(@Command));
end;
end;
function THTMLhelpRouter.GetVersion: string;
begin
result := cVersion;
end;
procedure THTMLhelpRouter.SetVersion(dummy: string);
begin
//do nothing
end;
THIS SOFTWARE AND THE ACCOMPANYING FILES ARE PROVIDED "AS IS" AND
WITHOUT WARRANTIES OF ANY KIND WHETHER EXPRESSED OR IMPLIED.
In no event shall the author be held liable for any damages whatsoever,
including without limitation, damages for loss of business profits,
business interruption, loss of business information, or any other loss
arising from the use or inability to use the software.
====================================================================*)
var
HtmlHelpA: THtmlHelpA;
HHCTRL: THandle;
GLOBAL_HELPROUTER: THTMLhelpRouter;
implementation
function LoadHHCTRL: boolean;
begin
if HHCTRL = 0 then
begin
HtmlHelpA := nil;
HHCTRL := LoadLibrary('HHCTRL.OCX');
if (HHCTRL <> 0) then HtmlHelpA := GetProcAddress(HHCTRL, 'HtmlHelpA');
end;
result := HHCTRL <> 0;
end;
function CheckRouterInstance: boolean;
begin
if GLOBAL_HELPROUTER <> NIL then raise Exception.Create('Multiple instances of THTMLhelpRouter are not allowed')
else result := true;
end;
{ --- THTMLhelpRouter --- }
constructor THTMLhelpRouter.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if CheckRouterInstance and not (csDesigning in Componentstate) then
begin
fAppOnHelp := Application.onhelp;
Application.onhelp := OnRouteHelp;
GLOBAL_HELPROUTER := Self;
end;
fShowType := stDefault;
end;
destructor THTMLhelpRouter.Destroy;
begin
if not (csDesigning in Componentstate) then if assigned(fAppOnHelp) then Application.onhelp := fAppOnHelp else Application.onhelp := nil;
GLOBAL_HELPROUTER := nil;
inherited Destroy;
end;