PBToolboxAI v2 ← Site

commandpalette — n_pbt_commandpalette #

← Komponentenreferenz · Inhalt des Leitfadens

Befehlspalette: Der Benutzer drückt ein Tastenkürzel, tippt drei Buchstaben und erreicht jede Aktion Ihrer Anwendung — ohne sie in den Menüs zu suchen.

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


Auf einen Blick #

Objektn_pbt_commandpalette — nicht visuell: nichts im Fenster zu platzieren
Dient zuJede Aktion der Anwendung über die Tastatur erreichbar machen, mit drei Buchstaben
RückgabeNicht blockierend: of_open() kehrt sofort zurück; die Auswahl kommt als Event zurück

Die Palette ist ein eigenes, losgelöstes Fenster: Sie schwebt über Ihrer Anwendung, nimmt den Fokus, solange der Benutzer tippt, und gibt ihn beim Schließen zurück.


Schnellstart #

// Einmalig, beim Start : die Aktionen Ihrer Anwendung
inv_palette.ipo_owner    = this
inv_palette.ipo_receiver = this
inv_palette.of_add_command(/*key*/ "new",  /*label*/ "N", /*group*/ "F")
inv_palette.of_add_command(/*key*/ "open", /*label*/ "O", /*group*/ "F")
inv_palette.of_add_command(/*key*/ "save", /*label*/ "S", /*group*/ "F")
inv_palette.of_register_shortcut()
// event ue_command_selected : (string as_key)
choose case as_key
	case "new";  of_nouveau()
	case "open"; of_ouvrir()
	case "save"; of_enregistrer()
end choose

Die Verdrahtung: der Empfänger #

Ein nicht visuelles Objekt hat kein Fensterhandle: Windows weiß nicht, wem es die Nachrichten der Palette übergeben soll. Genau dafür ist ipo_receiver da — ein visuelles Objekt, etwa Ihr Fenster, das zuhört und abholt.

Drei Zeilen, einmalig, beim Öffnen des Fensters:

inv_palette.ipo_owner    = this   // das Fenster, zu dem die Palette gehoert
inv_palette.ipo_receiver = this   // das die Events empfangen wird
inv_palette.of_register_shortcut()  // die Palette muss auf ihre Taste antworten

Dann, auf dem Empfänger, das Event, das abholt:

// event ue_palette_msg pbm_custom02
inv_palette.of_process_events()

Ohne dieses Abholen öffnet sich die Palette und funktioniert, aber nichts kommt zu Ihnen zurück: weder die Auswahl noch das Öffnen noch das Schließen.


Das Tastenkürzel: die DLL ist es, die es hört #

Das Tastenkürzel, das die Palette öffnet, wird nicht von der Seite abgehört: es wird bei der DLL registriert, die als Einzige die Tasten sieht, während der Fokus auf einem anderen Steuerelement liegt. Genau das ist der Unterschied zwischen einer Palette, die man findet, und einer, die erst antwortet, wenn man sie schon angeklickt hat.

Die DLL hört das Kürzel, öffnet aber von sich aus nichts: Sie meldet es über ue_shortcut, und Sie entscheiden. Eine Palette, die sich über einem modalen Dialog öffnet, hilft niemandem.

// event ue_shortcut : die Taste ist gefallen
if not ib_dialog_open then inv_palette.of_open()

is_shortcut wählt das Kürzel; of_register_shortcut() übergibt es. Rufen Sie es einmal beim Öffnen des Fensters auf — sonst antwortet die Palette erst, nachdem sie schon einmal geöffnet wurde. of_open übergibt es nebenbei erneut, ein später geändertes Kürzel braucht also nichts weiter.

// Das gewohnte Kuerzel, das der Code-Editoren
inv_palette.is_shortcut = inv_palette.SHORTCUT_DEFAULT

// Oder Ihres
inv_palette.is_shortcut = "ctrl+shift+p"

