Diese Funktion legt Speicher für eine Listbox an und initialisiert die Objekte, indem sie die Routine <set> für jedes der in <objs> übergebenen Objekte aufruft. Die Listbox wird jedoch nicht gezeichnet!
Bit 0 der Variable <flags> legt fest, ob es sich um eine horizontale (das erste Listenelement ist links und das letzte rechts) oder vertikale (das erste Listenelement ist oben und das letzte unten) Listbox handelt. Unabhängig von dieser Hauptscrollrichtung kann die Listbox noch einen zweiten Slider haben, wenn die Elemente selber noch gescrollt werden sollen. Das kann z.B. bei einer vertikalen Listbox mit Textelementen, die breiter als die Box sind, sinnvoll sein.
Deklaration: LIST_BOX *lbox_create( OBJECT *tree, SLCT_ITEM slct, SET_ITEM set, LBOX_ITEM *items, WORD visible_a, WORD first_a, WORD *ctrl_objs, WORD *objs, WORD flags, WORD pause_a, void *user_data, DIALOG *dialog, visible_b, first_b, entries_b, pause_b ); Aufruf: box = lbox_create( tree, slct_item, set_item, item_list, 10, 0, ctrl_objs, objs, lbox_flags, 20, 0L, 0L, 10, 0, 40, 5 ); Variable Belegung Bedeutung Eingaben: contrl[0] 170 lbox_create contrl[1] 4 oder 8 Einträge in intin contrl[3] 8 Einträge in addrin intin[0] visible_a Anzahl der sichtbaren Einträge (Slider A) intin[1] first_a Index des ersten sichtbaren Eintrags (Slider A) intin[2] flags diverse Flags intin[3] pause_a Verzögerung beim Scrolling in ms (Slider A) intin[4] visible_b Anzahl der sichtbaren ELemente (Slider B) intin[5] first_b erstes sichtbares Element (Slider B) intin[6] entries_b Anzahl der Elemente (Slider B) intin[7] pause_b Verzögerung beim Scrolling in ms (Slider B) addrin[0] tree Zeiger auf den Objektbaum des Dialogs addrin[1] slct Zeiger auf Auswahl-Routine addrin[2] set Zeiger auf Setz-Routine addrin[3] items Zeiger auf verkettete Liste mit LBOX_ITEMs addrin[4] ctrl_objs Zeiger auf ein Feld mit den Objektnummern der Buttons und Slider (5 Einträge) addrin[5] objs Zeiger auf ein Feld mit den Objektnummer der Listbox-Einträge (<entries> Einträge) addrin[6] user_data Zeiger für Applikation addrin[7] dialog Zeiger auf die Fensterdialog-Struktur oder 0L Ausgaben: contrl[2] 0 Einträge in intout contrl[4] 1 Einträge in addrout addrout[0] box Zeiger auf die Listbox-Struktur oder 0L
Sowohl <slct> als auch <set> sind Funktionen, deren Parameter auf dem Stack übergeben werden. Die Funktionen dürfen Register d0-d2/a0-a2 verändern.
<slct> ist ein Zeiger auf eine Auswahl-Routine, die immer dann aufgerufen wird, wenn ein Eintrag selektiert oder deselektiert wurde:
typedef void (cdecl *SLCT_ITEM)( LIST_BOX *box, OBJECT *tree, struct _lbox_item *item, void *user_data, WORD obj_index, WORD last_state );
<box> | zeigt auf die Listbox-Struktur |
<tree> | zeigt auf den Objektbaum des Dialogs |
<item> | zeigt auf die LBOX_ITEM-Struktur des ausgewählten |
Eintrags | |
<user_data> | ist der bei lbox_create() übergebene Zeiger |
<obj_index> | ist die Nummer des angewählten Objekts. Bei einem |
Doppelklick ist ähnlich wie nach form_do() das oberste | |
Bit gesetzt. Wenn <obj_index> 0 ist, heißt das, daß dem | |
Eintrag kein Objekt zugeordnet ist; er ist nicht sicht- | |
bar. Normalerweise ist das nur der Fall, wenn gescrollt | |
wird und durch Auswahl eines neuen Objekts die | |
(mittler weile nicht mehr sichtbare) Selektion gelöscht | |
werden muß. | |
<last_state> | ist der vorhergehende Status des Objekts. <last_state> |
kann auch den gleichen Wert wie <item->selected> haben. | |
In diesem Fall kann die Funktion <slct> normalerweise | |
sofort verlassen werden. |
<slct> wird auch dann aufgerufen, wenn die Selektion eines Objekts aufgehoben wird! Die Variable <selected> aus der LBOX_ITEM-Struktur enthält beim Aufruf von <slct> bereits den neuen Status des Objekts.
<set> zeigt auf die Funktion, die den Inhalt eines LBOX_ITEMs in ein Objekt des Listbox-Dialogs eintragen soll:
typedef WORD (cdecl *SET_ITEM)( LIST_BOX *box, OBJECT *tree, struct _lbox_item *item, WORD obj_index, void *user_data, GRECT *rect, WORD first );
<box> | zeigt auf die Listbox-Struktur |
<tree> | zeigt auf den Objektbaum des Dialogs |
<item> | zeigt auf die LBOX_ITEM-Struktur des zu setzenden |
Eintrags | |
<obj_index> | ist die Nummer des zu setzenden Objekts |
<user_data> | ist der bei lbox_create() übergebene Zeiger |
<rect> | ist der Zeiger auf das GRECT für das Objekt Redraw |
oder 0L | |
<first> | enthält die Nummer des ersten sichtbaren Elements |
für Slider B |
Bei einer Listbox, die nur Text-Strings enthält, ist <set> typischerweise eine Funktion, die ein String, auf den die LBOX_ITEM-Struktur verweist, in das Objekt <index> kopiert.
<rect> ist 0L, wenn ein Redraw der Dialogbox durchgeführt wird oder wenn lbox_update() aufgerufen wurde.
<rect> ist nicht 0L, wenn der Anwender ein Objekt selektiert oder deselektiert hat, und zeigt auf das GRECT für den Redraw. Der Rückgabewert von <set> ist die Nummer des Startobjekts für objc_draw()/wdlg_redraw(). Bei Einträgen in der Listbox, die aus mehreren Objekten bestehen, ist es manchmal sinnvoll bei Selektion/Deselektion eines Objekts das Redraw-Rechteck zu verkleinern oder das Startobjekt zu ändern, um unnötige Zeichenoperationen und unnötiges Geflacker zu vermeiden.
In den meisten Fällen rufen die Listbox-Routinen nach <set> die Funktion objc_draw()/wdlg_redraw() auf, um den geänderten Inhalt anzuzeigen.
<first> enthält die Nummer des ersten sichtbaren Elements für Slider B, wenn die Listbox 2 Slider hat. Bei einer (vertikalen) Listbox mit Text-Strings und zwei Slidern gibt man z.B. beim Aufruf von lbox_create() die Anzahl der sichtbaren Zeichen in <visible_b>, die gesamte Stringlänge in <entries_b> und den Index des ersten sichtbaren Zeichens in <first_b> an. Wird der Text horizontal gescrollt, wird <set> für alle sichtbaren Strings aufgerufen und der Bereich neugezeichnet bzw. verschoben. Wenn die Listbox nur einen Slider hat, ist <first> immer 0.
<items> zeigt auf das erste Element einer Liste aus LBOX_ITEMs. Die für die Elemente verwendete Struktur muß als erstes Element einen Zeiger auf den Nachfolger enthalten (next) und als zweites ein Wort für den Zustand (selected):
typedef struct _lbox_item { struct _lbox_item *next; /* Zeiger auf den nächsten Eintrag in der Liste */ WORD selected; /* gibt an, ob das Objekt selektiert ist */ WORD data1; /* Daten für das Programm... */ void *data2; void *data3; } LBOX_ITEM;
Die Struktur kann aber, wenn bei den Aufrufen entsprechend gecastet wird, durchaus wie das folgende Beispiel aussehen:
typedef struct { void *next; WORD selected; ... ab hier nach Belieben der Applikation... } LB_EXAMPLE;
<ctrl_objs> ist ein Zeiger auf ein Feld mit 5 bzw. 9 Einträgen, das die Nummern der Kontroll-Objekte (Buttons) enthält:
ctrl_objs[0]: | Objektnummer der BOX oder IBOX, die die eigentlichen |
Listbox-Objekt enthält. | |
ctrl_objs[1]: | Objektnummer des Buttons für das Scrolling nach oben |
bzw. links. | |
ctrl_objs[2]: | Objektnummer des Buttons für das Scrolling nach unten |
bzw. rechts. | |
ctrl_objs[3]: | Objektnummer der Box des Slider-Hintergrunds. |
ctrl_objs[4]: | Objektnummer der Slider-Box. |
Falls die Listbox 2 Slider hat, enhalten ctrl_objs[5-8] die Nummern der Objekte von Slider B:
ctrl_objs[5]: | Objektnummer des Buttons für das Scrolling nach oben |
bzw. links. | |
ctrl_objs[6]: | Objektnummer des Buttons für das Scrolling nach unten |
bzw. rechts. | |
ctrl_objs[7]: | Objektnummer der Box des Slider-Hintergrunds. |
ctrl_objs[8]: | Objektnummer der Slider-Box. |
Die Buttons, der Slider und der Slider-Hintergrund sollten TOUCHEXIT-Status haben. Wenn die Listbox nur die Buttons und keinen Slider hat, müssen ctrl_objs[3/4 bzw. 7/8] -1 enthalten.
<objs> ist ein Feld mit <entries> Einträgen, das die Nummern der Listbox- Objekte enthält (die Objekte sind normalerweise Kinder von ctrl_objs[0]).
objs[0]: Nummer des ersten Objekts . . . objs[entries - 1]: Nummer des letzten Objekts
Die Objekt sollten normalerweise TOUCHEXIT-Status haben.
Das Wort <flags> beeinflußt das Verhalten der Listbox:
Bit | Zustand | Beschreibung |
0 | 0 | Die Box scrollt horizontal. |
1 | Die Box scrollt vertikal. | |
1 | 0 | kein automatisches Scrolling |
1 | Es wird autmatisch gescrollt, sobald bei gedrückter | |
Maustaste der Mauszeiger über das erste oder letzte | ||
Element hinausbewegt wird. | ||
2 | 0 | Die Auswahl-Routine wird erst aufgerufen, wenn das |
automatische Scrolling aufgehört hat, d.h. sie wird | ||
für den letzten selektierten Eintrag aufgerufen. | ||
1 | Beim automatischen Scrolling wird die Auswahl-Routine | |
beim Scrolling für jeden selektieren Eintrag aufge- | ||
rufen. | ||
3 | 0 | Bei Bewegung des Sliders wird ein Rahmen verschoben |
(graf_slidebox), die Listbox wird erst nach Loslassen | ||
der Maustaste aktualisiert. | ||
1 | Der Slider ist ein Real-Time-Slider. | |
4 | 0 | Mehrfachselektion innerhalb der Listbox ist möglich. |
1 | Es kann nur ein Element selektiert werden. | |
5 | 0 | Mehrfachselektion ist ohne Shift-Taste möglich. |
1 | Mehrfachselektion ist nur mit Shift-Taste möglich. | |
6 | 0 | Bei Selektion ist der Status immer SELECTED |
1 | Bei Selektion wird der Status immer gewechselt | |
7 | 0 | Listbox hat nur einen Slider |
1 | Listbox hat zwei Slider |
#define LBOX_VERT 1 /* Listbox mit vertikalem Slider */ #define LBOX_AUTO 2 /* Auto-Scrolling */ #define LBOX_AUTOSLCT 4 /* automatische Darstellung beim Auto-Scrolling */ #define LBOX_REAL 8 /* Real-Time-Slider */ #define LBOX_SNGL 16 /* nur ein anwählbarer Eintrag */ #define LBOX_SHFT 32 /* Mehrfachselektionen mit Shift */ #define LBOX_TOGGLE 64 /* Status eines Eintrags bei Selektion wechseln */ #define LBOX_2SLDRS 128 /* 2 Slider unterstützen */
Das Flag LBOX_SNGL kann auch mit LBOX_SHFT oder LBOX_TOGGLE kombiniert werden, um in einer Listbox mit nur einem anwählbaren Eintrag auch Deselektion zu ermöglichen. LBOX_SNGL + LBOX_SHFT bedeutet, daß der selektierte Eintrag durch Klick mit gedrückter Shift-Taste deselektiert werden kann. LBOX_SNGL + LBOX_TOGGLE bewirkt bei einem Klick auf einen selektierten Eintrag dessen Deselektion.
Der Zeiger <items> kann auch 0L sein, wenn die Listbox noch leer ist und keine Einträge enthält.