Unterabschnitte

Allgemeine Fenterklassen

Wie im vorherigen Kapitel gezeigt wurde, kann mit der libCUI auf der Basis der allgemeinen Fensterstruktur CUIWINDOW eine Vielfalt unterschiedlicher Fensterklassen implementiert werden - alleine durch die Implementierung von Hook- Funktionen.

Neben dieser rudimentären Funktionalität bringt die LibCUI jedoch auch eine Reihe von Fensterklassen mit, die bereits fertig für ihre spezielle Aufgabe implementiert sind und vom Anwendungsprogrammierer ohne Änderung eingesetzt werden können. Dies sind vor allem Kontrollelemente wie z.B. Eingabezeilen, Buttons, Labels etc.

Dieses Kapitel stellt die einzelnen Kontrollelemente vor, ohne allzusehr auf deren Anwendung einzugehen. Hinweise zur Anwendung finden sich später im Kapitel ''Dialoge''.

Konventionen

Alle von der libCUI zur Verfügung gestellten Kontrollelemente befolgen ein paar gemeinsame Konventionen. Dies sind:

Erzeugung:
Ein libCUI Kontrollelement stellt eine Funktion zur Verfügung, mit der das Kontrollelement vollständig angelegt und spezialisiert wird. Üblicherweise trägt diese Funktion den Namen des Kontrollelements mit dem Anhängsel ''New''. Beispiel ''ButtonNew''. Das auf diese Weise angelegte Fenster braucht anschließend lediglich mittels der Funktion ''WindowCreate'' erzeugt zu werden.

Fensterstile:
Die Funktion zur Anlage von Kontrollelementinstanzen kennt zusätzlich zwei Parameter, die das Setzen von zusätzlichen Fensterstilen und das Zurücksetzen von standardmäßig gesetzen Fensterstilen erlauben. Wird hier jeweils CWS_NONE übergeben, dann wird das Kontrollelement mit den ihm eigenen Fensterstilen angelegt. Manche Kontrollelemente erweitern die Fensterstile der libCUI um spezifische Eigenschaften. So kennt z.B. die Eingabezeile den Stil ''ED_PASSWORD''.

Klassenname:
Jedes Kontrollelement hat seinen eigenen Klassennamen, den es an das Datenelement ''Class'' der Struktur CUIWINDOW gebunden hat. Der Klassenname entspricht dabei dem Namen des Kontrollelements. Beispiele: ''EDIT'', ''BUTTON'' und ''LISTBOX''

Zugriffsfunktionen:
Ein Kontrollelement bringt eine Reihe von Funktionen mit, über die auf die jeweilige Elementinstanz und deren Daten zugegriffen werden kann. Diese Funktionen führen als Prefix immer den Namen des Kontrollelements. Beispiel: ''EditSetText''.

Custom Callback Hooks:
Während die im vorigen Kapitel vorgestellten Hook-Funktionen die Schnittstelle zwischen dem Fenstersystem und der Fensterinstanz bilden, bilden Custom Callback Hooks die Verbindung von Kontrollelementen zum Anwendungsprogramm. Über diese Hook- Funktionen teilt das Kontrollelement der Anwendung mit, wenn sich etwas geändert hat. Dies kann z.B. der Erhalt oder Verlust des Fokus sein, ebenso wie der Wechsel des markierten Eintrags in einer Listbox oder die Modifikation des Textes in einer Eingabezeile. Custom Callback Hooks müssen vom Anwendungsprogramm aus beim jeweiligen Kontrollelement angemeldet werden.

Kennnummer (ID):
Jedes Kontrollelement erhält eine (innerhalb des aktuellen Popup-Fensters) eindeutige Kennnummer. Über diese ID kann das Kontrollelement jederzeit mittels der Funktion ''WindowGetCtrl'' gefunden werden.

Hot-Key:
Kontrollelemente kennen einen Hot-Key und können darüber direkt durch einen Tastendruck bedient werden, auch wenn der Eingabefokus auf einem anderen Fenster steht. Dies funktioniert natürlich nur dann, wenn das andere Fenster die eingegebene Taste nicht sebst verwendet. Als Hot-Key wird dasjenige Zeichen hinterlegt, das im Fenstertext mit einem vorangestellten '&' markiert ist.

