# messagebox — `n_pbt_messagebox` #

← Komponentenreferenz · Inhalt des Handbuchs

> Modales Dialogfeld im Design der Anwendung, mit synchronem Rückgabewert: der direkte Ersatz für das `MessageBox()` von PowerBuilder, mit Rich-Text, frei wählbaren Schaltflächen, Symbolen und Kontrollkästchen.

> ▶ Live ansehen — Demoanwendung, Kachel Message box: die Vorschau, der zugehörige Code und diese Seite, nebeneinander.

## Auf einen Blick #

Objekt | `n_pbt_messagebox` — nicht visuell: nichts, was im Fenster platziert werden muss
Wofür | Eine Frage stellen oder ein Ergebnis melden, anstelle des starren und nicht gestalteten nativen `MessageBox()`
Rückgabewert | Synchron: `of_show()` blockiert und liefert den Index der angeklickten Schaltfläche

Anders als die visuellen Komponenten wird dieses Objekt nicht in ein Fenster eingefügt: Sie erzeugen, konfigurieren, zeigen und zerstören es.

    n_pbt_messagebox lnv_mb

    lnv_mb = create n_pbt_messagebox
    // ... Konfiguration ...
    destroy lnv_mb

## Schnellstart #

    n_pbt_messagebox lnv_mb

    lnv_mb = create n_pbt_messagebox

    lnv_mb.is_title   = "Löschen"
    lnv_mb.is_icon    = lnv_mb.ICON_WARNING
    lnv_mb.is_message = "[b]12 Ordner[/b] endgültig löschen ?[br][br]Diese Aktion kann nicht rückgängig gemacht werden."

    lnv_mb.of_add_button(/*text*/ "Löschen", /*standard*/ true,  /*abbrechen*/ false)   // -> 1
    lnv_mb.of_add_button(/*text*/ "Abbrechen",   /*standard*/ false, /*abbrechen*/ true)    // -> 2

    if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
        of_supprimer()
    end if

    destroy lnv_mb

`of_show` wartet auf die Antwort des Benutzers: Die nächste Zeile wird erst nach dem Klick ausgeführt, genau wie bei `MessageBox()`.

## Eigenschaften #

Vor `of_show` zu setzen.

Eigenschaft | Typ | Standard | Zweck
--- | --- | --- | ---
`is_title` | string | `""` | Titel, der in der Kopfzeile des Dialogfelds angezeigt wird
`is_message` | string | `""` | Text der Meldung. Akzeptiert die Rich-Text-Auszeichnung (`[b]`, `[i]`, `[br]`, `[accent]`, `[picture=…]`…)
`is_instruction` | string | `""` | Hauptanweisung: die Frage selbst, größer über der Meldung angezeigt. Titel / Anweisung / Meldung ist der Aufbau, der einen Dialog auf einen Blick lesbar macht — „42 Zeilen löschen?“ dann „Dies kann nicht rückgängig gemacht werden“ — statt eines gleichförmigen Blocks. Nimmt die Auszeichnung an
`is_icon` | string | `""` | Symbol: eine Konstante `ICON_*` oder Ihr eigenes Bild (Dateipfad oder DLL-Ressource `meine.dll:NAME`)
`is_checkbox` | string | `""` | Text eines optionalen Kontrollkästchens im Stil „nicht mehr nachfragen" (`""` = kein Kontrollkästchen)
`ib_checked` | boolean | `false` | Anfangszustand des Kontrollkästchens (der Endzustand wird mit `of_checked()` gelesen)
`ib_input` | boolean | `false` | Fügt ein gestaltetes Eingabefeld hinzu (umbenennen, Grund, Kommentar), sodass eine Anwendung kein selbstgebautes Fenster mehr braucht, das weder dem Thema noch der Leserichtung folgt. Mit `of_input_value()` nach `of_show` auslesen. Alles in einem Aufruf: `of_prompt`
`is_input_label` | string | `""` | Beschriftung über dem Feld (`""` = keine). Erfordert `ib_input`
`is_input_value` | string | `""` | Anfangsinhalt des Feldes. Er ist beim Öffnen ausgewählt: Tippen ersetzt ihn, wie in jedem Umbenennen-Dialog
`is_input_placeholder` | string | `""` | Hinweis, solange das Feld leer ist. Es ist kein Wert: Tippt der Benutzer nichts, wird nichts zurückgegeben
`ib_input_password` | boolean | `false` | Verbirgt die eingegebenen Zeichen
`ib_input_required` | boolean | `false` | Die Standard-Schaltfläche bleibt deaktiviert, solange das Feld leer ist. Absenden zu lassen, um danach zurechtgewiesen zu werden, hilft niemandem; die Abbrechen-Schaltfläche bleibt erreichbar
`ib_buttons_reverse` | boolean | `false` | Reihenfolge der Schaltflächen: `false` = von links nach rechts in der Reihenfolge des Hinzufügens; `true` = umgekehrt
`is_position` | string | `POSITION_OWNER` | Zentrierung: `POSITION_OWNER` (auf dem aufrufenden Fenster) oder `POSITION_SCREEN` (auf dem Bildschirm)
`il_min_width` | long | `0` | Mindestbreite in Pixeln (`0` = automatisch)
`il_max_width` | long | `0` | Maximalbreite in Pixeln (`0` = automatisch): Der Text bricht innerhalb dieser Grenze um
`il_max_height` | long | `0` | Maximalhöhe in Pixeln (`0` = automatisch): Darüber hinaus wird der Meldungstext gescrollt, statt das Fenster zu vergrößern

