Da Assistenten mit den Property-Sheets vergleichbar sind und auch die selben Records benutzen (von anderen Stilattributen mal abgesehen), wäre dieser Beitrag unvollständig, wenn wir überhaupt nicht darauf eingehen würden.
Ich werde mich auch hier nur auf das Wesentliche beschränken, das beim Erstellen von Property-Sheets interessant ist, und verweise Sie darum auf das Beispiel für die Systemsteuerung, wo ich einen Dialog mit zwei Registerseiten als CPL-Modul benutze.
Auch hier müssen Sie für jede gewünschte Registerseite einen eigenen Dialog erstellen. Der Titel wird übrigens als Beschriftung für das Register (landläufig auch Reiter genannt) verwendet.
Die Dialogressourcen müssen natürlich auch geladen werden, damit sie dem Programm zur Verfügung stehen. Bei einem Property-Sheet entscheidet die Reihenfolge, in der Sie die Dialoge laden, darüber, wie die Registerseiten angeordnet werden.
Beachten Sie bitte, dass Ihnen hier zum Teil andere Attribute als bei Assistenten zur Verfügung stehen. So können Sie beispielsweise die Registerseite mit einem Icon ausstatten. Dazu benutzen Sie das Flag PSP_USEICONID und geben dann in der pszIcon-Membervariablen den Namen der Symbolressource an:
psp.dwFlags := PSP_DEFAULT or PSP_USEICONID;
psp.pszIcon := MAKEINTRESOURCE(1);Und natürlich müssen Sie die Property-Sheets durch den Befehl "PropertySheet" anzeigen lassen. Auch hierbei sind spezielle Attribute zu beachten. So gibt es bei Property-Sheets natürlich nicht den Header oder die Bitmaps des Assistenten. Dafür wird standardmäßig ein Dialog mit den Buttons OK, Abbrechen und Übernehmen (deaktiviert) erzeugt. Mögliche Attribute sind u.a.
| Wert | Bedeutung |
|---|---|
PSH_NOAPPLYNOW | versteckt den Übernehmen-Button |
PSH_NOCONTEXTHELP | versteckt den Hilfe-Button in der Titelleiste |
PSH_PROPTITLE | benötigt die Membervariable pszCaption mit einem gültigen Text, der mit dem Präfix "Eigenschaften von" versehen wird |
PSH_USEICONID | zeigt ein Symbol in der Titelleiste an (dazu muss pszIcon auf eine gültige Ressource verweisen) |
Die gute Nachricht zuerst: die Dialogprozedur ändert sich eigentlich überhaupt nicht. Neu ist lediglich, dass Sie den Übernehmen-Button im Dialog haben, den Sie ggf. abfragen müssen. Üblicherweise ist dies bei diversen Änderungen in den Registerseiten der Fall. Sie kennen das ja von zahlreichen Dialogen des Systems.
Nun ist der Button aber standardmäßig deaktiviert. Sie müssen dem System daher selbst mitteilen, welche Änderungen so "schwerwiegend" sind, dass dafür der Button aktiviert werden soll. Dies geschieht mit Hilfe der Nachricht "PSM_CHANGED", die als wParam das Handle des Dialogs benötigt. In der kleinen Demonstration können Sie den Übernehmen-Button aktivieren, indem Sie in irgendwelchen Text in die Eingabezeile auf der ersten Registerseite eintippen:
WM_COMMAND:
case HIWORD(wp) of
EN_CHANGE:
SendMessage(GetParent(hwndDlg),PSM_CHANGED,WPARAM(hwndDlg),0);
end;
Wenn der Anwender den Button anklickt, wird die Benachrichtigung "PSN_APPLY" als Teil von "WM_NOTIFY" ausgelöst. Hier können Sie dann den notwendigen Code ausführen, um alle gemachten Änderungen (je nach Zweck Ihrer Anwendung) zu speichern.
Danach sollten Sie den Button aber wieder deaktivieren, wofür Sie die Nachricht "PSM_UNCHANGED" benutzen (wieder mit dem Handle des Dialogs):
SendMessage(GetParent(hwndDlg),PSM_UNCHANGED,WPARAM(hwndDlg),0);
Manchmal gibt es aber Situationen, in denen nach dem Klick auf Übernehmen das Beenden des Dialogs erforderlich ist. Das kann der Fall sein, wenn Sie gemachten Änderungen so tief greifend waren, dass ein normales Abbrechen nicht mehr ausreicht (etwa, wenn ein Systemneustart oder dergleichen notwendig ist). In diesem Fall können Sie mit der Nachricht "PSM_CANCELTOCLOSE" bzw. dem Makro "PropSheet_CancelToClose" den Abbrechen-Button deaktivieren, wobei sich auch der Text des OK-Buttons in "Schließen" ändert. Als Parameter geben Sie in beiden Fällen nur das Handle zum Property-Sheet an (also zum übergeordneten Fenster Ihrer Dialogressource). Die Werte von wParam und lParam (bei Verwendung der Nachricht) werden nicht genutzt und bleiben Null.
PropSheet_CancelToClose(GetParent(hwndDlg));