6. Übergreifende Funktionen #
← Sprache und RTL · Inhalt · FAQ →
Dieses Kapitel bündelt die Dienste, die unabhängig von der Komponente verfügbar sind: Tooltips, Hosting von PowerBuilder-Steuerelementen, Drag & Drop aus dem Explorer, Tastaturfokus, Bildexport und die nicht visuellen Hilfsobjekte.
6.1 Einfache und erweiterte Tooltips #
Tooltip der Komponente #
uo_button.is_tooltip = "Die Akte speichern (Strg+S)"
Der Text nimmt die Rich-Text-Auszeichnung an: [b], [br], [color=…], [picture=…]…
Rich-Tooltip (Titel + Text + Bild) #
Für eine kontextbezogene Hilfe im Stil des Office-Menübands:
uo_button.is_super_tooltip_title = "Speichern"
uo_button.is_super_tooltip_text = "Schreibt die Änderungen auf den Server." &
+ "[br][br][size-=15]Tastenkürzel: Strg+S[/size-=15]"
uo_button.is_super_tooltip_image = "img\help_save.png"
Die drei Eigenschaften sind voneinander unabhängig: ein Titel allein oder ein Titel mit Text ohne Bild sind gültig. Sobald eine Eigenschaft is_super_tooltip_* gesetzt ist, hat sie Vorrang vor is_tooltip.
Tooltip eines Items #
Jede Item-Klasse (n_pbt_item und ihre Nachfahren) trägt dieselben vier Eigenschaften:
uo_toolbar.of_item(/*keys*/ "main/save").is_tooltip = "Speichern"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_title = "Kunden"
uo_tab.of_page(/*key*/ "clients").is_super_tooltip_text = "128 Datensätze, letzte Synchronisierung um 09:12"
Verhalten #
- Der Tooltip ist ein natives, dem Design folgendes Fenster, in allen Komponenten identisch (er wird nicht durch die Grenzen des Webviews eingeschränkt).
- Er erscheint nicht, wenn Ihre Anwendung nicht den Fokus hat: Mit der Maus über ein Fenster im Hintergrund zu fahren, löst nichts aus.
- Er verschwindet, sobald Sie zu einer anderen Anwendung wechseln, und spätestens nach 10 Sekunden.
of_reset()entfernt die Tooltips, die auf der Instanz und auf ihren Items gesetzt wurden.
6.2 Echte PowerBuilder-Steuerelemente hosten #
Die Container-Komponenten zeigen an der Stelle Ihrer Masken kein HTML an: Sie nehmen echte PowerBuilder-Steuerelemente auf (Userobjects, DataWindows, Steuerelementgruppen), die als untergeordnete Win32-Fenster umgehängt werden. Ihre vorhandenen Masken werden unverändert weiterverwendet.
// Registerkarten: jede Seite ist ein PB-Userobject
uo_tab.of_add_page(/*key*/ "clients", /*title*/ "Kunden", /*page*/ uo_page_clients)
uo_tab.of_add_page(/*key*/ "invoices", /*title*/ "Rechnungen", /*page*/ uo_page_invoices, /*closable*/ true)
// Andockbare Panels: genauso
uo_dock.is_main = "doc" // zentraler Bereich
uo_dock.of_add_panel(/*key*/ "doc", /*position*/ uo_dock.POSITION_STACK, /*relative_to*/ "", /*size*/ 0, /*title*/ "Dokument", /*content*/ uo_editor)
uo_dock.of_add_panel(/*key*/ "explorer", /*position*/ uo_dock.POSITION_START, /*relative_to*/ "", /*size*/ 240, /*title*/ "Explorer", /*content*/ uo_tree)
uo_dock.of_add_panel(/*key*/ "props", /*position*/ uo_dock.POSITION_END, /*relative_to*/ "", /*size*/ 260, /*title*/ "Eigenschaften", /*content*/ uo_props)
Was Ihnen abgenommen wird:
- die Positionierung und die Größenanpassung des gehosteten Steuerelements, wenn sich die Größe der Registerkarte oder des Panels ändert;
- das Anzeigen / Ausblenden beim Wechsel der aktiven Registerkarte oder des aktiven Panels;
- die schwebenden, angedockten oder automatisch ausgeblendeten Panels (dockcontainer);
- die saubere Zerstörung beim Schließen des Fensters.
⚠️ Ein gehostetes Steuerelement ist ein natives Fenster: Es wird über der Web-Ebene gezeichnet. Das ist so gewollt (Ihr DataWindow bleibt scharf und schnell), bedeutet aber, dass kein Web-Effekt — Schatten, Transparenz, Animation — darüber gelegt werden kann.
6.3 Dateien aus dem Windows-Explorer entgegennehmen #
Eine Komponente kann zum Ablageziel für Dateien werden, die aus dem Explorer gezogen werden. Die Bibliothek installiert ein natives Ablageziel: Sie erhalten die vollständigen Pfade, was eine HTML-Ablage nicht ermöglicht.
uo_editor.ib_allow_drop = true
// Event ue_drop_files von uo_editor: (string as_files[])
// Local variables
long ll_i
// Jede abgelegte Datei oeffnen
for ll_i = 1 to UpperBound(as_files)
of_open_file(as_files[ll_i])
next
| Event | Ausgelöst wenn |
|---|---|
ue_drag_enter ( ) | Ein Dateiziehvorgang tritt in die Komponente ein |
ue_drag_leave ( ) | Er verlässt sie ohne Ablage |
ue_drop_files (string as_files[]) | Die Dateien werden abgelegt — vollständige Pfade |
Die Komponente liefert die visuelle Rückmeldung beim Überfahren selbst (Hervorhebung der Ablagezone). Veröffentlicht von den Komponenten, bei denen eine Ablage sinnvoll ist: statictext, codeeditor.
6.4 Tastatur und Fokus #
Eine PBToolboxAI-Komponente nimmt an der Tastaturnavigation Ihres Fensters teil wie ein natives Steuerelement:
- die Tabulatortaste erreicht sie in der Tabulatorreihenfolge des Fensters;
- die Tasten (Pfeile, Eingabe, Escape, Eingaben) werden von der Komponente verarbeitet, die den Fokus hat;
- die Fenster-Tastenkürzel (Eingabe = Standardschaltfläche, Escape = Abbrechen) funktionieren weiterhin, auch wenn der Fokus in einer Komponente liegt.
Eine Taste, die die Komponente selbst verarbeitet, bleibt bei ihr: Enter auf einem Element, das sie als Schaltfläche zeichnet (ein Schritt, ein Segment), aktiviert es — und drückt nicht zusätzlich die Standardschaltfläche; Escape, das ein Ziehen abbricht oder einen Modus verlässt, schließt das Fenster nicht. Ein Tastendruck hat nie zwei Wirkungen. Ein AltGr-Tastendruck, der ein Zeichen erzeugt (das Euro-Zeichen einer französischen Tastatur), ist Eingabe, nie eine Tastenkombination.
Um dem Inhalt einer Komponente ausdrücklich den Fokus zu geben (zum Beispiel nach dem Öffnen eines Suchbereichs):
uo_editor.of_focus_webview()
6.5 Die Darstellung als Bild exportieren #
Zur Erinnerung aus der gemeinsamen Basis: Jede Komponente lässt sich so exportieren, wie sie angezeigt wird.
uo_tiles.of_save_as_png(/*path*/ "C:\temp\accueil.png")
uo_tiles.of_save_as_jpg(/*path*/ "C:\temp\accueil.jpg")
Nützlich, um eine Maske an eine E-Mail anzuhängen, einen Bericht zu versorgen oder einen Anwenderzwischenfall zu dokumentieren.
6.6 Dialogfelder und Benachrichtigungen #
Zwei Dienste, für die kein Steuerelement im Fenster platziert werden muss:
// Local variables
n_pbt_messagebox lnv_mb
// Modales Dialogfeld im Design (synchrone Rueckgabe)
lnv_mb = create n_pbt_messagebox
lnv_mb.is_title = "Löschen"
lnv_mb.is_message = "[b]12 Akten[/b] endgültig löschen?"
lnv_mb.is_icon = lnv_mb.ICON_QUESTION
lnv_mb.of_add_button(/*text*/ "Löschen", /*default*/ false, /*cancel*/ false)
lnv_mb.of_add_button(/*text*/ "Abbrechen", /*default*/ true, /*cancel*/ true)
if lnv_mb.of_show(/*hwnd*/ Handle(this)) = 1 then of_delete()
destroy lnv_mb
// Local variables
n_pbt_toaster lnv_toast
// Nicht blockierende "Toast"-Benachrichtigung in einer Bildschirmecke
lnv_toast = create n_pbt_toaster
lnv_toast.is_title = "Import abgeschlossen"
lnv_toast.is_text = "1.240 Zeilen übernommen."
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS
lnv_toast.of_show()
destroy lnv_toast
Vollständige Einzelheiten: messagebox und toaster.
6.7 Nicht visuelle Hilfsobjekte #
In derselben PBL ausgeliefert, ohne Webview und ohne Darstellung: Es sind einfache Hüllen um die DLL. Erzeugen Sie sie, verwenden Sie sie, zerstören Sie sie.
Base64, Hashes, Bezeichner — n_pbt_crypto #
Base64 (Text oder Datei), SHA-Hashes und eindeutige Bezeichner leben in der Komponente crypto: of_base64_encode, of_base64_encode_file, of_sha256, of_hash_file, of_uuid… Eine Seite für alles, was rechnet, ohne etwas anzuzeigen.
Reguläre Ausdrücke — u_pbt_regex #
ECMAScript-Syntax, die es in PowerScript nicht gibt.
Ohne einen Schlüssel, der es abdeckt, läuft u_pbt_regex im Demomodus: Der durchsuchte Text umfasst höchstens 2048 Zeichen; darüber schlägt der Aufruf fehl, und is_last_error nennt den Grund. Damit der Schlüssel Ihrer Anwendung greift, setzen Sie ipo_owner auf das Objekt, das es verwendet (lnv_re.ipo_owner = this), wie bei crypto.
// Local variables
u_pbt_regex lnv_re
string ls_found[], ls_email, ls_date, ls_input, ls_text, ls_year, ls_clean
long ll_nb
// Ein Objekt fuer alle Suchen : erzeugen, benutzen, zerstoeren
lnv_re = create u_pbt_regex
if lnv_re.of_is_match(/*pattern*/ "^[\w.]+@[\w.]+\.\w{2,}$", /*input*/ ls_email) then …
ls_year = lnv_re.of_match(/*pattern*/ "(\d{4})-(\d{2})-(\d{2})", /*input*/ ls_date, /*group*/ 1)
ls_clean = lnv_re.of_replace(/*pattern*/ "\s+", /*input*/ ls_input, /*replacement*/ " ")
ll_nb = lnv_re.of_match_all(/*pattern*/ "[A-Z]{2}\d{6}", /*input*/ ls_text, /*matches*/ ls_found)
destroy lnv_re
| Methode | Zweck |
|---|---|
of_is_match (Muster, Text [, ab_ignore_case | al_flags]) | Passt der Text? |
of_match (Muster, Text, ai_groupe [, al_flags]) | Erste Fundstelle (0 = alles, 1.. = einfangende Gruppe) |
of_match_all (Muster, Text [, ai_groupe, al_flags], ref as_res[]) | Alle Fundstellen; gibt die Anzahl zurück |
of_replace (Muster, Text, Ersetzung) | Ersetzt alle Vorkommen ($1… erlaubt) |
Kombinierbare Optionen: FLAG_IGNORE_CASE (1), FLAG_SINGLELINE (2, der . überschreitet Zeilenumbrüche).
Ein Muster, das die Engine ablehnt, oder ein Text, an dem sie aufgibt — eine wiederholte Alternative wie (a|b)* über einen langen Text, verschachtelte Wiederholungen wie (a*)* —, ist kein „kein Treffer“: of_is_match liefert false, of_match eine leere Zeichenkette, of_match_all 0 und of_replace den unveränderten Text, und is_last_error nennt den Grund (leer, wenn wirklich nichts da ist). [ab]* statt (a|b)* schreiben. of_match_all liefert einen long: ein großer Text enthält mehr als 32 767 Treffer. Ein wiederverwendetes Muster wird nur einmal kompiliert.
ZIP-Archive — u_pbt_zip #
// Local variables
u_pbt_zip lnv_zip
// Einen Ordner komprimieren, dann das Archiv anderswo entpacken
lnv_zip = create u_pbt_zip
lnv_zip.of_compress(/*zip*/ "C:\temp\livraison.zip", /*src*/ "C:\appli\export") // Datei ODER Ordner
lnv_zip.of_extract(/*zip*/ "C:\temp\livraison.zip", /*dest*/ "C:\appli\import") // Ordner wird angelegt, falls er fehlt
destroy lnv_zip
Beide Methoden geben einen boolean zurück.
Eine Methode, die false liefert, nennt den Grund in is_last_error: ein abgelehnter Pfad, das Archivwerkzeug von Windows (tar.exe) fehlt oder scheitert. Das Fenster zeichnet sich während der Arbeit weiter neu (die Sanduhr erscheint nach einer Viertelsekunde), und ein Archiv, das zu lange dauert — zwei Minuten plus die Zeit, die Quelle mit 2 MB/s zu lesen (das Archiv mit 512 KB/s beim Entpacken) —, wird angehalten: das unvollständige Archiv wird gelöscht, nach einem Fehlschlag erscheint nichts.
Ohne einen Schlüssel, der es abdeckt, läuft u_pbt_zip im Demomodus: Was es komprimiert (eine Datei oder ein Ordner, insgesamt) und das Archiv, das es entpackt, umfassen höchstens 2048 Byte; darüber gibt die Methode false zurück, und is_last_error nennt den Grund. Setzen Sie ipo_owner auf das Objekt, das es verwendet (lnv_zip.ipo_owner = this), damit der Schlüssel Ihrer Anwendung greift.
6.8 Informationen über die Bibliothek #
// Local variables
long ll_version
// Version der DLL: ein long, Hauptversion x 10000 + Nebenversion x 100 + Korrektur
ll_version = PBT_GetVersion() // 50000 = 5.00.00
| Globale Funktion | Zweck |
|---|---|
PBT_GetVersion ( ) → long | Version der Bibliothek: 50000 = 5.00.00 (Hauptversion × 10000 + Nebenversion × 100 + Korrektur) |
PBT_CheckRuntime (ref string, long) | Version der installierten WebView2-Laufzeitumgebung (≤ 0 = nicht vorhanden) |
PBT_GetLastErrorMessage (ref string, long) | Letzte Fehlermeldung des Prozesses |
PBT_LicenseStatus ( ) | Zustand der Lizenz — siehe Lizenz |
6.9 Drucken #
Jede Komponente kann sich selbst drucken, so wie sie angezeigt wird, ohne zwischengeschaltetes DataWindow.
// Lautlos: ein PDF auf der Platte, nichts zum Anklicken
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf")
// Querformat, fuer ein breites Raster
uo_grid.of_print_to_pdf(/*path*/ "C:\etats\ventes.pdf", /*landscape*/ true)
// Mit Dialog: der Benutzer waehlt seinen Drucker und sieht die Vorschau
uo_grid.of_print()
// Direkt der Systemdruckdialog
uo_grid.of_print(/*system_dialog*/ /*dialogue systeme*/ true)
| Methode | Zweck |
|---|---|
of_print_to_pdf (string as_path) · of_print_to_pdf (string, boolean ab_landscape) | Schreibt ein PDF, ohne etwas anzuzeigen. Kehrt erst zurück, wenn die Datei geschrieben ist (0 = erledigt) |
of_print ( ) · of_print (boolean ab_system_dialog) | Öffnet den Druckdialog. Kehrt zurück, sobald der Dialog steht: was der Benutzer damit macht, ist seine Sache |
⚠️ Gedruckt wird, was GERENDERT ist. Ein virtualisiertes Raster druckt nur die Zeilen, die es hält: für einen vollständigen Bericht zuerst auf ein Layout wechseln, das alle zeigt (Seitennummerierung), oder die Daten statt der Darstellung exportieren.
Der Rückgabewert -6 bedeutet, dass die WebView2-Runtime zum Drucken zu alt ist (1.0.1108 für das PDF, 1.0.1587 für den Dialog). Alles Übrige folgt den gemeinsamen Rückgabewerten.