PBToolboxAI v5 ← Site

toaster — n_pbt_toaster #

← Komponentenreferenz · Inhalt des Handbuchs

„Toast“-Benachrichtigungen in einer Bildschirmecke: eine Meldung, die erscheint, informiert und wieder verschwindet, ohne den Benutzer zu blockieren oder seine Eingabe zu unterbrechen.

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


Auf einen Blick #

Objektn_pbt_toaster — nicht visuell: nichts, was im Fenster platziert werden müsste
WofürEine erfolgreiche Aktion bestätigen, eine Warnung oder einen Fehler melden, ohne die laufende Arbeit anzuhalten
RückgabeNicht blockierend: of_show() gibt sofort die Kontrolle zurück; die Reaktionen des Benutzers kommen über Events zurück

Der Toast ist ein losgelöstes Fenster: Er schwebt über Ihrer Anwendung (oder über dem gesamten Bildschirm) und schließt sich von selbst.

// Lokale Variablen
n_pbt_toaster lnv_toast

// Den Notifier erzeugen
lnv_toast = create n_pbt_toaster

// ... Konfiguration ...

// Am Ende zerstoeren
destroy lnv_toast

Schnellstart #

// Lokale Variablen
n_pbt_toaster lnv_toast

// Den Notifier erzeugen
lnv_toast = create n_pbt_toaster

// Konfigurieren, dann anzeigen
lnv_toast.ipo_owner = this                       // Fenster, an dem sich der Toast festmacht
lnv_toast.is_kind   = lnv_toast.KIND_SUCCESS     // gruenes Symbol + Erfolgsstreifen
lnv_toast.is_text   = "Ihre Änderungen wurden [b]gespeichert[/b]."
lnv_toast.of_show()

// Am Ende zerstoeren
destroy lnv_toast

Alles wird über Eigenschaften konfiguriert, danach lässt of_show() — das kein Argument entgegennimmt — die Benachrichtigung erscheinen. Der obige Toaster wird sofort zerstört: Nichts kommt zurück, was für eine schlichte Bestätigung passt. Um die Rückmeldungen eines Toasts zu empfangen, siehe „Wo die Events geschrieben werden“.


Eigenschaften #

Vor of_show zu setzen.