Label

Ein Label ist ein statisches Textfeld, in dem einzeiliger oder mehrzeiliger Text dargestellt werden kann. Es wird häufig für Beschiftungen innerhalb von Dialogen verwendet.

Anlage:

   CUIWINDOW* LabelNew(CUIWINDOW* parent, 
                       const wchar_t* text,
                       int x, int y, int w, int h, 
                       int id, 
                       int sflags, int cflags);

Standardstil:

   CWS_NONE

Custom Callbacks:

   void LabelSetSetFocusHook (CUIWINDOW* win, 
                              CustomHook1PtrProc proc, 
                              CUIWINDOW* target);
   void LabelSetKillFocusHook(CUIWINDOW* win, 
                              CustomHookProc proc, 
                              CUIWINDOW* target);

Beispiel:

   ctrl = LabelNew(aparent, "Password:", 2, 1, 10, 1, 
                   IDC_STATIC, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);

Button

Ein Button ist eine Schaltfläche, die mit der Enter- oder der Leertaste betätigt (geschaltet) werden kann. Buttons werden häufig zum Schließen von Fenstern o.ä. verwendet.

Anlage:

   CUIWINDOW* ButtonNew(CUIWINDOW* parent, 
                        const wchar_t* text, 
                        int x, int y, int w, int h,
                        int id, 
                        int sflags, int cflags)

Standardstil:

   CWS_TABSTOP

Erweiterte Stile:

   CWS_DEFOK, CWS_DEFCANCEL

Custom Callbacks:

   void ButtonSetSetFocusHook  (CUIWINDOW* win, 
                                CustomHook1PtrProc proc, 
                                CUIWINDOW* target);
   void ButtonSetKillFocusHook (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);
   void ButtonSetClickedHook   (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);

Beispiel:

   ctrl = ButtonNew(aparent, "&Ok", 15, 6, 10, 1, 
                    IDOK, CWS_DEFOK, CWS_NONE);
   ButtonSetClickedHook(ctrl, MyOkHook, aparent);
   WindowCreate(ctrl);
   ...
   
   void MyOkHook(void* w, void* c)
   {
      WindowClose((CUIWINDOW*) w, IDOK);
   }

Checkbox

Mit Hilfe von Checkboxen können Werte dargestellt und verändert werden, die nur die zwei Zustände ''markiert'' und ''nicht markiert'' kennen. Befinden sich mehrere Checkboxen in einem gemeinsamen Fensterbereich (z.B. in einer Groupbox), dann können ihre Werte unabhängig voneinander verändert werden.

Anlage:

   CUIWINDOW* CheckboxNew(CUIWINDOW* parent, 
                          const wchar_t* text,
                          int x, int y, int w, int h, 
                          int id, 
                          int sflags, int cflags);

Standardstil:

   CWS_TABSTOP

Custom Callbacks:

   void CheckboxSetSetFocusHook (CUIWINDOW* win, 
                                 CustomHook1PtrProc proc, 
                                 CUIWINDOW* target);
   void CheckboxSetKillFocusHook(CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);
   void CheckboxSetClickedHook  (CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);

Zugriffsfunktionen:

   void CheckboxSetCheck(CUIWINDOW* win, int state);
   int  CheckboxGetCheck(CUIWINDOW* win);

Beispiel:

   ctrl = CheckboxNew(agroup, "Create &Databases", 1, 2, 20, 1, 
                      IDC_CHKCREATEDB, CWS_NONE, CWS_NONE);
   CheckboxSetCheck(ctrl, data->CreateDb);
   WindowCreate(ctrl);

   ctrl = CheckboxNew(agroup, "Create &Users", 1, 3, 20, 1, 
                      IDC_CHKCREATEUSER, CWS_NONE, CWS_NONE);
   CheckboxSetCheck(ctrl, data->CreateUser);
   WindowCreate(ctrl);

   ...
   
   ctrl = WindowGetCtrl(win, IDC_CHKCREATEDB);
   if (ctrl)
   {
      data->CreateDb = CheckboxGetCheck(ctrl);
   }
   
   ...