### Konstanten #

Konstante | Wert | Verwendung
--- | --- | ---
`ICON_INFORMATION` | `"information"` | Neutrale Information
`ICON_WARNING` | `"warning"` | Warnung, riskante Aktion
`ICON_ERROR` | `"error"` | Fehlschlag, Fehler
`ICON_QUESTION` | `"question"` | Geschlossene Frage
`ICON_SUCCESS` | `"success"` | Bestätigung eines Erfolgs
`ICON_NONE` | `"none"` | Kein Symbol
`POSITION_OWNER` | `"owner"` | Auf dem aufrufenden Fenster zentriert
`POSITION_SCREEN` | `"screen"` | Auf dem Bildschirm zentriert

## Methoden #

Methode | Zweck
--- | ---
`of_add_button (string as_texte)` → long | Fügt eine einfache Schaltfläche hinzu. Liefert ihren Index ab 1
`of_add_button (string as_texte, boolean ab_defaut, boolean ab_annulation)` → long | Dasselbe, wobei die Schaltfläche als Standard (Eingabetaste) und/oder als Abbrechen (Esc) gekennzeichnet wird
`of_add_button (string as_texte, string as_icone, boolean ab_defaut, boolean ab_annulation)` → long | Dasselbe, mit einem Symbol auf der Schaltfläche
`of_add_button_timed (string as_texte, boolean ab_defaut, boolean ab_annulation, long al_secondes_actif, long al_secondes_clic)` → long | Schaltfläche mit Countdown: bleibt `al_secondes_actif` Sekunden lang deaktiviert (mit sichtbarem Zähler) und klickt sich dann selbst nach `al_secondes_clic` Sekunden (`0` = Zeitgeber inaktiv)
`of_show (long al_hwnd)` → long | Zeigt das modale Dialogfeld und liefert den Index der angeklickten Schaltfläche (`0` = Schließen über Esc oder das Kreuz ohne Abbrechen-Schaltfläche)
`of_checked ( )` → boolean | Zustand des Kontrollkästchens zum Zeitpunkt des letzten `of_show`
`of_input_value ( )` → string | Beim letzten `of_show` eingegebener Text (leer, wenn `ib_input` aus war)
`of_action ( )` → string | Id der im Meldungstext angeklickten `[action=id]`-Zone, sonst eine leere Zeichenkette. Eine solche Zone ist eine im Satz selbst angebotene Wahl: sie schließt den Dialog und `of_show` liefert `0`. Eine `[hyperlink=url]`-Zone dagegen öffnet im Browser und lässt den Dialog stehen — der Aufrufer steckt in `of_show` fest, ein Link kann also keine Antwort sein
`of_info (long al_hwnd, string as_title, string as_message)` → long | Dialog in einer Zeile, so wie `MessageBox()` einer ist: Informationssymbol und eine einzige OK-Schaltfläche, liefert `1`. Die Beschriftungen stammen aus den Übersetzungen der Bibliothek (6 Sprachen), statt in jeder Anwendung geschrieben zu werden — genau dafür gibt es diese Kurzformen
`of_warning (long al_hwnd, string as_title, string as_message)` → long | Warnsymbol, eine OK-Schaltfläche. Liefert `1`
`of_error (long al_hwnd, string as_title, string as_message)` → long | Fehlersymbol, eine OK-Schaltfläche. Liefert `1`
`of_success (long al_hwnd, string as_title, string as_message)` → long | Erfolgssymbol, eine OK-Schaltfläche. Liefert `1`
`of_confirm (long al_hwnd, string as_title, string as_message)` → long | Frage + OK / Abbrechen. Liefert `1` = OK, `2` = Abbrechen, `0` = geschlossen
`of_yes_no (long al_hwnd, string as_title, string as_message)` → long | Frage + Ja / Nein. Liefert `1` = Ja, `2` = Nein, `0` = geschlossen
`of_yes_no_cancel (long al_hwnd, string as_title, string as_message)` → long | Frage + Ja / Nein / Abbrechen. Liefert `1`, `2`, `3` oder `0`, wenn geschlossen
`of_prompt (long al_hwnd, string as_title, string as_message, string as_default)` → string | Fragt einen Wert ab und liefert das Eingetippte, oder eine leere Zeichenkette bei Abbruch. Um eine leere Antwort von einem Abbruch zu unterscheiden, nehmen Sie `of_show` + `of_input_value`
`of_reset ( )` | Löscht alle Eigenschaften und die hinzugefügten Schaltflächen: Dieselbe Instanz beginnt wieder bei null

