Die Hilfe verwenden


Wir brauchen nun die schon angesprochenen Units der JEDIs. Davon binden wir die Unit "HtmlHlp.pas" in unser Projekt ein.

Probleme vermeiden

Ganz wichtig ist es, den Compilerschalter HTMLHELP_DYNAMIC_LINK zu benutzen. Damit wird versucht, die CHM-Funktionen dynamisch zu laden. Wenn Sie den Schalter nicht nutzen, wird davon ausgegangen, dass CHM-Hilfedateien generell unterstützt werden. Das kann auf Windows 95/NT4-Systemen zu Problemen führen, weil diese standardmäßig mit dem CHM-Typ nichts anfangen können. Sie könnten alternativ eine zweite Hilfedatei im HLP-Format schreiben, oder Sie fordern den Anwender auf, sich das HtmlHelp-Update von Microsoft zu installieren wenn er Ihre Hilfe nutzen möchte.

Durch den o.g. Compilerschalter steht Ihnen die Bool-Variable "HtmlHelpIsAvail" zur Abfrage zur Verfügung. Der Schalter ist Teil einer Include-Datei. Allerdings ist er entweder fehlerhaft eingetragen oder auf diese Weise standardmäßig deaktiviert. Öffnen Sie im Zweifelsfall bitte die Datei "HtmlHlp.inc" und ersetzen Sie den Eintrag HTML_HELP_DYNAMIC_LINK durch den o.g. korrekten Compilerschalter. Bei der Version, die diesem Tutorial beiliegt, habe ich dies bereits erledigt.

Als Grundlage soll unser HLP-Beispielprogramm dienen, das wir nun für die CHM-Hilfedatei ein wenig ändern. An erster Stelle steht dabei natürlich der Dateiname in der Variablen "szHelpFile", der angepasst werden muss. Wenn das geschehen ist, benutzen wir den neuen Befehl "HtmlHelp" in unserem Programm:

HWND HtmlHelp(
	HWND    hwndCaller,
	LPCSTR  pszFile,
	UINT    uCommand,
	DWORD   dwData
);


WM_COMMAND:
  case HIWORD(wp) of
    BN_CLICKED:
      case LOWORD(wp) of
        IDC_TOCBTN:
          if(IsWindowEnabled(hTocBtn)) then
            HtmlHelp(wnd,@szHelpFile[1],HH_DISPLAY_TOC,0);
        IDC_IDXBTN:
          if(IsWindowEnabled(hIdxBtn)) then
            HtmlHelp(wnd,@szHelpFile[1],HH_DISPLAY_INDEX,0);
        IDC_THEME2BTN:
          if(IsWindowEnabled(hTheme2Btn)) then
          begin
            URL := szHelpFile + '::/page2.htm';
            HtmlHelp(wnd,@URL[1],HH_DISPLAY_TOPIC,0);
          end;
      end;
  end;

Der o.g. Codeauszug demonstriert Ihnen anhand des Buttons "IDC_THEME2BTN", wie Sie gezielt ein Thema der Hilfedatei aufrufen können.


Beachten Sie bitte die Syntax der CHM-Hilfe, die sich von der Syntax im Web unterscheidet. Vom Web sind Sie es gewohnt einen Doppelpunkt und zwei Schrägstriche zu verwenden, bei der CHM-Hilfe ist das genau umgekehrt.
Hier liegt übrigens auch eine der Hauptfehlerquellen bei CHM-Hilfedateien. Bei der Kompilierung der HTML-Seiten zu einer CHM-Datei werden standardmäßig alle Ordner- und Dateireferenzen beibehalten. Befindet sich Ihre HTML-Datei also in einem eigenen Verzeichnis, dann müssen Sie dieses Verzeichnis beim Aufruf des Themas mit angeben. Gehen wir als Beispiel davon aus, die Datei "page2.htm" würde nicht im Verzeichnis der Projektdateien sondern stattdessen im untergeordneten Verzeichnis "htdocs" gespeichert sein. Der Aufruf von oben müsste daher so geändert werden:

URL := szHelpFile + '::/htdocs/page2.htm';

Auch hier sollten wir beim Beenden des Programms ein evtl. offenes Hilfefenster ebenfalls schließen. Das ist nur eine kleine Änderung im "WM_DESTROY"-Teil:

WM_DESTROY:
  begin
    if(HtmlHelpIsAvail) then HtmlHelp(wnd,nil,HH_CLOSE_ALL,0);
    PostQuitMessage(0);
  end;


Als einzig noch erwähnenswerte Änderung soll noch auf die Sicherheitsprüfung eingegangen werden. Bei unserem HLP-Beispiel genügte es, das Vorhandensein der Hilfedatei zu prüfen. Bei der CHM-Hilfe müssen Sie aber auch damit rechnen, dass ein Anwender Ihr Programm unter Windows 95 oder NT 4 laufen lässt. Ohne das Update von Microsoft gibt es dort keine Html-Hilfe. Daher müssen wir zusätzlich prüfen, ob das dafür zuständige OCX-Control geladen wurde:

if(not fileexists(szHelpFile)) or (not HtmlHelpIsAvail) then
begin
  // Elemente deaktivieren
end;



Die Hilfe in einer MessageBox verwenden

Wie bereits bei den HLP-Dateien beschrieben, kann man auch hier "MessageBox(Ex)" benutzen, um die Hilfe aufzurufen. Selbstverständlich lässt sich für die Anzeige von speziellen Themen der Hilfedatei auch wieder "MessageBoxIndirect" verwenden, weil aber die Technik eine andere ist, muss ein wenig nachgeholfen werden.

Um das Thema als Popup anzuzeigen, sollten Sie Ihre Textdatei mit den kontextsensitiven Informationen entsprechend ergänzen:

.TOPIC 3000
Wenn Sie diese Seite sehen, dann haben Sie auf den Hilfe-Button
einer MessageBox geklickt. Sie können solche Sachen natürlich
sinnvoller nutzen.

(Den gleichen Text können Sie auch auch direkt im Programm unterbringen, wie hier noch beschrieben werden wird.) Würden Sie die Hilfedatei nun neu kompilieren und ausprobieren, sollte der obige Text eigentlich erscheinen.
Wenn Sie ihn aber auch wieder in einem Hilfefenster sehen wollen, dann sollten Sie zuerst natürlich eine entsprechende HTML-Seite anlegen und Ihrem Hilfe-Projekt hinzufügen. Dann benutzen Sie die Funktion "MsgBoxCallback" aus dem o.g. HLP-Kapitel als Grundlage, ändern jedoch den Aufruf der alten Hilfe für die HTML-Hilfe um:

procedure MsgBoxCallback(phi: PHelpInfo); stdcall;
begin
  if(phi.dwContextId = HLP_PAGE_4) then
  begin
    URL := szHelpFile + '::/page4.htm';
    HtmlHelp(phi.hItemHandle,@URL[1],HH_DISPLAY_TOPIC,0);
  end;
end;

In diesem Fall ist eine Abfrage enthalten, damit das gewünschte Thema nur angezeigt wird, wenn die übermittelte Kontext-ID stimmt. Wenn Sie mehrere verschiedene Themen auf diese Weise anzeigen wollen, dann bietet sich ein Array oder vielleicht eine case-Abfrage an.
Wie dem auch sei, mehr ist an Änderungen nicht erforderlich, und Ihr Programm ruft nun auch Themen aus CHM-Hilfedateien auf.