Radio-Button

Wie die Checkbox, so ist auch der Radio-Button ein Kontrollelement mit dem Werte dargestellt und verändert werden können, die nur die zwei Zustände ''markiert'' und ''nicht markiert'' besitzen. Im Unterschied zur Checkbox kann in einem gemeinsamen Fensterbereich (z.B. in einer Groupbox) jedoch immer nur einer der Radio-Buttons eine Markierung haben, die übrigen werden automatisch auf ''nicht markiert'' gesetzt.

Anlage:

   CUIWINDOW* RadioNew(CUIWINDOW* parent, 
                          const wchar_t* text,
                          int x, int y, int w, int h, 
                          int id, 
                          int sflags, int cflags);

Standardstil:

   CWS_TABSTOP

Custom Callbacks:

   void RadioSetSetFocusHook (CUIWINDOW* win, 
                              CustomHook1PtrProc proc, 
                              CUIWINDOW* target);
   void RadioSetKillFocusHook(CUIWINDOW* win, 
                              CustomHookProc proc, 
                              CUIWINDOW* target);
   void RadioSetClickedHook  (CUIWINDOW* win, 
                              CustomHookProc proc, 
                              CUIWINDOW* target);

Zugriffsfunktionen:

   void RadioSetCheck(CUIWINDOW* win, int state);
   int  RadioGetCheck(CUIWINDOW* win);

Beispiel:

   ctrl = RadioNew(agroup, "&1 kHz sample rate", 1, 2, 20, 1, 
                      IDC_RB1KHZ, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);

   ctrl = RadioNew(agroup, "&4 kHz sample rate", 1, 3, 20, 1, 
                      IDC_RB4KHZ, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);

   ctrl = RadioNew(agroup, "&8 kHz sample rate", 1, 4, 20, 1, 
                      IDC_RB8KHZ, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);

   ctrl = NULL;
   switch(data->SampleRate)
   {
   case 1: ctrl = WindowGetCtrl(agroup, IDC_RB1KHZ); break;
   case 4: ctrl = WindowGetCtrl(agroup, IDC_RB4KHZ); break;
   case 8: ctrl = WindowGetCtrl(agroup, IDC_RB8KHZ); break;
   default: ctrl = WindowGetCtrl(agroup, IDC_RB1KHZ); break;
   }

   if (ctrl)
   {
      RadioSetCheck(ctrl, TRUE);
   }

Edit

Ein Edit-Kontrollelement wird zur einzeiligen Darstellung und Eingabe von Textdaten herangezogen. Optional kann es in einem Passwort-Modus betrieben werden, in dem anstelle der eingegebenen Zeichen der Platzhalter '*' dargestellt wird.

Anlage:

   CUIWINDOW* EditNew (CUIWINDOW* parent, 
                       const wchar_t* text,
                       int x, int y, int w, int h, 
                       int len, 
                       int id, 
                       int sflags, int cflags);

Standardstil:

   CWS_TABSTOP

Erweiterte Stile:

   EF_PASSWORD

Custom Callbacks:

   void EditSetSetFocusHook (CUIWINDOW* win, 
                             CustomHook1PtrProc proc, 
                             CUIWINDOW* target);
   void EditSetKillFocusHook(CUIWINDOW* win, 
                             CustomHookProc proc, 
                             CUIWINDOW* target);
   void EditSetChangedHook  (CUIWINDOW* win, 
                             CustomHookProc proc, 
                             CUIWINDOW* target);

Zugriffsfunktionen:

   void EditSetText(CUIWINDOW* win, const wchar_t* text);
   const wchar_t* EditGetText(CUIWINDOW* win, wchar_t* text, int len);

Beispiel:

   ctrl = EditNew(aparent, "", 64, 1, 2, 20, 1, 
                  IDC_EDPASSWORD, EF_PASSWORD, CWS_NONE);
   WindowCreate(ctrl);
   EditSetText(ctrl, "sesam123");

Listbox