// Oder keines: die Palette oeffnet dann nur ueber of_open()
inv_palette.is_shortcut = inv_palette.SHORTCUT_NONE

Zwei Komponenten, die dasselbe Kürzel verlangen: die mit dem Fokus gewinnt, sonst die zuerst registrierte. Das Tastaturkapitel führt es aus.


Wo die Palette erscheint #

is_position sagt, wo das Fenster landet. Es wird immer in den Bildschirm zurückgeholt: eine Palette, die unter einem Feld am unteren Fensterrand verankert ist, verschwindet nicht hinter der Taskleiste.

KonstanteWohin
POSITION_WINDOW_CENTERAuf ipo_owner zentriert — der Standard, und was das Auge erwartet
POSITION_SCREEN_CENTERAuf dem Bildschirm zentriert, unabhängig vom Fenster
POSITION_ABSOLUTEBei il_x / il_y, in Bildschirmpixeln

PowerBuilder rechnet in PBU: umrechnen, bevor Sie il_x / il_y setzen.

Ihre Höhe richtet sich nach der Anzahl der angezeigten Befehle und schrumpft beim Filtern — ohne dass die obere Ecke wandert, sonst würde das Suchfeld unter den Fingern wegrutschen. Sie ist auf den halben Bildschirm begrenzt: darüber hinaus scrollt die Liste im Innern, und das Suchfeld bleibt oben.

Ein Klick woanders in der Anwendung schließt die Palette, und dieser Klick erreicht sein Ziel trotzdem — wie beim Verlassen eines Menüs. Dafür ist nichts zu tun.


Eigenschaften #

EigenschaftTypStandardRolle
ipo_ownerpowerobject—Das Fenster, zu dem die Palette gehört: es besitzt das Popup-Fenster und verankert es. Vor of_open setzen
ipo_receiverpowerobject—Das visuelle Objekt, das die Events empfängt. Es deklariert event xxx pbm_custom02 und ruft dort of_process_events auf
is_shortcutstring"ctrl+k"Tastenkürzel, das die Palette von überall im Fenster öffnet. Konstanten SHORTCUT_DEFAULT (ctrl+k) und SHORTCUT_NONE (keines). Wirkt bei of_register_shortcut
is_positionstringwindow-centerWo das Fenster landet (POSITION_*-Konstanten)
il_x · il_ylong0Position in Bildschirmpixeln, nur von POSITION_ABSOLUTE gelesen
is_placeholderstring""Grauer Text im Suchfeld, solange nichts getippt wurde
is_recentstring""Nutzungsgedächtnis: die zuletzt gestarteten ids, neueste zuerst, kommagetrennt. Die Palette holt sie nach oben, und die Aktualität entscheidet Gleichstände beim Filtern — sie überstimmt nie die Treffergüte. Nach Gebrauch auslesen und speichern, beim Start zurückgeben. Eine Palette, die jeden Morgen leer beginnt, lernt nichts
il_max_recentlong8Wie viele Einträge der Block « Zuletzt verwendet » hält. Standard 8. 0 schaltet ihn ab: eine Anwendung, deren Benutzer ihre Gruppen lieber unangetastet sehen, darf das sagen. Ein Eintrag des Blocks bleibt in seiner Gruppe und trägt deren Namen — eine Abkürzung verschiebt nicht, worauf sie abkürzt

Methoden #