EigenschaftTypStandardZweck
is_textstring""Rumpf der Meldung. Akzeptiert die Rich-Text-Auszeichnung
is_kindstringKIND_INFOStufe: steuert das Symbol und die Farbe des Streifens. Konstanten KIND_*
is_positionstringPOSITION_BOTTOM_RIGHTVerankerungsecke. Konstanten POSITION_*
ib_screenbooleanfalsefalse = an der Ecke des Fensters verankert; true = an der Ecke des Bildschirms verankert, über allem schwebend. Am Bildschirm verankerte Toasts stapeln sich je Monitor: Zwei Fenster, die je einen zeigen, überdecken sich nicht mehr
il_timeoutlongTIMEOUT_AUTOAnzeigedauer in Millisekunden bis zum automatischen Schließen. TIMEOUT_AUTO (-1, die Vorgabe) bedeutet 4 s für eine Information, aber bis zum Klick für einen Fehler — ein Fehler, der nach vier Sekunden verschwindet, ist ein verlorener Fehler. TIMEOUT_UNTIL_CLICKED (0) macht jeden Toast dauerhaft; eine ausdrückliche Dauer wird unverändert übernommen. Solange der Zeiger auf einem Toast ruht, ist sein Countdown angehalten, und ein Balken zeigt die verbleibende Zeit
is_titlestring""Fett gesetzte Titelzeile über der Meldung (erweiterter Toast)
is_imagestring""Illustrationsbild links, anstelle des Stufensymbols (akzeptierte Formen: Pfad, mono:, DLL-Ressource)
is_keystring""Schlüssel des Toasts: Denselben Schlüssel erneut anzuzeigen aktualisiert den bereits sichtbaren Toast, statt einen zweiten zu öffnen. Genau das braucht eine Fortschrittsmeldung („Export 3/10“ dann „4/10“): Schließen und neu öffnen würde die Animation neu starten und den Stapel durcheinanderbringen. Für einen gewöhnlichen Toast leer lassen. Der Schlüssel gehört dem Toaster: Ein anderer Toaster, der denselben Schlüssel zeigt, öffnet seinen eigenen Toast. Eine Aktualisierung übernimmt auch die neue Ecke, die Bildschirmverankerung und das Ankerfenster. Der Schlüssel kommt als as_key in den Events ue_toast_* zurück
is_soundstringSOUND_AUTOSystemklang des Toasts, gespielt, wenn er angefordert wird. SOUND_AUTO (der Standard): ein Fehler oder eine Warnung klingt, eine Information oder ein Erfolg bleibt stumm; SOUND_ALWAYS: jede Art; SOUND_NEVER: stumm
il_max_visiblelong0Höchstzahl gleichzeitig sichtbarer Toasts in derselben Ecke (1 bis 20). Darüber hinaus warten die nächsten und erscheinen, sobald Platz frei wird: eine Verarbeitungsschleife mit einem Toast je Zeile stapelte die Fenster sonst aus dem Bildschirm hinaus. Diese Obergrenze gilt für alle Toaster der Anwendung gemeinsam: der zuletzt gesetzte Wert gilt; 0 (der Standard) lässt sie unverändert — 5, solange niemand sie gesetzt hat. Ein Stapel ist dieselbe Ecke desselben Fensters — oder, für einen am Bildschirm verankerten Toast oder einen ohne ipo_owner, dieselbe Ecke desselben Monitors, gleich welches Fenster ihn gezeigt hat. Ein Toast, der nicht mehr auf den Bildschirm passen würde, wartet ebenfalls, und ein Toast ist nie höher als der Bildschirm: sein Text scrollt
ipo_ownerpowerobject—Das visuelle Objekt, an dem der Toast festgemacht ist (die Ecke des Clientbereichs seines Fensters dient als Bezugspunkt: unter der Titelleiste; in einem MDI-Rahmen der Clientbereich des Rahmens, Symbolleisten und MicroHelp bleiben frei). Es ist die einzige Verdrahtung: die Events des Toasts werden am Toaster selbst ausgelöst. Solange dieses Fenster minimiert ist, wartet der Toast: Er wird nicht angezeigt, und sein Countdown läuft erst, wenn das Fenster zurückkommt
ipo_receiverpowerobject—Optional, veraltet: gesetzt, erhält sein Fenster bei jedem Toast-Event ein pbm_custom02 (für älteren Code, der es verdrahtet hatte). Lassen Sie es leer — der Toaster liefert seine Events selbst, an sich selbst

Konstanten #

KonstanteWertVerwendung
KIND_INFO"info"Neutrale Information
KIND_SUCCESS"success"Erfolgreiche Operation
KIND_WARNING"warning"Warnung
KIND_ERROR"error"Fehlschlag
POSITION_TOP_LEFT"top-left"Obere linke Ecke
POSITION_TOP_CENTER"top-center"Oben, zentriert
POSITION_TOP_RIGHT"top-right"Obere rechte Ecke
POSITION_BOTTOM_LEFT"bottom-left"Untere linke Ecke
POSITION_BOTTOM_CENTER"bottom-center"Unten, zentriert
POSITION_BOTTOM_RIGHT"bottom-right"Untere rechte Ecke (Standard)
SOUND_AUTO"auto"Klang nur bei Fehler oder Warnung (Standard)
SOUND_ALWAYS"always"Klang für jede Art
SOUND_NEVER"never"Nie ein Klang
REASON_TIMEOUT"timeout"ue_toast_dismissed: sein Countdown ist abgelaufen
REASON_USER"user"ue_toast_dismissed: der Benutzer hat sein Kreuz angeklickt
REASON_CODE"code"ue_toast_dismissed: of_close oder of_close_all hat ihn geschlossen
REASON_OWNER_CLOSED"owner"ue_toast_dismissed: das Fenster, an dem er verankert war, wurde geschlossen

Warum hier LEFT/RIGHT und anderswo START/END? Der Toast ist ein Systemfenster, das in Bildschirmpixeln platziert wird, kein Inhalt, der einer Leserichtung folgt: Eine Bildschirmecke hat keinen „Anfang“. Diese Konstanten bleiben daher bewusst physisch und wechseln nicht die Seite, wenn die Anwendung auf Schreibrichtung von rechts nach links umschaltet. Siehe Sprache und RTL.


Methoden #

