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 #
| Objekt | n_pbt_commandpalette — nicht visuell: nichts im Fenster zu platzieren |
| Dient zu | Jede Aktion der Anwendung über die Tastatur erreichbar machen, mit drei Buchstaben |
| Rückgabe | Nicht 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.
| Konstante | Wohin |
|---|---|
POSITION_WINDOW_CENTER | Auf ipo_owner zentriert — der Standard, und was das Auge erwartet |
POSITION_SCREEN_CENTER | Auf dem Bildschirm zentriert, unabhängig vom Fenster |
POSITION_ABSOLUTE | Bei 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 #
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
ipo_owner | powerobject | — | Das Fenster, zu dem die Palette gehört: es besitzt das Popup-Fenster und verankert es. Vor of_open setzen |
ipo_receiver | powerobject | — | Das visuelle Objekt, das die Events empfängt. Es deklariert event xxx pbm_custom02 und ruft dort of_process_events auf |
is_shortcut | string | "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_position | string | window-center | Wo das Fenster landet (POSITION_*-Konstanten) |
il_x · il_y | long | 0 | Position in Bildschirmpixeln, nur von POSITION_ABSOLUTE gelesen |
is_placeholder | string | "" | Grauer Text im Suchfeld, solange nichts getippt wurde |
is_recent | string | "" | 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_recent | long | 8 | Wie 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 #
| Methode | Rolle |
|---|---|
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_command | Das 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 ( ) → integer | Wie viele Befehle die Palette trägt |
of_keys_at ( integer ai_index ) → string | Die 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 ) → boolean | Gibt 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.
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
is_label | string | — | Der Text der Zeile |
is_shortcut | string | "" | Das rechts in der Zeile gezeigte Kürzel, das gilt, solange die Palette offen ist (Ctrl+Shift+S) |
ib_enabled | boolean | true | Befehl ausgegraut: sichtbar, suchbar und inaktiv – weder Klick, Eingabe noch sein Kürzel |
ib_visible | boolean | true | Befehl verborgen: aus der Liste und den Kürzeln genommen, ohne entfernt zu werden; er kommt unverändert zurück |
Events #
| Event | Ausgelö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 #
| Taste | Wirkung |
|---|---|
Das Kürzel aus is_shortcut | Meldet es Ihrem Code über ue_shortcut; dieser öffnet |
| Tippen | Filtert während der Eingabe: die Buchstaben müssen nicht aufeinanderfolgen, ndt findet „Neues Dokument“ |
| Pfeile hoch / runter | Verschieben die Auswahl in der Liste |
| Eingabetaste | Wählt die markierte Aktion (ue_command_selected) |
| Das auf einer Zeile angezeigte Kürzel | Führt diesen Befehl aus, ohne ihn erst auswählen zu müssen |
| Escape | Schließ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 #
- Geben Sie jedem Befehl denselben Bezeichner wie im Menü: eine einzige Funktion bedient beide, und der Benutzer bekommt genau dasselbe.
- Rufen Sie
of_register_shortcut()beim Öffnen des Fensters auf, nicht beim erstenof_open: eine Palette, die erst nach dem Öffnen per Maus auf ihre Taste hört, nützt nichts. - Füllen Sie die Schlüsselwörter aus: das unterscheidet eine genutzte Palette von einer, in der man nie etwas findet. Denken Sie an die Wörter des Benutzers, nicht an Ihre.
- Zeigen Sie das Kürzel der Aktion in
as_shortcut: die Palette wird so zum Weg, sie zu lernen. - Nehmen Sie nur sofortige Aktionen auf. Ein Befehl, der einen Einstellungsdialog öffnet, ja; einer, der drei Parameter braucht, nein.
- Entfernen Sie Befehle, die keinen Sinn mehr ergeben, statt sie scheitern zu lassen: eine Palette, die Unmögliches anbietet, verliert das Vertrauen auf einen Schlag.