Wir nutzen Help&Manual und lassen die
HTML-Hilfe erzeugen.
Das ist jetzt zwar
VCL, aber prizipiell ist es ja egal, ob man Application.OnHelp benutzt, oder z.B. im Form.KeyPreview auf VK_F1 reagiert.
Bei uns, im zentralen ApplicationServer/WindowsService läuft, ein TIdHTTPServer (aber egal was), der unsere Hilfe ausliefert.
Es ginge auch direkt im Programmverzeichnis oder auf einer Freigabe (SMB), aber der IE/Edge stufen standardmäßig das Intranet als unsicher ein (z.B. JS und CSS wird dabei krankhaft blockiert),
aber irgendein dubioser WebServer gilt dagegen als sicher.
(Help&Manual bietet auch eine eigene WebServer-App, für dieses Problem, aber zumindestens "damals" war Jene einfach nur grauenhaft und man mußte dringend von deren Nutzung abraten, weil sicherheitstechnisch öffnete sie Scheunentore, so groß wie die Erde)
Man könnte die Dateien sogar als Ressource in eine EXE/
DLL linken und dann via
res-Protokoll.
Bei uns steht die Verlinkung/Zuordnung in einer synchronisierten Datenbanktabelle, also z.B. FormName + optional der CompnentName
oder HelpKontext (selten) direkt an Komponenten oder Menüs/Dialogen (nicht HelpIndex, weil wilde Nummern sind ja nichtssagend)
oder manuell im Code ein
Application.HelpKeyword('...');
und in der Hauptform (oder z.B. einem zentralen Datenmodul) dann TApplicationEvents drauf und dort im OnHelp die Behandlung.
-> also wenn jemand F1 drückt, dann vom AciveControl, über die übergeordneten Panels/GroupBoxen/TabSheets, bis zur Form schauen, ob/wo etwas zugewiesen ist und das Erste anzeigen
-> entweder in einen programminterne TWebBrowser oder an den Default-WebBrowser im System
Also gespeichert ist hier in der
DB das Objekt (FormName/ComponentName) und dazu dann der nur Name der Hilfeseite (ohne
HTML) oder alternativ eine
URL (z.B. in unser Redmine)
PS:
https://docwiki.embarcadero.com/RADS...TML-Hilfetypen
https://www.delphi-treff.de/tutorials/tools/html-hilfe/
https://stackoverflow.com/questions/...my-application
...
Der Hilfe-Button von TaskDialog,
MessageDlg usw. bietet leider nur den HilfeIndex.
(aber die
VCL-Version dieser Dialoge kann man "hacken" und dem
VCL-Button einen HelpKontext zuweisen)
Hier ein Auszug, als Demo, wie man selber auf das F1 reagiert und dessen Infos interpretiert.
Delphi-Quellcode:
{$IFDEF VER220 DelphiXE}
function THelpModul.ApplicationEvents1Help(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
{$ELSE}
function THelpModul.ApplicationEvents1Help(Command: Word; Data: NativeInt; var CallHelp: Boolean): Boolean;
{$ENDIF}
const
cIndex = 'index';
var
Log, HomePath, HelpPath, Browser, Params, Link, Anker, S: string;
Internal: (iIExplore, iDefault, iExtern);
OverrideLink, B: Boolean;
C, C2: TWinControl;
F: TCustomForm;
i: Integer;
begin
Log := '';
try
{$REGION 'originalen Hilfeaufruf loggen'}
case Command of
HELP_CONTEXT: S := ' - HELP_CONTEXT (Display topic in ulTopic)';
HELP_QUIT: S := ' - HELP_QUIT (Terminate help)';
HELP_INDEX: S := ' - HELP_INDEX/HELP_CONTENTS (Display index)';
HELP_HELPONHELP: S := ' - HELP_HELPONHELP (Display help on using help)';
HELP_SETINDEX: S := ' - HELP_SETINDEX/HELP_SETCONTENTS (Set current Index for multi index help)';
HELP_CONTEXTPOPUP: S := ' - HELP_CONTEXTPOPUP';
HELP_FORCEFILE: S := ' - HELP_FORCEFILE';
HELP_CONTEXTMENU: S := ' - HELP_CONTEXTMENU';
HELP_FINDER: S := ' - HELP_FINDER';
HELP_WM_HELP: S := ' - HELP_WM_HELP';
HELP_SETPOPUP_POS: S := ' - HELP_SETPOPUP_POS';
HELP_KEY: S := ' - HELP_KEY (Display topic for keyword in offabData)';
HELP_COMMAND: S := ' - HELP_COMMAND';
HELP_PARTIALKEY: S := ' - HELP_PARTIALKEY';
HELP_MULTIKEY: S := ' - HELP_MULTIKEY';
HELP_SETWINPOS: S := ' - HELP_SETWINPOS';
else S := '';
end;
Log := Log + Format('CallHelp: Command=%d%s Data=%d'#10, [Command, S, Data]);
if Command = HELP_COMMAND then
Log := Log + ' Keyword/JumpID="' + PChar(Data) + '"'#10
else if (Command = HELP_CONTEXT) or (Command = HELP_CONTEXTPOPUP) then
Log := Log + ' ContextID=' + IntToStr(THelpContext(Data)) + #10
else
Log := Log + ' Keyword/ContextID/JumpID nicht erkannt'#10;
{$ENDREGION}
{$REGION 'nicht alle Komandos verarbeiten (z.B. wird beim F1 ein HELP_SETPOPUP_POS vor dem HELP_COMMAND aufgerufen)'}
//if not (Command in [HELP_INDEX, HELP_CONTEXT, HELP_COMMAND, HELP_WM_HELP, HELP_QUIT]) then
// Exit(True);
case Command of
HELP_INDEX, HELP_CONTEXT, HELP_CONTEXTPOPUP, HELP_COMMAND, HELP_WM_HELP, HELP_QUIT: ; // mit CASE, da IN einen zu kleinen Wertebereich zur Verfügung stellt
else Exit(True);
end;
{$ENDREGION}
{$REGION 'HELP_QUIT: das Hilfefenster soll geschlossen werden'}
if Command = HELP_QUIT then begin
FreeAndNil(FormWebBrowser);
Exit(True);
end;
{$ENDREGION}
...
finally
TDM1.LogEvent(Trim(Log));
{$REGION 'weitere Behandlung der Hilfe (F1) abbrechen'}
Result := True;
CallHelp := False;
ApplicationEvents1.CancelDispatch;
{$ENDREGION}
end;
end;