MethodeZweck
of_show ( ) → longZeigt die aus den Eigenschaften aufgebaute Benachrichtigung an. Gibt den Bezeichner des Toasts zurück (> 0) — auch ein Toast, der auf seinen Platz wartet (il_max_visible), erhält ihn sofort — oder einen negativen Wert im Fehlerfall. Blockiert nicht. -5 (und nichts wird angezeigt) bei einer Einstellung außerhalb ihres Bereichs: ein is_kind, is_position oder is_sound, das keine seiner Konstanten ist, il_max_visible außerhalb von 0 bis 20, il_timeout unter TIMEOUT_AUTO; -4: diesmal nicht angezeigt — die Anzeige-Engine ist noch nicht bereit (erneut versuchen) oder die Warteschlange ist voll; -6: WebView2-Runtime fehlt. of_get_last_error sagt, warum
of_close ( long al_id ) → longSchließt einen Toast dieses Toasters, bestimmt durch den von of_show gelieferten Bezeichner — angezeigt, noch nicht gezeichnet oder noch wartend. Jeder so geschlossene Toast löst ue_toast_dismissed mit REASON_CODE aus, auch einer, der direkt nach of_show geschlossen wird. Gibt 0 zurück oder -5 (of_get_last_error sagt, warum), wenn die Kennung leer ist, einen bereits verschwundenen oder bereits schließenden Toast bezeichnet, oder einen Toast eines anderen Toasters
of_close_all ( ) → longSchließt alle Toasts dieses Toasters — angezeigt, noch nicht gezeichnet oder wartend — und nichts eines anderen Toasters. Jeder löst ue_toast_dismissed mit REASON_CODE aus. Gibt die Anzahl der geschlossenen Toasts zurück (0, wenn es keinen gab)
of_get_last_error ( ) → stringWarum das letzte of_show oder of_close abgelehnt hat — "", wenn nichts abgelehnt wurde. Nach einem negativen Rückgabewert zu lesen: eine Einstellung außerhalb ihres Bereichs, die Anzeige-Engine noch nicht bereit, ein Toast eines anderen Toasters…
of_reset ( ) → longSetzt alle Inhaltseigenschaften auf ihren Standard zurück und löscht die Schaltflächen (ipo_owner und ipo_receiver bleiben erhalten: Sie sind Verdrahtung, kein Inhalt) Liefert 0, sobald erledigt.
of_process_events ( )Leert die Warteschlange der Rückmeldungen des Toasts und löst die entsprechenden ue_toast_*-Events aus. Die Komponente ruft sie selbst auf, solange ein Toast sichtbar ist: Normalerweise müssen Sie das nicht tun — siehe unten
of_add_button (string as_key, string as_label {, string as_image }) → longFügt eine Aktionsschaltfläche hinzu (höchstens 3). Ein Klick darauf löst ue_toast_action(id, key, action) aus; of_reset leert die Schaltflächen. Eine Beschriftung darf jedes Zeichen enthalten — ein Komma, ein Gleichheitszeichen — ohne zerschnitten zu werden. Liefert 0, oder -5 (nichts wird hinzugefügt) bei leerem Schlüssel, bereits vergebenem Schlüssel, einem Schlüssel mit / oder senkrechtem Strich, oder einer vierten Schaltfläche
of_count ( ) → longLiefert die Anzahl der Aktionsschaltflächen, die die Benachrichtigung trägt
of_keys_at ( long al_index ) → stringDer Schlüssel der Schaltfläche an Position al_index (ab 1), oder "" jenseits beider Enden
of_has ( string as_key ) → booleanWurde unter diesem Schlüssel eine Schaltfläche hinzugefügt? of_add_button lehnt einen bereits vergebenen Schlüssel ab (-5): Vorher zu fragen sagt, warum

Mehrere in derselben Ecke angezeigte Toasts stapeln sich automatisch. Jeder trägt ein Schließkreuz; der von of_show gelieferte Bezeichner erlaubt es, sie in den Events zu unterscheiden und sie aus Ihrem Code heraus zu schließen.

Der Countdown pausiert, solange der Zeiger über dem Toast steht: eine Meldung darf nicht unter den Augen dessen verschwinden, der sie liest. Ein schmaler Balken am unteren Rand zeigt die verbleibende Zeit — und erklärt damit ihr Verschwinden. Ein Klick auf den Rumpf antwortet und schließt.

Eine mit il_timeout = 0 gesetzte Benachrichtigung bleibt auf dem Bildschirm, solange niemand sie schließt: Bewahren Sie ihren Bezeichner auf, um sie entfernen zu können, sobald die angekündigte Aufgabe beendet ist.

