Die Dialogprozeduren des Assistenten


Hier kann ich mich kurz fassen, da sich am grundlegenden Aufbau der Dialogprozeduren ja nichts ändert. Es kommen lediglich spezielle Benachrichtigungen dazu, die mit dem Assistenten bzw. Property-Sheets allgemein zu tun haben. Bitte lesen Sie darum ggf. den Beitrag über Dialoge.

Neu ist, dass wir die Nachricht "WM_NOTIFY" bearbeiten müssen, wenn wir auf Benachrichtigungen des Assistenten reagieren, bzw. diese auch auslösen wollen.

WertBedeutung
PSN_SETACTIVEDie Seite wird angezeigt
PSN_WIZNEXTDer "Weiter"-Button wurde geklickt
PSN_WIZBACKDer "Zurück"-Button wurde geklickt
PSN_WIZFINISHDer "Fertig stellen"-Button wurde geklickt
PSN_HELPDer Hilfe-Button wurde geklickt

(weitere Benachrichtigungscodes finden Sie im PSDK)

Wichtig ist hier, dass die Seiten des Assistenten üblicherweise erst beim Aufruf erzeugt werden. Und nur dann können Sie Dialog-typisch "WM_INITDIALOG" bearbeiten. Bei jedem weiteren Aufruf der Seite, ob nun über den Weiter- oder Zurück-Button, wird die o.g. Benachrichtigung PSN_SETACTIVE ausgelöst.
Sie sollten diese Benachrichtigung in jeder Dialogprozedur bearbeiten, um die notwendigen Buttons zu aktivieren bzw. zu deaktivieren. Nutzen Sie dazu entweder die Nachricht "PSM_SETWIZBUTTONS" oder das Makro "PropSheet_SetWizButtons". Wenn Sie die Nachricht verwenden, dann übergeben Sie die gewünschten Buttons als lParam. Beim Makro geben Sie die Buttons als zweiten Parameter an. Wenn Sie mehrere Buttons aktivieren wollen, kombinieren Sie sie bitte mit or. Auf der Begrüßungsseite sollte bspw. nur der Weiter-Button aktiv sein:

WM_NOTIFY:
  case PNMHdr(lp)^.code of
    PSN_SETACTIVE:
      PropSheet_SetWizButtons(GetParent(hwndDlg),PSWIZB_NEXT);
  end;

Auf den Abbrechen-Button haben Sie keinen Zugriff, der gehört dem zugrunde liegenden Container.

Wie Sie sehen können wurde im Codeauszug "GetParent(hwndDlg)" benutzt. Warum das so ist, habe ich im Prinzip bereits gesagt. Das Handle "hwndDlg" gehört zu der von Ihnen erstellten Dialogressource. Die Buttons sind allerdings Teil des Assistenten, und weil Ihr Dialog ja Teil des Assistenten ist müssen Sie mit "GetParent" auch auf dessen Handle zugreifen.

Auf der letzten Seite ist die Bearbeitung der o.g. Benachrichtigung noch aus einem anderen Grund wichtig: Wenn Sie es vergessen, zeigt Ihre letzte Seite einen Weiter-Button an. Darum müssen Sie hier speziell den "Fertig stellen"-Button (PSWIZB_FINISH) angeben, damit sich die Beschriftung und der Typ ändern:

    PSN_SETACTIVE:
      PropSheet_SetWizButtons(GetParent(hwndDlg),
        PSWIZB_BACK or PSWIZB_FINISH);

Alternativ dazu lässt sich der Button aber auch mit einem anderen Text belegen. Wenn Sie bspw. ein einfaches Setup-Programm schreiben und einen Installieren-Button anbieten wollen, dann tun Sie das am besten beim Bearbeiten von "WM_INITDIALOG"

WM_INITDIALOG:
  PropSheet_SetFinishText(GetParent(hwndDlg),'Installieren');

Dadurch verschwinden aber auch die Zurück- und Weiter-Buttons.


Assistentenseiten überspringen

Um eine Seite zu überspringen, müssen Sie mit "SetWindowLong" das Rückgabeergebnis der Dialogprozedur verändern. Dazu übergeben Sie DWL_MSGRESULT und den Wert des gewünschten Dialogs, den Sie als nächstes sehen wollen.
Um beispielsweise direkt von der Start- zur Endseite zu gelangen, könnten Sie beim Klick auf den Weiter-Button folgendes tun:

WM_NOTIFY:
  case PNMHdr(lp)^.code of
    PSN_WIZNEXT:
      begin
        SetWindowLong(hwndDlg,DWL_MSGRESULT,IDD_FINISHDLG);

Allerdings müssen Sie die Nachricht als "bearbeitet" deklarieren, sonst wird der Befehl ignoriert, und Sie landen auf der regulären zweiten Seite:

        Result := true;
      end;

Im Beispielprogramm gibt es keine Verwendung für so ein Verhalten. Dort ist es aus verschiedenen Gründen erforderlich, die Reihenfolge einzuhalten.