MethodeRolle
of_add_command (string as_key, string as_label, string as_group)Deklariert eine Aktion: ihren Bezeichner, ihre Beschriftung und die Gruppe, unter der sie erscheint. Liefert 0 nach der Anwendung, -5 bei einem ungültigen Argument (leerer Schlüssel, falsche Adresse), -2 wenn die Komponente nicht erzeugt ist
of_add_command (string as_key, string as_label, string as_group, string as_hint, string as_shortcut, string as_keywords)Dasselbe, mit dem Hinweis rechts, dem anzuzeigenden Kürzel, das seinen Befehl ausführt, solange die Palette offen ist — so lernt man es ; außerhalb behält Ihre Anwendung ihre eigenen Tastenkombinationen — und Schlüsselwörtern, die die Suche liest, ohne sie zu zeigen. Liefert 0 nach der Anwendung, -5 bei einem ungültigen Argument (leerer Schlüssel, falsche Adresse), -2 wenn die Komponente nicht erzeugt ist
of_remove_command (string as_key)Entfernt eine Aktion; die anderen bleiben. Liefert 0 nach der Anwendung, -5 bei einem ungültigen Argument (leerer Schlüssel, falsche Adresse), -2 wenn die Komponente nicht erzeugt ist
of_command (string as_key) → n_pbt_commandpalette_commandDas Handle eines Befehls, um ihn umzubenennen, sein Kürzel zu ändern, ihn auszugrauen oder zu verbergen – über seine Eigenschaften. Ausgrauen statt entfernen: was der Benutzer gerade nicht tun kann zu entfernen, nimmt ihm auch jede Chance zu entdecken, dass es existiert. Der Zustand reist mit den Befehlen: eine Änderung bei offener Palette zeigt sich beim nächsten Öffnen
of_clear_commands ( )Leert die Palette. Liefert 0 nach der Anwendung, -2 wenn die Komponente nicht erzeugt ist
of_count ( ) → integerWie viele Befehle die Palette trägt
of_keys_at ( integer ai_index ) → stringDie Kennung des Befehls an Position ai_index (ab 1), oder "" jenseits beider Enden. Zusammen mit of_count lässt sich so eine Palette durchlaufen, die man nicht selbst gefüllt hat — ein gemeinsames Modul fügt seine eigenen hinzu
of_has ( string as_key ) → booleanGibt es einen Befehl unter dieser Kennung? Fragen ist besser als raten: ein zweiter unter einer bereits vergebenen Kennung erzeugt einen Zwilling
of_open ( )Öffnet die Palette: ein eigenes Fenster, im Besitz von ipo_owner, platziert durch is_position. Sie nimmt den Fokus und gibt ihn beim Schließen zurück. Liefert 0 nach dem Öffnen, -1 wenn die WebView2-Laufzeit fehlt, -4 wenn ihr Fenster nicht erzeugt werden konnte
of_is_open ( )TRUE, solange die Palette auf dem Bildschirm ist. Genau das lässt das Kürzel umschalten: ein zweiter Druck schließt eine Palette — ein erneutes of_open würde das Fenster zerstören und identisch neu aufbauen, was als Flackern erscheint, nicht als Schließen. Die DLL entscheidet weiterhin nichts: sie informiert
of_close ( )Schließt sie. Der Verlust des Fokus schließt sie ebenfalls, wie ein Menü. Liefert 0
of_register_shortcut ( )Übergibt das Kürzel aus is_shortcut an die DLL. Einmal beim Öffnen des Fensters aufrufen. Ein Kürzel pro Fenster: ein erneuter Aufruf nach dem Ändern von is_shortcut ersetzt das vorige, das sofort nicht mehr antwortet — es ist nie etwas vorher zu entfernen. Liefert 0 beim Setzen, 1 beim Ersetzen, 2 wenn ein leeres is_shortcut es entfernt hat
of_process_events ( )Holt die wartenden Events ab und löst sie auf diesem Objekt aus. Aus dem pbm_custom02-Handler von ipo_receiver aufrufen — der einzige Rückweg
of_reset ( )Leert die Befehle und setzt die Eigenschaften auf ihre Standardwerte zurück. ipo_owner und ipo_receiver bleiben unberührt: sie sind die Verdrahtung, nicht der Inhalt. Liefert 0 nach der Anwendung, -2 wenn die Komponente nicht erzeugt ist

Eigenschaften eines Befehls — n_pbt_commandpalette_command #