// Lokale Variablen
long ll_toast

// Dauerhafte Benachrichtigung : sie bleibt bis of_close sichtbar.
inv_toaster.is_text = "Export läuft..."
inv_toaster.il_timeout = /*ms, 0 = kein automatisches Schliessen*/ 0
ll_toast = inv_toaster.of_show()

// ... lange Verarbeitung ...

// Den Toast nach getaner Arbeit schliessen
inv_toaster.of_close(/*id*/ ll_toast)

Events — der Toast antwortet Ihnen #

Eine Benachrichtigung ist kein bloßes „anzeigen und vergessen“: Sie kann Ihnen mitteilen, dass sie angeklickt wurde, dass eine Aktionsschaltfläche gewählt wurde oder dass sie sich geschlossen hat.

Sie müssen dafür nichts verdrahten: Setzen Sie ipo_owner (das Fenster, an dem der Toast verankert ist) und behandeln Sie die Events. Die Komponente holt sie selbst, solange ein Toast sichtbar ist, und löst sie am Objekt aus — kein Empfänger, kein Timer.

Wo die Events geschrieben werden #

PowerBuilder bietet die Events eines nicht visuellen Objekts nur an zwei Stellen: ein Nachfahre von n_pbt_toaster (seine Events tragen Ihre Skripte) oder ein im Fenster platzierter Toaster wie jedes nicht visuelle Objekt (im Fenstermaler Insert > Object, dann n_pbt_toaster: seine Events werden im Fenster geskriptet). Eine mit create erzeugte n_pbt_toaster-Variable hat kein Skript: Ihre Toasts erscheinen, aber ihre Rückmeldungen erreichen niemanden. Und ein zerstörter Toaster meldet nichts mehr: Seine dauerhaften Toasts und die mit Schaltflächen schließen sich mit ihm, die anderen enden von selbst, stumm. Mit einem Nachfahren n_my_toaster hält das Fenster einen in einer Instanzvariablen inv_toaster:

// open-Event des Fensters : den Toaster einmal erzeugen und verankern
inv_toaster = create n_my_toaster
inv_toaster.ipo_owner = this

1. ipo_owner auf das Fenster setzen, an dem der Toast verankert ist:

// Die Toasts an diesem Fenster verankern
inv_toaster.ipo_owner = this      // das Fenster, an dem der Toast verankert ist

2. Die auf dem Toaster ausgelösten Events behandeln:

EventAusgelöst wenn
ue_toast_clicked (long al_id, string as_key)Der Rumpf des Toasts wird angeklickt (keine Schaltfläche). al_id ist der von of_show gelieferte Bezeichner, as_key der is_key des Toasts (leer ohne Schlüssel)
ue_toast_action (long al_id, string as_key, string as_action)Eine Aktionsschaltfläche wird angeklickt; as_action enthält den an of_add_button übergebenen Schlüssel. al_id ist der von of_show gelieferte Bezeichner, as_key der is_key des Toasts (leer ohne Schlüssel)
ue_toast_dismissed (long al_id, string as_key, string as_reason)Der Toast schließt sich; as_reason sagt, warum: REASON_TIMEOUT (Zeit abgelaufen), REASON_USER (Schließkreuz), REASON_CODE (of_close oder of_close_all, ob der Toast angezeigt, noch nicht gezeichnet oder wartend ist), REASON_OWNER_CLOSED (das Ankerfenster wurde geschlossen). Ein Klick auf den Rumpf löst ue_toast_clicked aus, eine Schaltfläche ue_toast_action. al_id ist der von of_show gelieferte Bezeichner, as_key der is_key des Toasts (leer ohne Schlüssel)

Wenn Sie keine Rückmeldung erwarten — keine Aktionsschaltfläche, kein Klick auf den Rumpf — müssen Sie keines dieser Events behandeln: Die Benachrichtigung erscheint und verschwindet von selbst. Das ist der einfachste Modus, ideal für eine schlichte Bestätigung.


Beispiele #

Die vier Stufen #

// Info : eine neutrale Meldung
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_INFO
inv_toaster.is_text = "Vorgang abgeschlossen."
inv_toaster.of_show()

// Erfolg : es hat geklappt
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Ihre Änderungen wurden [b]gespeichert[/b]."
inv_toaster.of_show()