Die Beschriftung einer Schaltfläche akzeptiert die Rich-Text-Auszeichnung und das Mnemonik-Zeichen `&` (`"&Speichern"` unterstreicht das S und aktiviert die Schaltfläche mit `Alt+S`); `&&` zeigt ein wörtliches Und-Zeichen an.

## Die Tastatur #

Taste | Wirkung
--- | ---
Eingabetaste | Löst die als Standard gekennzeichnete Schaltfläche aus
Esc | Löst die als Abbrechen gekennzeichnete Schaltfläche aus; ohne Abbrechen-Schaltfläche wird das Dialogfeld geschlossen und `0` geliefert
Alt + Buchstabe | Löst die Schaltfläche aus, deren Beschriftung dieses Mnemonik-Zeichen trägt
Tab | Bewegt den Fokus von einer Schaltfläche zur nächsten
Strg + C | Kopiert den Dialog (Titel, Anweisung, Meldung, Schaltflächenbeschriftungen) in die Zwischenablage, wie jeder Windows-Dialog — praktisch, wenn ein Fehler an den Support weitergegeben werden muss

> Beim Öffnen zeigt keine Schaltfläche einen Fokusrahmen: Das ist beabsichtigt und entspricht dem Verhalten moderner Windows-Dialoge. Der Rahmen erscheint erst nach dem ersten Druck auf Tab, also sobald der Benutzer ausdrücklich zur Tastatur wechselt. Eingabetaste und Esc sind von der ersten Sekunde an aktiv, auch ohne sichtbaren Fokus.

## Beispiele #

### Geschlossene Frage mit Standardschaltfläche #

    n_pbt_messagebox lnv_mb
    long ll_reponse

    lnv_mb = create n_pbt_messagebox

    lnv_mb.is_title   = "Änderungen speichern"
    lnv_mb.is_icon    = lnv_mb.ICON_QUESTION
    lnv_mb.is_message = "Der Ordner wurde geändert. Möchten Sie vor dem Schließen speichern ?"

    lnv_mb.of_add_button(/*text*/ "&Speichern",     /*standard*/ true,  /*abbrechen*/ false)  // 1
    lnv_mb.of_add_button(/*text*/ "&Nicht speichern", /*standard*/ false, /*abbrechen*/ false) // 2
    lnv_mb.of_add_button(/*text*/ "Abbrechen",          /*standard*/ false, /*abbrechen*/ true)   // 3

    ll_reponse = lnv_mb.of_show(/*hwnd*/ Handle(this))
    destroy lnv_mb

    choose case ll_reponse
        case 1 ; of_enregistrer() ; Close(parent)
        case 2 ; Close(parent)
        case else ; // 3 oder 0 : nicht schliessen
    end choose

### Formatierte Meldung und Symbol #

    lnv_mb.is_title   = "Import abgeschlossen"
    lnv_mb.is_icon    = lnv_mb.ICON_SUCCESS
    lnv_mb.is_message = "[b]1 240 Zeilen[/b] übernommen.[br][br]" &
                      + "[accent]18 Duplikate[/accent] wurden übersprungen."

    lnv_mb.of_add_button(/*text*/ "OK", /*standard*/ true, /*abbrechen*/ false)
    lnv_mb.of_show(/*hwnd*/ Handle(this))

