Wenn Sie den Hilfe-Button in den Standarddialogen nutzen wollen, dann müssen Sie zuerst das Flag *_SHOWHELP ergänzen. Das Sternchen bedeutet, dass der Präfix vom jeweiligen Dialog abhängig ist (Suchen/Ersetzen = FR, Öffnen/Speichern = OFN, Schriftart = CF).
Außerdem müssen Sie die hWndOwner-Variable in jedem Dialog auf das Hauptfenster Ihrer Anwendung setzen. Das ist notwendig, weil das Anklicken des Hilfe-Buttons eine Nachricht auslöst, die von Ihrem Programm bearbeitet werden muss. Als Beispiel ein Auszug aus dem TOpenFileName-Record:
ofn.hWndOwner := wnd;
Wenn Sie sich das Beispielprogramm ansehen, dann werden Sie bemerken, dass der Dialog in einer eigenen Prozedur aufgerufen wird, und das Fenster-Handle "wnd" wird als Parameter dieser Prozedur übergeben.
Außerdem müssen Sie noch den Wert der so genannten HELPMSGSTRING-Nachricht ermitteln. Sie kennen das Prinzip bereits vom Suchen und Ersetzen von Text. Dort haben Sie den Wert einer Nachricht ermittelt, damit Sie Ihr Programm mit der Suchen- und/oder Ersetzenfunktion erweitern konnten.
In der Art läuft das auch hier. Die HELPMSGSTRING-Nachricht ist vom System bereits vergeben, und mit Hilfe von "RegisterWindowMessage" holen wir uns den numerischen Wert:
HelpMsgId := RegisterWindowMessage(HELPMSGSTRING);
Wenn Sie nun den Hilfe-Button in einem der Dialoge anklicken, dann wird diese Nachricht an das Fenster gesendet, dass Sie in hWndOwner angegeben haben. Da es sich im Fall des Beispiels um das Hauptfenster handelt, können wir die Nachricht entsprechend in der "WndProc" des Editorfensters bearbeiten.
Da es sich aber wieder um eine Variable handelt, müssen wir den else-Teil der case-Anweisung nutzen.
case uMsg of { ... }
else if(HelpMsgId <> 0) and (uMsg = HelpMsgId) then MessageBox(wnd,pchar(Format('Hier könnte Ihre Hilfe zum %s erscheinen', [szHelpMsgArray[iHelpContext]])),nil,0) else Result := DefWindowProc(wnd, uMsg, wp, lp); end;
Gibt es etwas zu beachten?
Ja: Der wparam der Nachricht ist das Handle zum Dialog. Allerdings ist Ihnen bestenfalls das Handle des Suchen- und Ersetzendialoges bekannt, und selbst dabei handelt es sich um zwei verschiedene Dialoge. Eine Abfrage wie
if(HWND(wp) = hDlg) then
{ ... }
bringt also nicht viel. Zum einen müssten Sie zwei verschiedene Dialog-Variablen benutzen, um zumindest den Suchen- und den Ersetzendialog voneinander unterscheiden zu können. Und zum anderen haben Sie das Handle des Öffnen- und Speichern- und des Schriftartendialogs überhaupt nicht.
Dann ist zu bedenken, dass der lparam abhängig vom Dialog ein Zeiger auf das dazu gehörende Record ist. Handelt es sich also bspw. um den Schriftartendialog, in dem Sie den Hilfe-Button geklickt haben, dann zeigt der lparam auf ein TChooseFont-Record.
Mit anderen Worten: vergessen Sie die beiden Parameter und nutzen Sie eine einfachere Idee. Der obige Auszug aus dem Beispielprogramm zeigt es Ihnen. Es erscheint eine Messagebox mit einem Text, der den Namen des jeweils angezeigten Dialogs enthält. Das funktioniert mit einem simplen String-Array
const szHelpMsgArray : array[0..4]of string = ('Schriftartendialog', 'Suchendialog', 'Suchen- und Ersetzendialog', 'Öffnendialog', 'Speicherndialog');
auf dessen Elemente mit Hilfe einer integer-Variablen zugegriffen wird, die jeweils vor dem Aufruf des Dialogs entsprechend gesetzt wird. Um beim Beispiel mit dem Öffnendialog zu bleiben, hier würde die Zuweisung ganz einfach so aussehen:
iHelpContext := 3;
Der Rest ist schnell erklärt: Klickt man auf den Hilfe-Button, dann wird die o.g. Nachricht bearbeitet. Und da es sich bei "iHelpContext" um eine globale Variable handelt (ebenso wie das String-Array), kann die MessageBox auch den korrekten Dialognamen ergänzen und anzeigen.
Wenn Sie sinnvolle Informationen anzeigen lassen wollen, dann verweise ich Sie hiermit auf den Beitrag