Erhalten über of_command(Schlüssel). Die Palette baut ihr Fenster bei jedem of_open aus ihrer Liste neu auf: eine Eigenschaft, die geändert wird, während sie offen ist, zeigt sich beim nächsten Öffnen.

EigenschaftTypStandardRolle
is_labelstring—Der Text der Zeile
is_shortcutstring""Das rechts in der Zeile gezeigte Kürzel, das gilt, solange die Palette offen ist (Ctrl+Shift+S)
ib_enabledbooleantrueBefehl ausgegraut: sichtbar, suchbar und inaktiv – weder Klick, Eingabe noch sein Kürzel
ib_visiblebooleantrueBefehl verborgen: aus der Liste und den Kürzeln genommen, ohne entfernt zu werden; er kommt unverändert zurück

Events #

EventAusgelöst, wenn
ue_command_selected (string as_key)Der Benutzer hat eine Aktion gewählt. Die Palette ist bereits geschlossen: das Angekündigte zu tun, liegt bei Ihnen
ue_shortcut ( )Das Kürzel wurde gedrückt. Die DLL meldet, PB entscheidet. Eine Palette schaltet auf ihrer eigenen Taste um: if of_is_open() then of_close() else of_open(). Sie dürfen auch ablehnen
ue_opened ( )Die Palette ist auf dem Bildschirm — über of_open
ue_closed ( )Sie hat sich gerade geschlossen, ob etwas gewählt wurde oder nicht

Die Palette tut von sich aus nichts. Sie meldet den gewählten Bezeichner und schließt sich. Handeln muss Ihre Anwendung — dieselbe Aktion, aus einem Menü oder aus der Palette ausgelöst, läuft also über denselben Code.


Über die Tastatur #

TasteWirkung
Das Kürzel aus is_shortcutMeldet es Ihrem Code über ue_shortcut; dieser öffnet
TippenFiltert während der Eingabe: die Buchstaben müssen nicht aufeinanderfolgen, ndt findet „Neues Dokument“
Pfeile hoch / runterVerschieben die Auswahl in der Liste
EingabetasteWählt die markierte Aktion (ue_command_selected)
Das auf einer Zeile angezeigte KürzelFührt diesen Befehl aus, ohne ihn erst auswählen zu müssen
EscapeSchließt, ohne etwas zu wählen

Beispiele #

Die Palette aus Ihrem Menü füllen #

// Schluesselwoerter werden nicht angezeigt, die Suche liest sie aber :
// "pdf" findet den Export, auch wenn die Beschriftung es nie sagt
inv_palette.of_add_command(/*key*/ "export", /*label*/ "E", /*group*/ "F", /*hint*/ "H", /*shortcut*/ "Ctrl+E", /*keywords*/ "pdf csv xlsx")

Ein anderes Tastenkürzel wählen #

// Ctrl+K schon von Ihrer Anwendung belegt ? Waehlen Sie ein anderes.
// of_register_shortcut uebergibt es, das alte geht von selbst.
inv_palette.is_shortcut = "ctrl+shift+p"
inv_palette.of_register_shortcut()

Sie unter einem Feld verankern #

// Unter einem Eingabefeld verankert : PB rechnet in PBU, die DLL in Pixeln
// Die Palette wird in den Bildschirm zurueckgeholt, wenn sie ueberstand
inv_palette.is_position = inv_palette.POSITION_ABSOLUTE
inv_palette.il_x = UnitsToPixels(sle_1.x, XUnitsToPixels!)
inv_palette.il_y = UnitsToPixels(sle_1.y + sle_1.height, YUnitsToPixels!)
inv_palette.is_placeholder = "P"
inv_palette.of_open()
inv_palette.of_remove_command(/*key*/ "print")
inv_palette.of_clear_commands()
inv_palette.of_close()

Best Practices #


← Komponentenreferenz · Inhalt des Leitfadens