### Kontrollkästchen „nicht mehr nachfragen" #

    n_pbt_messagebox lnv_mb

    lnv_mb = create n_pbt_messagebox

    lnv_mb.is_title    = "Löschen"
    lnv_mb.is_icon     = lnv_mb.ICON_WARNING
    lnv_mb.is_message  = "Die ausgewählten Zeilen löschen ? Diese Aktion kann nicht rückgängig gemacht werden."
    lnv_mb.is_checkbox = "Nicht mehr nachfragen"
    lnv_mb.ib_checked  = false

    lnv_mb.of_add_button(/*text*/ "Löschen", /*standard*/ true,  /*abbrechen*/ false)
    lnv_mb.of_add_button(/*text*/ "Abbrechen",   /*standard*/ false, /*abbrechen*/ true)

    if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then
        of_supprimer()
        // Die Wahl des Benutzers merken
        ib_confirmer_suppression = not lnv_mb.of_checked()
    end if

    destroy lnv_mb

### Schaltfläche mit Countdown #

    lnv_mb.is_title   = "Neustart"
    lnv_mb.is_icon    = lnv_mb.ICON_INFORMATION
    lnv_mb.is_message = "Die Anwendung wird neu gestartet, um das Update anzuwenden."

    // "Weiter" bleibt 3 Sekunden lang grau (ein Zaehler wird angezeigt)
    lnv_mb.of_add_button_timed(/*text*/ "Weiter", /*standard*/ true, /*abbrechen*/ false, &
                               /*aktiv_sekunden*/ 3, /*klick_sekunden*/ 0)

    // "Spaeter" klickt sich nach 10 Sekunden von selbst
    lnv_mb.of_add_button_timed(/*text*/ "Später", /*standard*/ false, /*abbrechen*/ true, &
                               /*aktiv_sekunden*/ 0, /*klick_sekunden*/ 10)

    lnv_mb.of_show(/*hwnd*/ Handle(this))

### Lange Meldung: die Größe begrenzen #

    // Ein umfangreicher Text : das Dialogfeld ist gedeckelt und der Text scrollt
    lnv_mb.is_title      = "Versionshinweise"
    lnv_mb.is_message    = ls_notes
    lnv_mb.il_max_width  = 480
    lnv_mb.il_max_height = 320

    lnv_mb.of_add_button(/*text*/ "Schließen", /*standard*/ true, /*abbrechen*/ true)
    lnv_mb.of_show(/*hwnd*/ Handle(this))

### Eine Instanz wiederverwenden #

    // Eine Fensterinstanz, mehrere Dialoge : of_reset zwischen jedem Aufruf
    inv_mb.of_reset()      // loescht die Eigenschaften UND die vorherigen Schaltflaechen

    inv_mb.is_title   = "Zweiter Dialog"
    inv_mb.is_message = "Jedes of_reset beginnt wieder mit einem leeren Dialogfeld."
    inv_mb.of_add_button(/*text*/ "OK", /*standard*/ true, /*abbrechen*/ false)
    inv_mb.of_show(/*hwnd*/ Handle(this))

## Best Practices #

- Rufen Sie immer `of_reset()` auf, bevor Sie eine wiederverwendete Instanz neu konfigurieren: Andernfalls werden die Schaltflächen des vorherigen Dialogs zu den neuen hinzugefügt.
- Kennzeichnen Sie grundsätzlich eine Standard-Schaltfläche und eine Abbrechen-Schaltfläche: Wer die Tastatur benutzt, erwartet Eingabetaste und Esc.
- Prüfen Sie den Rückgabewert `0`: Er bedeutet, dass das Dialogfeld ohne Auswahl geschlossen wurde (Kreuz oder Esc). Behandeln Sie ihn wie ein Abbrechen.
- Übergeben Sie `Handle(this)` (oder `Handle(parent)`) als aufrufendes Fenster: Das Dialogfeld zentriert sich darauf und die Modalität bezieht sich auf das richtige Fenster.
- Reservieren Sie Rot und `ICON_ERROR` für echte Fehler; eine gewöhnliche Bestätigung verdient `ICON_QUESTION`.
- Für eine Information, die keinerlei Antwort erfordert, ziehen Sie eine nicht blockierende Benachrichtigung vor: siehe toaster.

← Komponentenreferenz · Inhalt des Handbuchs