// Warnung : einen Blick wert
inv_toaster.of_reset()
inv_toaster.is_kind    = inv_toaster.KIND_WARNING
inv_toaster.il_timeout = 5000                        // etwas laenger
inv_toaster.is_text    = "Wenig Speicherplatz auf Laufwerk C:."
inv_toaster.of_show()

// Fehler : es ist fehlgeschlagen ; er bleibt bis zum Klick
inv_toaster.of_reset()
inv_toaster.is_kind    = inv_toaster.KIND_ERROR
inv_toaster.is_text    = "Der Server ist nicht erreichbar."
inv_toaster.of_show()

Die Ecke wählen, im Fenster oder auf dem Bildschirm #

// Verankert an der oberen rechten Ecke des FENSTERS (Standard : folgt der Anwendung)
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen   = false
inv_toaster.is_text     = "An der Fensterecke verankert."
inv_toaster.of_show()
// Losgeloest : an der BILDSCHIRM-Ecke verankert, sichtbar auch wenn das Fenster minimiert ist
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen   = true
inv_toaster.is_text     = "Nachtverarbeitung abgeschlossen."
inv_toaster.of_show()

Erweiterter Toast: Titel, Bild und Dauer #

// Von den Standardeinstellungen ausgehen
inv_toaster.of_reset()

// Ein Titel, ein Text und ein Bild
inv_toaster.is_title    = "Sicherung abgeschlossen"
inv_toaster.is_text     = "1 240 Dateien kopiert nach [b]\\server\backup[/b]."
inv_toaster.is_image    = "mono:img\backup.svg"
inv_toaster.il_timeout  = 8000                    // bleibt 8 Sekunden
inv_toaster.of_show()

Benachrichtigung mit Aktionsschaltflächen #

// open-Event : den Toaster ein fuer alle Mal verankern ; die Rueckmeldung kommt von selbst
inv_toaster.ipo_owner = this
// Zwei Aktionen anbieten ; timeout 0 = der Toast wartet auf die Entscheidung des Benutzers
inv_toaster.of_reset()

// Titel, Text und zwei Schaltflaechen, dann anzeigen
inv_toaster.is_title   = "Update verfügbar"
inv_toaster.is_text    = "Version 2.0 ist zur Installation bereit."
inv_toaster.il_timeout = 0
inv_toaster.of_add_button(/*key*/ "install", /*label*/ "Installieren")
inv_toaster.of_add_button(/*key*/ "later", /*label*/ "Spaeter")
inv_toaster.of_show()
// Event ue_toast_action von inv_toaster : (long al_id, string as_key, string as_action)
choose case as_action
    case "install" ; of_start_update()
    case "later" ; of_remind_later()
end choose

Auf den Klick auf die Meldung reagieren #

// Event ue_toast_clicked von inv_toaster : (long al_id, string as_key)
// Der Benutzer hat den Rumpf des Toasts angeklickt : die betreffende Maske oeffnen
Open(w_import_log)

Wissen, warum ein Toast geschlossen wurde, alle schließen #

// Event ue_toast_dismissed von inv_toaster : (long al_id, string as_key, string as_reason)
// Nur ein vom Benutzer geschlossener Toast heisst nicht jetzt : spaeter erinnern
if as_reason = n_pbt_toaster.REASON_USER then of_remind_later()

// Ein neuer Import beginnt : die Benachrichtigungen des vorigen verschwinden
inv_toaster.of_close_all()

Aus einer langen Verarbeitung heraus benachrichtigen #

// Lokale Variablen
long ll_rows, ll_errors

// Geladene Zeilen und beim Import aufgetretene Fehler
ll_rows = of_rows_loaded()
ll_errors = of_errors_met()

// Ende eines Imports : informieren, ohne die Eingabemaske zu blockieren
inv_toaster.of_reset()

// Art und Text folgen dem Ergebnis
if ll_errors = 0 then
    inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
    inv_toaster.is_text = "Import abgeschlossen : [b]" + String(ll_rows) + " Zeilen[/b] übernommen."
else
    inv_toaster.is_kind    = inv_toaster.KIND_ERROR
    inv_toaster.il_timeout = 0                    // ein Fehler muss gelesen werden
    inv_toaster.is_text    = "Import abgebrochen : " + String(ll_errors) + " Fehler."
end if

// Den Toast anzeigen
inv_toaster.of_show()

Best Practices #


← Komponentenreferenz · Inhalt des Handbuchs