HTML-Hilfe

Ziel dieses Beispiels:
Ein HTML-basierendes Hilfesystem soll verwendet werden.
Hier gibt es das Beispiel zum Download: HTMLHelp.zip
Referenz-Links:
Knowledge Base Artikel 191118 How To Create Context-Sensitive HTML Help in an MFC Application
Technical Note TN028 Context-Sensitive Help Support

Schritt 1: Anwendungsgerüst

Erstellen des Anwendungsgerüsts (SDI-Anwendung) wie in den bisherige Beispielen.
In den "Advanced Features" wird die Checkbox "Context-sensitive Help" mit der Option "HTML Help Format" gesetzt.
HTML-Hilfe aktivieren
Beim Compilieren des Projekts wird der Help Compiler aufgerufen. Wird das Projekt gestartet gelangt man durch Drücken von "F1" oder über das Menü "Hilfe" in ein Hilfe-Template, das schon Einträge für die generierten Menüpunkte enthält.
Neu ist ein Unterverzeichnis "hlp" im Projekt, dass die HTML-Dateien der Hilfe enthält.
Verzeichnisstruktor
Aus diesen erzeugt der HTML Help Compiler (hhc.exe, im Verzeichnis "C:\Programme\HTML Help Workshop"), der beim compilieren kurz als Dos-Fenster auftaucht, eine chm-Datei, die ins Debug/Release-Verzeichnis kopiert wird.

Im Code findet sich nur eine einzige Änderung:
In MainFrm.cpp gibt es vier neue Einträge in der Message Map, die die Hilfe-Befehle auf Standard-Methoden von CFrameWnd (bzw. CWnd, dort sind sie deklariert) umleiten.

	// Globale Hilfebefehle
	ON_COMMAND(ID_HELP_FINDER, CFrameWnd::OnHelpFinder)
	ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
	ON_COMMAND(ID_CONTEXT_HELP, CFrameWnd::OnContextHelp)
	ON_COMMAND(ID_DEFAULT_HELP, CFrameWnd::OnHelpFinder)
Das Drücken von "F1" wird durch die Methode "OnHelp" abgehandelt.

Schritt 2: Programmlogik

Das Fenster der CView soll zwei Rechtecke enthalten. Wenn der User in eines davon klickt (sozusagen ein Auswählen) und dann F1 drückt soll er eine Contextabhängige Hilfe bekommen. Dazu im OnDraw zwei Rechteckt der Größe 200x200 zeichnen, das aktuell gewählte bekommt ein Fokus-Rechteck.
So soll es aussehen
Das Event "OnLButtonDown" speichert die Mausklick-Position in einer Instanzvariablen (im Konstruktor mit "-1/-1" initialisiert) und löst ein Repaint aus.


Schritt 3: Neue Hilfeeinträge

Jeder Hilfseintrag steht in einer eigenen HTML-Datei. Normalerweise enthalten diese den Namen des Controls/Menüpunkts, für den sie gelten. Da wir hier aber eigene Hilfe-Themen gebaut haben, verwenden wir einen leicht anderen Ansatz.
Zuerst einmal bauen wir drei HTML-Dateien "htmlhelp_links.htm", "htmlhelp_rechts.htm" und "htmlhelp_none.htm" im Verzeichnis "hlp". Ich habe hierzu die Datei "scrollbars.htm" kopiert und umbenannt. Der Inhalt ist reines HTML, zu beachten ist nur dass der Anchor mit dem Namen der Hilfe-Datei vorhanden ist (im Beispiel: htmlhelp_links.htm):
	<A NAME="htmlhelp_links"></A> 
Wichtig: Diese Dateien dem Projekt zufügen: im "Solution Explorer" die "HTML Help Topics" auswählen, Rechtsklick und "Add Existing Item..." wählen.

In der Datei "./help/HTMLHelp.hhp" erfolgt die Definition der Hilfe.
In der Sektion "[FILES]" fügen wir drei neue Einträge ein:
	htmlhelp_links.htm
	htmlhelp_rechts.htm
	htmlhelp_none.htm  