Die Listbox stellt eine einspaltige scrollbare Auswahlliste zur Verfügung, in der ein Eintrag markiert werden kann. Listboxen können alle möglichen Daten enthalten und dem Anwender zur Auswahl anbieten.

Anlage:

   CUIWINDOW* ListboxNew(CUIWINDOW* parent, 
                         const wchar_t* text,
                         int x, int y, int w, int h, 
                         int id, 
                         int sflags, int cflags);

Standardstil:

   CWS_TABSTOP, CWS_BORDER

Erweiterte Stile:

   LB_SORTED, LB_DESCENDING

Custom Callbacks:

   void ListboxSetSetFocusHook  (CUIWINDOW* win, 
                                 CustomHook1PtrProc proc, 
                                 CUIWINDOW* target);
   void ListboxSetKillFocusHook (CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);
   void ListboxSetLbChangedHook (CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);
   void ListboxSetLbChangingHook(CUIWINDOW* win, 
                                 CustomBoolHookProc proc, 
                                 CUIWINDOW* target);
   void ListboxSetLbClickedHook (CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);

Zugriffsfunktionen:

   int  ListboxAdd(CUIWINDOW* win, const wchar_t* text);
   void ListboxDelete(CUIWINDOW* win, int index);
   const wchar_t* ListboxGet(CUIWINDOW* win, int index);
   void ListboxSetData(CUIWINDOW* win, int index, 
                       unsigned long data);
   unsigned long ListboxGetData(CUIWINDOW* win, int index);
   void ListboxSetSel(CUIWINDOW* win, int index);
   int  ListboxGetSel(CUIWINDOW* win);
   void ListboxClear(CUIWINDOW* win);
   int  ListboxGetCount(CUIWINDOW* win);

Beispiel:

   ctrl = ListboxNew(aparent, "Names", 1, 2, 20, 10, 
                  IDC_LBNAMES, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);
   
   ListboxAdd(ctrl, "Otto");
   ListboxAdd(ctrl, "Fritz");
   ListboxAdd(ctrl, "Maria");
   ListboxAdd(ctrl, "Franz");
   
   ListboxSetSel(ctrl, 0);

Listview

Der Listview ist der Listbox sehr verwandt, mit dem Unterschied, dass hier die Daten in mehreren Spalten dargestellt werden können. Die Anzahl der Spalten wird bei der Anlage festgelegt, die Angabe der Spaltenüberschrifen erfolgt später.

Ein Eintrag in der Liste wird über die folgende Struktur abgebildet:

    typedef struct LISTRECStruct
    {
       wchar_t**        ColumnText;   /* char array with text data */
       int*          ColumnWidth;  /* Width of column */
       int           NumColumns;   /* Numer of columns */
       unsigned long Data;         /* User data */
       void*         Next;         /* Next list record */
    } LISTREC;

Anlage:

   CUIWINDOW* ListviewNew(CUIWINDOW* parent, 
                          const wchar_t* text,
                          int x, int y, int w, int h, 
                          int num_cols, 
                          int id, 
                          int sflags, int cflags);

Standardstil:

   CWS_TABSTOP, CWS_BORDER

Custom Callbacks:

   void ListviewSetSetFocusHook  (CUIWINDOW* win, 
                                  CustomHook1PtrProc proc, 
                                  CUIWINDOW* target);
   void ListviewSetKillFocusHook (CUIWINDOW* win, 
                                  CustomHookProc proc, 
                                  CUIWINDOW* target);
   void ListviewSetLbChangedHook (CUIWINDOW* win, 
                                  CustomHookProc proc, 
                                  CUIWINDOW* target);
   void ListviewSetLbChangingHook(CUIWINDOW* win, 
                                  CustomBoolHookProc proc, 
                                  CUIWINDOW* target);
   void ListviewSetLbClickedHook (CUIWINDOW* win, 
                                  CustomHookProc proc, 
                                  CUIWINDOW* target);