In der Sektion "[ALIAS]" (Mapping von internen Alias-Namen auf Dateien) erfolgen ebenfalls drei Einträge:
	HTMLHELP_RECHTECK_LINKS				= HTMLHELP_LINKS.HTM
	HTMLHELP_RECHTECK_RECHTS			= HTMLHELP_RECHTS.HTM 
	HTMLHELP_RECHTECK_NONE				= HTMLHELP_NONE.HTM

Schließlich werden in der Sektion "[MAPS]" die drei Alias-Namen aus der vorherigen Sektion definiert:
	#define HTMLHELP_RECHTECK_LINKS			0x1
	#define HTMLHELP_RECHTECK_RECHTS		0x2
	#define HTMLHELP_RECHTECK_NONE			0x3 
Gemäß Technical Note 28 ist der Bereich von 0x00000000 bis 0x0000FFFF "user defined", darf also für sonstige Hilfe-IDs verwendet werden.
Achtung: NICHT mit "0x0" beginnen, da die Help-ID bei der Message "WM_HELPHITTEST" als Rückgabe dient und "0x0" dann "nicht gefunden" bedeuten würde !
Hinweis: In der "[MAPS]"-Sektion wird zuerst "HTMLDefines.h" includiert. Dort können wir unsere Defines jedoch nicht unterbringen da die Datei bei jedem compilieren neu (aus der Resourcen-Datei ?) erzeugt wird.

Im Beispielprogramm ist dies ein wenig cleverer gelöst, indem die Defines in eine eigene Headerdatei "HTMLHelpDefines.d" verschoben sind.
In der "[MAPS]"-Sektion von "HTMLHelp.hhp" wird nur diese Datei eingebunden (die in diesem Fall nicht im gleichen Verzeichnis wie die hhp-Datei liegt !):
#include ..\HTMLHelpDefines.h 

Letzter Schritt: die Dateien in den Hilfe-Inhalt-Baum eintragen. Dazu die Datei "HTMLHelp.hcc" öffnen und folgendes einfügen:
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="Rechteck: links">
		<param name="Local" value="htmlhelp_links.htm">
		</OBJECT>
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="Rechteck: rechts">
		<param name="Local" value="htmlhelp_rechts.htm">
		</OBJECT>
	<LI> <OBJECT type="text/sitemap">
		<param name="Name" value="Rechteck: none">
		<param name="Local" value="htmlhelp_none.htm">
		</OBJECT> 
Das Ergebnis sieht so aus:
Hilfe-Inhalt

Jetzt können wir das Programm starten und sehen unsere Hilfedateien in der Hilfe selbst, kommen aber mit F1 noch nicht dorthin.


Einträge in Karteikarte "Index" einfügen:
Hierzu einfach folgenden Eintrag in den Body einer HTML-Datei einfügen:
	<OBJECT TYPE="application/x-oleobject" CLASSID="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
		<PARAM NAME="Keyword" VALUE="Rechteckfenster">
	</OBJECT> 
Wichtig ist das "Value"-Attribut des Elements "param".
Im Beispiel habe ich für alle drei Rechteckfenster-Hilfedateien diesen Eintrag eingefügt. Das führt zu diesem Ergebnis:
Hilfeindex

Schritt 4: Von der View zur Hilfe

Hier können wir keine Standard-MFC-Verknüpfung der Hilfeeinträge verwenden, da diese nur pro Menüpunkt oder Control angebbar ist, aber nicht dynamisch. Also tricksen wir in der View ein wenig:


Weiteres



HTML-Hilfe in ein bestehendes Projekt einbauen

Ideales Vorgehen: ein SDI-Projekt "NoHelp" ohne Hilfe und ein Projekt "WithHelp" mit HTML-Hilfe erstellen. Diese beiden Projekte vergleichen und die Änderungen nachbauen.

Version 1.1.0.1, Stand 17.07.2005
Historie:
1.0.0.0 (26.06.2005) Beispiel zugefügt.
1.1.0.0 (27.06.2005) Wie versehe ich ein hilfloses Projekt mit einer Solchen ?
Beispiel gesäubert: Hilfe-IDs in eigener Headerdatei.
1.1.0.1 (17.07.2005) Die Umstellung eines existierenden Projekts unterstützte F1 nicht.