Zugriffsfunktionen:

   void ListviewAddColumn(CUIWINDOW* win, 
                          int colnr, 
                          const wchar_t* text);
                          
   void ListviewClear(CUIWINDOW* win);
   
   LISTREC* ListviewCreateRecord(CUIWINDOW* win);
   
   int  ListviewInsertRecord(CUIWINDOW* win, 
                             LISTREC* newrec, 
                             int doupdate);
                             
   void ListviewSetColumnText(LISTREC* rec, 
                              int colnr, 
                              const wchar_t* text);
                              
   const wchar_t* ListviewGetColumnText(LISTREC* rec, 
                                     int colnr);
                                     
   void ListviewSetSel(CUIWINDOW* win, int index);
   int  ListviewGetSel(CUIWINDOW* win);
   LISTREC* ListviewGetRecord(CUIWINDOW* win, int index);
   int  ListviewGetCount(CUIWINDOW* win);

Beispiel:

   ctrl = ListviewNew(aparent, "Address", 
                      1, 2, 40, 10, 3,
                      IDC_LVADDR, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);
   
   ListviewAddColumn(ctrl, 0, "Name");
   ListviewAddColumn(ctrl, 1, "Firstname");
   ListviewAddColumn(ctrl, 2, "Town");
   
   rec = ListviewCreateRecord(ctrl);
   if (rec)
   {
      ListviewSetColumnText(rec, 0, "Mustermann");
      ListviewSetColumnText(rec, 1, "Max");
      ListviewSetColumnText(rec, 2, "Hintertupfingen");
      ListviewInsertRecord(ctrl, rec, FALSE);
   }
   rec = ListviewCreateRecord(ctrl);
   if (rec)
   {
      ListviewSetColumnText(rec, 0, "R"ussel");
      ListviewSetColumnText(rec, 1, "Rudi");
      ListviewSetColumnText(rec, 2, "Musterhausen");
      ListviewInsertRecord(ctrl, rec, TRUE);
   }
   
   ListviewSetSel(ctrl, 0);

Textview

Der Textview erlaubt das Betrachten von vielzeiligem Text in einer scrollbaren Ansicht. Optional kann der Text am Zeilenende umgebrochen werden. Texte werden entweder über Zugriffsfunktionen in das Kontrollelement übertragen oder aus einer Datei gelesen.

Anlage:

   CUIWINDOW* TextviewNew(CUIWINDOW* parent, 
                          const wchar_t* text,
                          int x, int y, int w, int h, 
                          int id, 
                          int sflags, int cflags);

Standardstil:

   CWS_TABSTOP, CWS_BORDER

Custom Callbacks:

   void TextviewSetSetFocusHook  (CUIWINDOW* win, 
                                  CustomHook1PtrProc proc, 
                                  CUIWINDOW* target);
   void TextviewSetKillFocusHook (CUIWINDOW* win, 
                                  CustomHookProc proc, 
                                  CUIWINDOW* target);

Zugriffsfunktionen:

   void TextviewEnableWordWrap(CUIWINDOW* win, int enable);
   void TextviewAdd(CUIWINDOW* win, const wchar_t* text, 
                    int doupdate);
   void TextviewClear(CUIWINDOW* win);
   int  TextviewRead(CUIWINDOW* win, const wchar_t* filename);
   int  TextviewSearch(CUIWINDOW* win, 
                    const wchar_t* text, 
                    int wholeword, 
                    int casesens, 
                    int down);

Beispiel:

   ctrl = TextviewNew(aparent, "User Accounts", 
                      1, 2, 40, 10,
                      IDC_TVACCOUNTS, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);
   
   if (!TextviewRead(ctrl, "/etc/passwd"))
   {
      MessageBox(aparent, 
                 "Error reading file /etc/passwd!",
                 "Error",
                 MB_ERROR);
   }

Progressbar

Der PogressBar ist ein Kontrollelement mit dem der Fortschritt eines Vorgangs visualisiert werden kann, der längere Zeit in Anspruch nimmt. Vergleichbar mit einer Bildlaufleiste kennt der Fortschrittsbalken einen Bereich und eine Position.

Anlage:

   CUIWINDOW* ProgressbarNew(CUIWINDOW* parent, 
                             const wchar_t* text,
                             int x, int y, int w, int h, 
                             int id, 
                             int sflags, int cflags);

Standardstil:

   CWS_TABSTOP, CWS_BORDER

Zugriffsfunktionen:

   void ProgressbarSetRange(CUIWINDOW* win, int range);
   void ProgressbarSetPos(CUIWINDOW* win, int pos);
   int  ProgressbarGetRange(CUIWINDOW* win);
   int  ProgressbarGetPos(CUIWINDOW* win);

Beispiel:

   ctrl = ProgressbarNew(aparent, "Progress", 
                      1, 2, 30, 3,
                      IDC_PGBAR, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);
   
   ProgressbarSetRange(ctrl, 100);
   ProgressbarSetPos(ctrl, 50);

Memo

Das Memo-Kontrollelement erlaubt die Bearbeitung von mehrzeiligem Text in einem Editor-Fenster. Eine Textzeile kann dabei eine definierbare maximale Breite annehmen, ab der das folgende Wort in die nächste Zeile umgebrochen wird (word wrap). Der Umbruch erfolgt an Leerzeichen und Bindestrichen.

Alternativ kann das Kontrollelement in einem automatischen Umbruchsmodus betrieben werden, in dem der Text immer am rechten Fensterrand umgebrochen wird und dadurch niemals breiter als der tatsächlich sichtbare Bereich des Fensterinhaltes ist. Wird das Kontrollelement in seiner Grösse verändert, wird der Text automatisch auf die neue Fensterbreite umgerechnet.

Anlage:

   CUIWINDOW* MemoNew (CUIWINDOW* parent, 
                       const wchar_t* text,
                       int x, int y, int w, int h, 
                       int id, 
                       int sflags, int cflags);

Standardstil:

   CWS_TABSTOP

Erweiterte Stile:

   MF_AUTOWORDWRAP

Custom Callbacks:

   void MemoSetSetFocusHook (CUIWINDOW* win, 
                             CustomHook1PtrProc proc, 
                             CUIWINDOW* target);
   void MemoSetKillFocusHook(CUIWINDOW* win, 
                             CustomHookProc proc, 
                             CUIWINDOW* target);
   void MemoSetChangedHook  (CUIWINDOW* win, 
                             CustomHookProc proc, 
                             CUIWINDOW* target);

Zugriffsfunktionen:

   void        MemoSetText(CUIWINDOW* win, const wchar_t* text);
   const wchar_t* MemoGetText(CUIWINDOW* win, wchar_t* text, int len);
   int         MemoGetTextBufSize(CUIWINDOW* win);
   void        MemoSetWrapColumns(CUIWINDOW* win, int cols);

Beispiel:

   ctrl = MemoNew(aparent, "", 1, 2, 20, 10, 
                  IDC_MEMO, MF_AUTOWORDWRAP, CWS_NONE);
   WindowCreate(ctrl);
   MemoSetText(ctrl, "Hello World this is a test");

Terminal

Das Terminal Kontrollelement erlaubt es, Co- Prozesse in einem interaktiven Fenster ablaufen zu lassen. Der Co- Prozess wird im Hintergrund gestartet und über Pipes mit dem Kontrollelements verbunden.

Anlage:

   CUIWINDOW* TerminalNew(CUIWINDOW* parent, 
                          const wchar_t* text,
                          int x, int y, int w, int h, 
                          int id, 
                          int sflags, int cflags);

Standardstil:

   CWS_TABSTOP, CWS_BORDER

Custom Callbacks:

   void TerminalSetSetFocusHook (CUIWINDOW* win, 
                                 CustomHook1PtrProc proc, 
                                 CUIWINDOW* target);
   void TerminalSetKillFocusHook(CUIWINDOW* win, 
                                 CustomHookProc proc, 
                                 CUIWINDOW* target);

Zugriffsfunktionen:

   void TerminalWrite(CUIWINDOW* win, const wchar_t* text, 
                      int numchar, int doupdate);
   int  TerminalRun(CUIWINDOW* win, const wchar_t* cmd);

Beispiel:

   ctrl = TerminalNew(aparent, "Shell", 
                      1, 2, 40, 10,
                      IDC_TERMINAL, CWS_NONE, CWS_NONE);
   WindowCreate(ctrl);
   
   TerminalWrite(ctrl, "Just type 'exit' to return\r\n");
   TerminalRun(ctrl, "/bin/bash -i");

Menu

Ein Menü ist ein Kontrollelement, das dem Anwender erlaubt aus einer Liste von Optionen (Menübefehlen) zu wählen. Jeder Menüeintrag besitzt dabei eine Nummer und einen Namen. Ein als ''moveable'' markierter Menüeintrag kann im Menü verschoben werden, wenn das Kontrollelement in den ''Drag'' Mode geschaltet wird.

Die Auswahl eines Menüeintrags erfolgt entweder mittels der Pfeiltasten, über die direkte Eingabe der Nummer oder mit Hilfe der Maus.

Ein Menü kann in einer Liste von Kindfenstern sowie als Popup Fenster eingesetzt werden.

Menüpunkte werden in einer Struktur verwaltet, die den folgenden Aufbau hat:

   typedef struct MENUITEMStruct
   {
      wchar_t*         ItemText;
      int           IsSeparator;
      int           IsMoveable;
      unsigned long ItemId;
      void*         Next;
      void*         Previous;
   } MENUITEM;

Anlage:

   CUIWINDOW* MenuNew(CUIWINDOW* parent, 
                      const wchar_t* text,
                      int x, int y, int w, int h, 
                      int id, 
                      int sflags, int cflags);

Custom Callbacks:

   void MenuSetSetFocusHook    (CUIWINDOW* win, 
                                CustomHook1PtrProc proc, 
                                CUIWINDOW* target);
   void MenuSetKillFocusHook   (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);
   void MenuSetMenuChangedHook (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);
   void MenuSetMenuChangingHook(CUIWINDOW* win, 
                                CustomBoolHookProc proc, 
                                CUIWINDOW* target);
   void MenuSetMenuClickedHook (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);
   void MenuSetMenuEscapeHook  (CUIWINDOW* win, 
                                CustomHookProc proc, 
                                CUIWINDOW* target);

Zugriffsfunktionen:

   
   void MenuAddItem(CUIWINDOW* win, 
                    const wchar_t* text, 
                    unsigned long id, 
                    int moveable);
   void MenuAddSeparator(CUIWINDOW* win, int moveable);
   void MenuSelectItem(CUIWINDOW* win, unsigned long id);
   MENUITEM* MenuGetSelectedItem(CUIWINDOW* win);
   void MenuSetDragMode(CUIWINDOW* win, int state);
   void MenuClear(CUIWINDOW* win);

Beispiel:

   CUIWINDOW* menu = MenuNew(win, "Edit", 0, 0, 30, 12, 1,
                             CWS_CENTERED | CWS_POPUP, CWS_NONE);
   if (menu)
   {
      int choice = 0;

      MenuAddItem(menu, "Edit selected database", 1, FALSE);
      MenuAddItem(menu, "Drop selected database", 2, FALSE);
      MenuAddItem(menu, "Create new database", 3, FALSE);
      MenuAddSeparator(menu, FALSE);
      MenuAddItem(menu, "Exit application", 7, FALSE);
      MenuAddSeparator(menu, FALSE);
      MenuAddItem(menu, "Close menu", 0, FALSE);
      MenuSelectItem(menu, 1);

      MenuSetMenuClickedHook(menu, DatabasesMenuChoice, win);
      MenuSetMenuEscapeHook(menu, DatabasesMenuEscape, win);

      WindowCreate(menu);
      if (WindowModal(menu) == IDOK)
      {
         MENUITEM* item = MenuGetSelectedItem(menu);
         if (item)
         {
            choice = item->ItemId;
         }
         WindowDestroy(menu);

         switch(choice)
         {
         case 1: 
            DatabasesModify(win, &data->Module[data->Current]); 
            break;
         case 2: 
            DatabasesDelete(win, &data->Module[data->Current]); 
            break;
         case 3: 
            DatabasesCreate(win, &data->Module[data->Current]); 
            break;
         case 7:
            WindowQuit(EXIT_SUCCESS);
            break;
         }
      }
      else
      {
         WindowDestroy(menu);
      }
   }
Holger Bruenjes 2016-12-12