VOICE Homepage: http://de.os2voice.org |
Dezember 2002
[Inhaltsverzeichnis]
|
Von Thomas Klein © Dezember 2002 |
Ein herzliches "Willkommen zurück" von jemandem, der noch immer überwältigt ist von den Eindrücken der diesjährigen Warpstock Europe! Diesen Monat wird uns DrDialog einen Einblick in die Grundlagen der GUI-Entwicklung (mit REXX) geben, denn wir schauen uns die Komponenten an, die zum Standardumfang einer jeden grafischen Benutzeroberfläche gehören - ungeachtet der Plattform.
Aber zuerst kümmern wir uns um die 'Hausaufgaben' von letztem
Monat... wie man REXXs strip()
-Funktion verwendet,
um führende/folgende Leerzeichen aus einer
Zeichenkette zu entfernen. Wie in der Hilfedatei REXX.INF bereits
angegeben ist, lautet die Syntax:
STRIP(String1 [,option] [,zeich])
Zur Erinnerung - eckige Klammern bezeichnen optionale Argumente:
[zeich]
gibt das
Zeichen an, das aus String1
entfernt werden soll, und ist standardmäßig SPACE
(also das Leerzeichen) - wenn Sie also hier kein Zeichen explizit
angeben, wird strip()
Leerzeichen
entfernen.
[option]
ist
ein optionaler Befehl, mit dem Sie angeben können, welche Art des
angegebenen Zeichens aus String1
entfernt werden soll: Führende ("Leading"), Folgende ("Trailing")
oder Beide ("Both"). Von diesem Befehl muß nur der erste Buchstabe
angegeben werden (z.B. "L" für 'leading'; also 'führende'
Zeichen). Die Standardvorgabe für diesen Parameter ist 'Both' und strip()
entfernt damit
sowohl führende als auch folgende Zeichen vom Typ [zeich]
. Fassen wir es
kurz:
Wenn Sie führende und folgende Leerzeichen aus String1
entfernen
wollen, brauchen Sie nur anzugeben:
STRIP(String1)
Da es sich bei strip()
um eine Funktion handelt, gibt es auch einen Rückgabewert. Genau
genommen gibt sie die Zeichenkette zurück, die (in unserem Fall)
von den Leerzeichen befreit wurde. Wir müssen also entweder eine
Variable angeben, die den Rückgabewert entgegennimmt
NEUSTRING = STRIP(String1)
oder sie im Rahmen einer anderen Anweisung einsetzen, wie bspw. SAY
die lediglich das Ergebnis anzeigt wie in
SAY STRIP(String1)
Un um zu verdeutlichen, wie das im Rahmen unseres letztmonatigen Beispiels auszusehen hätte, hier die Version 1 mit 'Zwischenvariablen':
Grusstext = Auswahl.Item( Auswahl.Select() )
Grussname = strip( Eingabe.Text() )
call ausgabe.text( Grusstext || " " || Grussname || "." )
...oder...
Grusstext = Auswahl.Item( Auswahl.Select() )
Grussname = Eingabe.Text()
call Ausgabe.text(Grusstext || " " || strip( Grussname ) || ".")
Zu guter letzt noch Version 2, die (falls Sie dies bevorzugen) dasselbe mittels des 'spektakulären' Einzeilers macht:
call Ausgabe.text( Auswahl.Item( Auswahl.Select() ) || " " || strip( Eingabe.text() ) || "." )
So weit so gut. Wenn Sie Ihre REXX-Programmierungskenntnisse
ausbauen, werden Sie strip()
wahrscheinlich etwas häufiger
über den Weg laufen. Lassen Sie uns aber nun auf das konzentrieren,
was wir heute eigentlich besprechen wollten:
Wie ich letzten Monat bereits bemerkte, kann die Darstellung je nach Plattform unterschiedlich ausfallen. In den meisten Fällen werden Sie diese Komponenten aber immer daran wiedererkennen können, wie Darstellung und Verhalten miteinander 'verzahnt' sind... es handelt sich um:
Anm.: Wir werden hier absichtlich die englischen Begriffe verwenden, da innerhalb von DrDialog auch diese Bezeichnungen verwendet werden.
Natürlich gibt es eine Vielzahl weiterer Komponenten, aber diese hier stellen den absolut kleinsten 'gemeinsamen Nenner' dar, wenn man OS/2 Warp, Windows (3.x bis 2K) und die Macs in Betracht zieht. Für das Linux-GUI und BeOS kann ich es nicht mit Sicherheit sagen, da ich mich nie getraut habe, es mir so genau anzuschauen <g>, aber wenn's dort ein GUI gibt, hat es mit Sicherheit (auch) diese Bestandteile. Sogar in Java oder der 'Formulardarstellungen' Ihres Webbrowsers werden Sie diese Komponenten wiederfinden! Und zu Zeiten von DOS, als man begann, die Bildschirmmasken von zeichenorientierten Programmen mit 'einer Art' von GUI auszustatten, waren sie bereits präsent in Produkten wie den Norton Utilities oder PCTools.
Nun, die meisten unter uns benutzen diese
Komponenten schon sehr lange fast intuitiv, ohne sich darüber
großartige Gedanken zu machen. Wahrscheinlich haben Sie sogar
schon ein gutes "Gespür" dafür, welche Komponenten man
einsetzen würde, um bestimmte Anforderungen umzusetzen. Aber lassen
Sie mich Ihnen sagen, daß gesunder Menschenverstand in der
Programmierung von grafischen Oberflächen scheinbar doch nicht
jedem einfach so in die Wiege gelegt wird. ;) So gibt es da
draußen einige lustige Zeitgenossen, die lustige Sachen mit
GUI-Komponenten veranstalten und sich dabei nicht im geringsten durch
die ungeschriebenen Gesetze der 'GUI-Ethik' einschüchtern lassen.
Eines von vielen klassischen Beispielen dafür ist 'Optionbutton
oder Checkbox'.
Im Grunde sind 'option buttons' dafür da, sich gegenseitig
ausschließende Optionen zu kennzeichnen - solche also, bei denen
man sich immer nur für eine entscheiden kann. Daher werden diese
Komponenten auch RADIO BUTTONS genannt, in Anspielung an
die Stations- oder Modulationsauswahlschalter an den alten Radios: Wenn
man einen davon nach unten drückte, sprang der vorher
gedrückte Knopf wieder zurück nach oben. Ein typisches
Beispiel für den Einsatz von radio buttons wäre folgende Frage:
Die 'checkbox' wiederum dient zur Kennzeichnung von Optionen, die man beliebig und unabhängig voneinander kombinieren kann, beispielsweise:
Was nun die angesprochenen Zeitgenossen so 'lustig' macht, ist Ihre totale Ignoranz hinsichtlich der eingebauten Logik von Verhalten, Aussehen und Benutzersteuerung, die sich bereits in den Komponenten verbirgt. Natürlich steht es Ihnen frei, sich sämtlicher Möglichkeiten zu bedienen, die Ihnen durch den Einsatz dieser Komponenten zur Verfügung stehen. Wenn Sie sich das Leben unnötig schwer machen wollen, können Sie auch eine Gruppe von radio buttons auf Basis von checkboxen zusammenstricken... dennoch gibt es Sachen, die man besser vermeiden sollte wie...
links: Scheinbar ein Programmierer, der einer strengen Validierung den Vorzug gibt vor dem Einsatz der geeigneten Komponente, die das bereits in sich trägt. Zwei radio buttons, von denen einer standardmäßig vorgewählt ist, hätten einiges an 'code-Arbeit' erspart...
unten: Eine meiner bevorzugten 'Schwachsinns-GUI's. Um deren "Hirnrissigkeit" in Gänze verstehen zu können, habe ich noch nicht einmal den Einsatz einer kleinen Animation gescheut:
Ziemlich leicht zu benutzen - die Default
-Option
im Style-Dialog eines pushbuttons bewirkt, daß die
Schaltfläche das Drücken der <ENTER>-Taste
in einem Dialogfenster 'abfängt', auch wenn die Schaltfläche
gar nicht das aktive control ist. No pointer focus
verhindert, daß das kleine 'focus'-Rähmchen um die Aufschrift
der Schaltfläche nicht gezeichnet wird, wenn man mit der Maus auf
diese Schaltfläche geklickt hat. Wurde die Schaltfläche
mittels <TAB>-Taste
angewählt, wird der 'focus' nach wie vor angezeigt.
No border
bewirkt, daß die Schaltfläche fast wie eine
Textbox aussieht - mit dem Unterschied, daß der 'Versatzeffekt'
beim Anklicken bestehen bleibt.
Man glaubt es kaum: Es gibt
tatsächlich ein click
-Ereignis für pushbuttons! ;)
Davon abgesehen gibt es das INIT
-Ereignis, das wir
bereits aus unserem Textbox-Beispiel kennen und ein Ereignis namens DROP
,
welches immer dann ausgelöst wird, wenn ein anderes DrDialog-Objekt
auf die Schaltfläche gezogen und abgelegt wurde. Drag-und-Drop
(Ziehen und Übergeben) erfordert allerdings noch ein paar andere Dinge und
obwohl 'DnD' sehr nützlich und mit DrDialog leicht zu
bewerkstelligen ist, werden wir uns seiner zu einem späteren
Zeitpunkt widmen.
Mit DrDialog wirklich einfach zu
benutzen: Im Grunde kann eine checkbox ("Ankreuzkästchen") sich in
einem von 3 verschiedenen Zuständen befinden:
unchecked
(nicht angekreuzt), checked
(angekreuzt)
und undetermined
(unbestimmt), bei dem die
Ankreuzfläche grau schattiert dargestellt wird. In den meisten
Fällen werden aber die zwei Zustände checked/unchecked
reichen. Wenn Sie tatsächlich den dritten Zustand 'unbestimmt'
benötigen, wählen Sie im Style-Dialog der checkbox die Option
3state aus. Die weitere
Bearbeitung von Events (Ereignissen) gestaltet sich äußerst
einfach (da nämlich keine nötig ist), wenn Sie die
Option Auto aus dem
Style-Dialog der checkbox verwenden, was standardmäßig auch
der Fall ist.
Hierdurch bewegt sich die checkbox bei jedem Klick automatisch zwischen
den Zuständen hin und zurück (bzw. bei 3 Zuständen immer
reihum). Wenn Sie Auto deaktivieren,
müssen Sie sich selbst um die benötigte Programmlogik auf
Basis des Click-Ereignis bemühen. Beachten Sie, daß der
Zustand undetermined
nur dann zur Verfügung steht, wenn die Option
3state aktiviert wurde. Auch
'manuelle Anweisungen' im Programmcode können dies dann nicht
bewerkstelligen - die Box wird dann schlicht angekreuzt. Der zu einer
checkbox angezeigte Text wird entweder über die Auswahl
TEXT im Kontextmenü zur
Entwicklungszeit oder mittels der Funktion/Anweisung TEXT()
zur Laufzeit festgelegt, wie wir das bereits im letzten Monat mit
unserer Textbox kennengelernt haben.
Wie alle anderen controls, so erzeugt
auch die CHECKBOXES ein DROP
Ereignis, wenn man ein Objekt
darauf ablegt. Da wir Drag-und-Drop etwas später in dieser Serie
besprechen werden, bleiben noch zwei Ereignisse übrig: INIT
(kennen wir schon, oder?) und CLICK
. Das CLICK
-Ereignis
ist dann sehr nützlich, wenn man eine bestimmte Abhängigkeit von
Optionsgruppen darstellen will, wenn diese ansonsten zu
unübersichtlich geraten würden... ich versuche mal, ein
Beispiel anhand einer Animation zu geben:
Sowohl das Abfragen als auch das Setzen
des Status einer checkbox wird mittels der
SELECT
-Methode bzw. Eigenschaft
erledigt. Um den Status einer checkbox abzufragen (also, ob Sie
angekreuzt ist oder nicht), verwenden Sie einfach
SELECT
in der 'funktionalen' Schreibweise
zustand = meineCheckBox.select()
wodurch zustand
dann
entweder 0 (null) enthält, wenn die checkbox nicht angekreuzt ist, respektive 1
(eins), wenn sie es ist, - oder auch 2, wenn sie sich im 'unbestimmten'
Zustand befindet (und dies mittels der Option 3state
vorher auch
ermöglicht wurde). Wenn Sie den Zustand sofort auswerten wollen,
indem Sie z.B. etwas bestimmtes machen wollen, wenn die box angekreuzt
ist, können Sie das im Rahmen einer IF
-Anweisung tun wie z.B.:
if meineCheckBox.select() = 1 then say 'JA - wurde angekreuzt'
Um den Zustand einer checkbox aus dem Programm heraus zu setzen (z.B. anhand gespeicherter Einstellungen aus einer .INI-Datei), verwenden Sie 'Befehls'-Schreibweise:
call meineCheckBox.select 1
...wodurch die checkbox angekreuzt wird.
Analog zu den Rückgabewerten der Funktion, verwenden Sie hier den
Wert 0 (null) anstelle von 1 (eins) um die checkbox 'abzukreuzen' oder
2, wenn Sie den 'unbestimmten' Zustand setzen sollen. Letzteres geht wie
gesagt nur dann, wenn Sie im Style-Dialog die Option 3state
ausgewählt hatten. Das wär's schon zu den checkboxen.
Natürlich gibt es noch mehr Möglichkeiten, checkboxen zur
Laufzeit zu beeinflussen, wie die VISIBLE
-Funktion zum
Anzeigen/Verstecken oder das Aktivieren und Deaktivieren mittels der
Anweisungen ENABLE, DISABLE
oder die ENABLED
-Funktion,
aber dies betrifft alle Typen von controls und daher werden wir uns das
am Ende dieses Artikels nochmals im Detail anschauen.
Mit DrDialog ist das Verwenden von radio buttons spielend leicht. Alles, was Sie zur Entwicklungszeit machen müssen, um eine Gruppe von sich gegenseitig automatisch ausschließenden Optionen zu erstellen, ist, die gewünschten radio buttons in Reihe zu setzen - vorzugsweise untereinander, um eine bessere Übersichtlichkeit zu erreichen. Die Reihenfolge der Optionen (per <TAB>-Taste) wird von DrDialog zur Laufzeit automatisch anhand der IDs ermittelt.
Wenn Sie zwei (oder mehrere) unabhängige Gruppen von mehreren Optionen erreichen wollen, wird DrDialog dies aber nicht automatisch erkennen und alle radio buttons als Bestandteile einer einzelnen großen Gruppe ansehen... außer, Sie teilen ihm mit, wie sich die Gruppen jeweils zusammensetzen. Das erreichen Sie, indem Sie entweder
ein beliebiges anderes Element (wie eine einfache textbox) zwischen die Gruppen setzen | oder indem Sie einen 'Gruppe'-Rahmen um die jeweiligen Optionen ziehen, wenn Sie dies von seiner optischen Wirkung bevorzugen: |
Auch bei den radio buttons können Sie die Auto-Option im Style-Dialog deaktivieren, wenn Sie es bevorzugen, die "Drecksarbeit" selbst zu übernehmen. Wenn also Auto deaktiviert ist, müssen Sie sich um das an- und abwählen der einzelnen Optionen innerhalb einer Gruppe selbst kümmern - speziell, was das gegenseitige Ausschließen angeht. Viel Spaß, sage ich nur. Ansonsten übernimmt DrDialog die Aufgabe, immer nur eine einzelne Option innerhalb einer Gruppe wählbar zu machen, d.h. eine evtl. vorher ausgewählte Option abzuwählen.
Das läuft genau wie bei den
checkboxen: Click, Init
und Drop
.
Punkt. Die 'Zustände' sind aber noch einfacher zu kontrollieren als
bei den checkboxen, da wir es hier wirklich nur mit zwei Arten zu tun
haben, denn einen 'unbestimmten' Zustand gibt es bei den radio buttons
nicht. Gott sei Dank - ich frage mich, was unsere lustige Zeitgenossen
damit noch alles anstellen würden... um also den Zustand eines
radio buttons abzufragen, bedienen wir uns wieder der Funktion SELECT
:
zustand = meineOption1.select()
Luxus pur: Wird ein nicht
ausgewählter radio button zur Laufzeit mittels SELECT
angewählt, sorgt DrDialog dafür, daß ein vorher
angewählter anderer radio button der selben Gruppe automatisch
ABgewählt wird. Okay, macht
Sinn. Wenn Sie aber mittels SELECT einen bis dato
ANgewählten radio button
ABwählen, wird nicht etwa
automatisch ein anderer radio button angewählt. Im Grunde ist das
aber auch logisch, denn DrDialog kann ja nicht ahnen, welcher radio
button angewählt werden soll. Auch, wenn die Gruppe nur aus
zwei Optionen besteht, erfolgt kein automatisches anwählen der
anderen Option.... gut: Um den Zustand eines radio buttons zur Laufzeit
zu beeinflussen, verwenden wir SELECT
in der CALL-Notation und analog zu
den checkbox-Zuständen gilt auch hier wieder einfach 0 = abgewählt, 1 = ausgewählt:
call meineOption1.select 1
Damit wird meineOption1
ausgewählt
und alle anderen radio buttons, die sich in der selben Gruppe befinden,
wie meinOption1
, würden abgewählt. Eigentlich kümmert man
sich meisten nie um den Zustand eines einzelnen radio buttons, sondern
ist vielmehr daran interessiert, WELCHER radio button einer Gruppe
jeweils ausgewählt ist, nicht wahr? Tja - dafür gibt es in
DrDialog leider keinen eingebauten Weg, aber man kann z.B. allen
Optionen einen eindeutigen Wert zuordnen und mittels einer Variable sich
den Wert des jeweils gerade angeklickten radio button merken. Ein
anderer Weg ist, dieses Verfahren mittels der focus()
-Eigenschaft zu
verfeinern, aber das nehmen wir später durch...
Na, die kennen wir doch schon, oder? Wenn man sich die Optionen zur Textausrichtung ("Alignment") im Style-Dialog anschaut, könnte man nicht auf die Idee kommen, daß es dort irgendwelche versteckte Geheimnisse gibt... es gibt allerdings etwas, das man beachten sollte: Die Abhängigkeiten zwischen der Option Word break und der vertikalen Ausrichtung. Wenn Sie eine Textbox anlegen, die eine mehrzeilige Anzeige verwendet, müssen Sie die vertikale Ausrichtung TOP verwenden, sonst klappt es nicht. Schauen Sie sich einmal die beiden Abbildungen an, dann verstehen Sie was ich meine:
oben: Das ist korrekt - Text wird vollständig und mehrzeilig angezeigt / unten: Wegen des 'Vertical alignment'wird der Text nur auf einer Zeile (und somit unvollständig) angezeigt...
Die Option horizontal alignment hat allerdings keinen Einfluß auf
word break und funktioniert wie erwartet.
Um ein control 'deaktiviert' erscheinen zu lassen, können Sie die
Option Disabled in
dessen Style-Dialog aktivieren. Hierdurch reagiert das jeweilige
control dann nicht mehr auf benutzeraktionen und wird 'blass'
dargestellt. Sie können aber auch hier wieder alle Prinzipien des
GUI über Bord werfen ;-) und stattdessen die Option
Halftone verwenden, die ebenfalls den selben optischen Effekt
erzielt, das control selbst aber
AKTIV lässt. Das wäre unter Umständen dann von Nutzen,
wenn das control deaktiv aussehen, aber trotzdem auf die Aktion des
Benutzers reagieren soll. Allerdings kennt die textbox aber nur eine Art
von Benutzerereignis: Das Ablegen eines Objekts. Ich bin kein Freund
solcher Dinge wie das Auslösen einer Aktion mittels des Ablegens
eines Objekts auf ein deaktiviertes
control, aber... vielleicht teilen Sie nicht meinen ethischen Standpunkt
in GUI-Grundlagen. Vielleicht werden Sie aber auch irgendwann einmal mit
einer Situation konfrontiert, wo nur DAS Ihnen hilft - und da ist es
gut zu wissen, das so etwas zumindest möglich ist.
Im Gegensatz zu vergleichbaren controls
in anderen Entwicklungsumgebungen, erzeugt die textbox in DrDialog kein
click
-Ereignis... wozu
auch? Welchen Sinn soll es machen, auf einen Text zu klicken? Na gut -
jemand könnte einen URL-Link simulieren, indem er einen
unterstrichenen Text anzeigt und beim Klick darauf den Webbrowser
startet, aber das kann man sicher auch anders bewerkstelligen. Bleibt
also nur nur das INIT
-Ereignis,
das wir schon kennen und das DROP
-Ereignis, welches
wir später besprechen werden.
Zur Textausrichtung brauche ich - glaube ich - nichts zu sagen. Schauen wir uns lieber einmal die anderen Sachen an, mit denen man lustige Verhaltensweisen erreichen kann: Von der Option Auto scroll zum Beispiel sollte man meiner Meinung tunlichst die Finger lassen. Wenn Ihre Eingaben länger sind als die Anzeigegröße eines entry fields, dann sorgt diese Option in ihrem aktivierten Standardzustand nämlich dafür, daß der Inhalt eines entry fields immer so verschoben wird, daß man sehen kann, was man gerade tippt. Wird diese Option deaktiviert, müssen Sie Ihre Eingaben 'blind' tätigen. Lustig. ;)
Die Option read only ist relativ selbsterklärend, jedoch auch nennenswert: Wenn Sie ein entry field mittels 'disabled' deaktivieren, werden dessen Inhalte in 'halftone' dargestellt, was manchmal zu einer sehr schlechten Lesbarkeit führt. Wenn Sie also erreichen wollen, daß man in einem entry field zwar nichts eingeben, dessen Inhalte dafür aber zumindest vernünftig lesen kann, ist read only genau die Option Ihrer Wahl.
Margin (Rand) gibt lediglich an, ob ein Rand um das Eingabefeld gezogen werden soll und ist nicht zu verwechseln mit dem Begriff 'margin', der normalerweise Textränder betrifft (was der Grund dafür ist, daß ich denke, 'margin' war eine schlechte Wahl verglichen mit 'border'... aber jetzt wissen Sie ja, was es bedeutet).
Unreadable bewirkt, daß Sternchen anstelle der vom Anwender eingegebenen Zeichen angezeigt werden. Also der sogenannte 'Passworteingabe-Effekt'. Aber das ist noch nicht alles: Haben Sie schon einmal versucht, den Inhalt eines 'passwortfeldes' mittels Kopieren und Einfügen in - beispielsweise - den Editor zu übertragen? Das geht nicht. Glücklicherweise. Ich kenne einige 'handgestrickte' Dialoge, die das nicht berücksichtigten - was zu einer lächerlichen Farce von Sicherheit führte... glücklicherweise ist das mit DrDialog (und allen anderen Entwicklungstools, die mir begegnet sind) nicht so und das Kopieren eines eingegebenen Texts wird unterbunden, wenn die Option unreadable verwendet wird. Das Einfügen von Text in ein solch definiertes feld ist allerdings natürlich nach wie vor möglich.
Auto tab und Max length spielen auf
bestimmte Art und Weise zusammen:
Max length gibt die maximale
Länge des eingebbaren Texts an. Wird hier beispielsweise 5
angegeben, kann der Anwender keine Eingabe machen, die mehr als 5
Zeichen lang ist (Leerzeichen eingeschlossen). Wenn
zusätzlich Auto tab
ausgewählt wurde, springt der Cursor automatisch in das
nächste Feld oder das nächste Control, wenn die angegebene
Höchstgrenze an Zeichen erreicht wurde. Beispiel:
Sie haben ein Bestellformular entwickelt. Im ersten Feld muß eine
5-stellige Artikelnummer eingegeben werden, dann eine Mengenanzahl und
schließlich der Stückpreis. Wenn Sie für das
Artikelnummerfeld die Option auto tab setzen, braucht der Anwender nach Eingabe der
fünfstelligen Artikelnummer nicht mittels <TAB>-Taste oder Mausklick
in das nächste Feld zu wechseln, sondern DrDialog steuert das
automatisch anhand der ID-Nummer der Felder. Eine extrem nützliche
Funktionalität für Datenerfassungsdialoge!
DBCS bedeutet 'double byte character set' und bezeichnet Zeichensätze, bei denen zwei Byte für die Speicherung eines Zeichens verwendet werden, wie z.B. für Chinesisch. SBCS (single byte character set) ist das, was wir im Allgemeinen gewohnt sind: Zeichensätze, die nur 1 Byte benötigen, um einen Buchstaben (oder ein beliebiges anderes Zeichen) zu speichern. Die SBCS/DBCS-Optionen werden wir später noch besprechen - vorausgesetzt ich finde jemanden, der erst einmal MIR beibringt, um was es da genau geht - sorry.
Abgesehen von den Ereignissen INIT
und
DROP
gibt es noch andere
Ereignisse, die durchaus interessant an den Eingabefeldern sind:
OVERFLOW
zum Beispiel wird
dann ausgelöst, wenn der Anwender im Eingabefeld eine Taste
gedrückt hat, durch die der Inhalt länger würde, als durch
die Option Max Length (die wir gerade besprochen hatten) festgelegt.
Changed
wird immer
ausgelöst, wenn sich der Inhalt des Eingabefelds geändert hat.
Das betrifft wohlgemerkt aber nur den Inhalt des Feldes - so würde
dieses Ereignis nicht ausgelöst, wenn der Anwender beispielsweise
nur einen Bereich des eingegebenen Textes markiert hätte.
Scrolling
ist
witzig: Dieses Ereignis tritt ein, wenn der Inhalt des Eingabefelds
verschoben wird, um dem Anwender seine aktuelle Schreibposition
ersichtlich zu machen. Witzig daran ist die Tatsache, daß das
"scrollen" nicht zeichenweise ein ums andere mal geschieht, sondern in
'Häppchen' zu je drei Zeichen. Momentan habe ich keine Ahnung, wozu
man dieses Ereignis nutzen könnte. Hm.
Für GetFocus
und LoseFocus
muss ich etwas weiter ausholen: Der focus ist eine Art systemeigener
Kenner, der angibt, welches control gerade innerhalb eines Dialoges
aktiv ist und somit die primäre Steuerung übernimmt.
Vielleicht haben Sie schon einmal das kleine, aus einer gepunkteten
Linie bestehende Rechteck bemerkt, welches sich z.B. um den Text einer
Schaltfläche herum befindet... das ist die Kennzeichnung
dafür, daß diese Schaltfläche das momentan aktive
control ist ("den Fokus hat"). Das Ereignis
GetFocus
tritt nun auf, wenn Ihr
Eingabefeld soeben zum aktiven control geworden ist, weil der Anwender
entweder mit der <TAB>-Taste dorthin gewechselt hat oder den Mauszeiger
auf das Feld bewegt und dann geklickt hat. Häufig wird dieses
Ereignis dafür verwendet, den gesamten gerade enthaltenen Text des
Feldes auszuwählen (das Drücken einer Taste wird dann zuerst
den 'alten' Inhalt des Feldes löschen). Das
LoseFocus
-Ereignis wiederum
tritt ein, sobald der Anwender per Tastatur oder Maustaste ein anderes
control angewählt hat. Es wird normalerweise verwendet, um eine
Prüfung der im Feld eingegebenen Daten vor deren weiterer
Verarbeitung durchzuführen (z.B. Datumsformat prüfen).
Die Steuerung und Verwendung eines entry fields aus dem Programmcode
heraus ist nicht allzu schwer, da Sie ohnehin meist nur die Funktion text()
benutzen
werden. Mittels der Funktion RANGE
können Sie zur
Laufzeit das machen, was Sie zur Entwicklungszeit mittels der Option Max length
machen, nämlich die maximale Eingabelänge festlegen (oder abfragen).
Dies ist ganz nützlich, denn ansonsten müssten Sie dies durch
entsprechendes Setzen der Bits in der Style-Maske tun, was ein wenig
unkomfortabel ist. Um beispielsweise zur Laufzeit den Wert
für max length auf 12 zu setzen, geben Sie an:
call meineEingabe.RANGE 12
Aber es gibt noch eine weitere Funktion,
die hier auf jeden Fall besprochen werden muß: Select
.
Hierbei handelt
es sich um den Teil des Textfelds, der markiert wurde. Der Anwender kann
einen Bereich des Eingabetextes (oder den ganzen Text)
mittels der Umschalttaste markieren, wenn er gleichzeitig die Maus
darüber bewegt oder die Cursortasten drückt. Und das ist es,
worum es sich bei SELECT
dreht - der Programmierer kann
damit den markierten Bereich des Texts
ermitteln, denn es werden zwei Werte geliefert: Der Index des ersten
markierten Zeichens (1 ist der erste Buchstabe im Eingabefeld usw.)
sowie die Gesamtanzahl der markierten Zeichen.
Wenn der Anwender beispielsweise den Teil 'all'
aus dem Wort
'Hallo'
markiert hätte, würde die Funktion
SELECT
zurückgeben: '2 3' (ohne die Hochkommata).
Wie immer, so verwenden Sie auch SELECT
anhand seiner
CALL-Aufrufart um den ausgewählten Bereich eines Eingabefeldes zu
setzen. Alles, was Sie angeben müssen, sind die Stelle des ersten
markierten Zeichens im Eingabefeld und die Gesamtanzahl der markierten
Zeichen (= die Länge). Wenn Sie als Länge 0 (null) angeben,
wird der komplette Inhalt de-markiert. Um den gesamten Inhalt eines
entry fields namens meineEingabe
zu markieren, verwenden Sie:
call meineEingabe 0, 9999
Beachten Sie, daß beim
Übergeben der Werte im Rahmen des Aufrufs ein Komma verwendet
werden muß, wohingegen die Rückgabe der beiden Werte kein Komma
enthält. Die Parameter '0,9999'
stammen aus dem
Beispiel in DrDialogs Onlinehilfe. Gut, es funktioniert, aber eigentlich
macht man so etwas anders, nämlich indem man die REXX-Funktion
LENGTH()
verwendet:
call meineEingabe.SELECT 1, length( meineEingabe.text() )
Hier wird beim Aufruf die Länge des
Inhalts von meineEingabe
als Längenangabe für die Markierung verwendet. So beginnt die
Markierung auf Stelle 1 und ist immer genau so lang, wie der momentane
Inhalt - kein Byte zu wenig, keins zu viel. ;)
MLE's ("multi line edit fields") sind eigentlich nur gewöhnliche Eingabefelder mit speziellen Zusätzen, damit Sie mit Zeilenumbrüchen und mehrzeiligen Texten umgehen können:
Beachten Sie, daß es mitunter Kombinationen gibt, die nicht unbedingt Sinn machen: Wenn man beispielsweise word wrap aktiviert, so wird der Inhalt des MLE immer so umgebrochen, daß er in dessen momentane Anzeigegröße paßt. In diesem Fall benötigt man also eigentlich keine horizontale Scrollbar. Aber egal, es gibt etwas wichtigeres für den Gebrauch von MLEs: Die Option ignore tab. Das MLE besitzt die Fähigkeit, Tabulatorzeichen einzusetzen, um den Text zu formatieren. Wurde diese Option aktiviert, wird das Drücken der <TAB>-Taste nicht mehr vom MLE zum Einfügen eines Tabulatorzeichens verwendet, sondern (standardgemäß) um von einem Control zum nächsten zu wechseln (den 'Fokus' verändern).
Da es für MLEs keine max length-Option gibt,
existiert auch kein OVERFLOW
-Ereignis. Und
da MLEs primär zur Verarbeitung von mehrzeiligem Text dienen,
haben sie von Hause aus Scrollbars und lösen somit kein
SCROLL
-Ereignis aus.
Übrig bleiben also INIT, CHANGED, GetFocus, LoseFocus
und
DROP
, die wir ja vom 'normalen'
entry field kennen. Bei den Funktionen sieht es ebenfalls genau so aus,
wie bei den entry fields, mit Ausnahme von RANGE
und
SELECT
: Für MLEs gibt es sie nicht.
Einer der wichtigsten Aspekte beim Arbeiten mit Listboxen ist ihr SELECTION-Style: Normalerweise kann man innerhalb einer Liste immer nur einen Eintrag auswählen. Das ist der Fall, wenn man die Option single angegeben hat. Die Option multiple ermöglicht es dem Anwender, mehr als nur einen Eintrag in der Liste auszuwählen, indem er die Einträge mittels Anklicken oder dem Drücken der Leertaste an- bzw. abwählt. Die Option extended ermöglicht es zusätzlich noch, ganze Bereiche von Einträgen mittels der Umschalttaste an/abzuwählen (oder einzelne Einträge ohne die vorherige Selektion zu verlieren mittels der Strg-Taste). Beachten Sie, daß beide Optionen sowohl einzeln als auch zusammen verwendet werden können.
Owner draw deaktiviert den Standardmodus von DrDialog, die Einträge der Liste darzustellen, wodurch die Liste selbst nach dem Hinzufügen von Einträgen immer noch leer erscheint. Das 'Anzeigen' von Einträgen bleibt nun dem Entwickler überlassen. Ich glaube, daß es sich hierbei um eine Funktionalität handelt, die erst in Zusammenhang mit anderen Entwicklungsumgebungen richtig nutzbar ist, denn DrDialog kann auch dazu eingesetzt werden, 'nur' die Dialogdefinitionen zu generieren, die dann von anderen Entwicklungstools benutzt werden können. Lassen wir diese Option erst einmal außer Acht... ;)
Eine horizontal scroll bar ist dann serh nützlich, wenn der freie Platz auf Ihrem Dialog nicht ausreicht, um die Liste so 'breit' zu gestalten, daß deren Einträge vollständig lesbar sind. Vertikale Bildlaufleisten werden von Listboxen grundsätzlich zur verfügung gestellt und sind aktiv, sobald mehr Einträge in der Liste sind, als gleichzeitig angezeigt werden können.
Abgesehen von INIT
, dem üblichen
FOCUS
-Kram und DROP
, gibt es drei Ereignisse,
die man mit Listboxen verwenden kann:
SCROLL
SELECT
ENTER
Als Funktionen stehen in erster Linie ADD
(hinzufügen) und
DELETE
(Löschen) zur
Verfügung, mit denen der Inhalt der Listbox bestimmt werden kann.
Beachten Sie, daß keine automatische Sortierung der Listeninhalte
stattfindet. Um eine bestimmte Sortierreihenfolge zu erzielen,
müssen beim Hinzufügen der Einträge die entsprechenden
Parameter angegeben werden. Werden keine Sortierungsparameter angegeben,
erfolgt die Reihenfolge genau so, wie die Einträge in die Liste
eingefügt wurden.
Keine Sortierung | call meineListe.ADD neuEintrag |
Aufsteigend: | call meineListe.ADD neuEintrag, 'A' |
oder: | call meineListe.ADD neuEintrag, 'Ascending' |
Absteigend: | call meineListe.ADD neuEintrag, 'D' |
oder: | call meineListe.ADD neuEintrag, 'Descending' |
Außerdem können Einträge an einer beliebige Stelle der Liste eingefügt werden (bspw. 17. Platz) ungeachtet einer evtl. vorliegenden Sortierung, indem die gewünschte Position angegeben wird:
call meineListe.add neuerEintrag, 17
Oder um beispielsweise sicherzugehen, daß ein Eintrag als letzter in die Liste aufgenommen wird:
call meineListe.ADD neuEintrag, 'L' |
|
or | call meineListe.ADD neuEintrag, 'LAST' |
Die Funktion bzw. der Befehl SELECT
kann dazu
verwendet werden, einen bestimmten Eintrag in der Liste aus- bzw.
abzuwählen. Auf den ersten Blick sieht das ziemlich kompliziert
aus, wenn man Listboxtypen mit Mehrfachauswahl betrachtet, aber es ist
eigentlich relativ einfach. In einer Liste mit 'single selection'
(Einfachauswahl) kann immer nur ein einziger Eintrag ausgewählt
sein, daher bräuchte man in diesem Fall nur
nummer = meineListe.SELECT()
zu verwenden und das wär's. Entweder enthält nummer
danach den Index des ausgewählten Eintrags (wobei 1 für den
ersten Eintrag der Liste steht und so weiter) oder 0 (null), wenn kein
Eintrag in der Liste ausgewählt ist. Der gleiche Aufruf gibt - wenn
auf eine Listbox mit Mehrfachauswahl angewendet - den Index des ersten
ausgewählten Eintrags zurück (oder wieder 0, falls keiner
ausgewählt wurde). Dabei spielt es keine Rolle, ob die
Mehrfachauswahl auf Basis von multiple oder extended definiert wurde -
für SELECT
macht das keinen Unterschied. Um die restlichen evtl.
ausgewählten Einträge zu ermitteln, bewegt man sich in einer
Schleife durch die Liste und beginnt jeweils beim Eintrag, der dem zuvor
gefundenen folgt:
nummer = meineListe.SELECT(nummer + 1, 'NEXT')
Was eigentlich auch nichts anderes macht, als den ersten ausgewählten Eintrag in der Liste zu suchen... Allerdings fängt die Suche nicht am Listenanfang an, sondern bei dem Eintrag, der dem zuletzt gefundenen Eintrag folgt. Das macht man dann so lange, bis man 0 zurück bekommt - das Zeichen für 'keine (weiteren) selektierten Einträge da'. Im Vergleich zum Durcharbeiten der gesamten Liste mit Prüfung jedes einzelnen Eintrags liegt der Vorteil dieser hier beschriebenen Methode darin, daß sie einerseits viel schneller ist und sie zweitens auch dann immer funktioniert, wenn man gar nicht weiß, wie viele Einträge überhaupt in der Liste sind. Um nun einen bestimmten Eintrag zu wählen, verwendet man
call meineListe.SELECT nummer
um den 'nummerten' Eintrag zu markieren. Gut, aber wo wir gerade bei der Anzahl der
Einträge einer Liste waren... wie bekommt man das heraus? Na, mit
der Funktion ITEM
einer Listbox:
Damit kann man Informationen zu einem einzelnen Eintrag abrufen oder -
wenn man keine Parameter übergibt - die Anzahl der Einträge
herausbekommen:
anzahl = meineListe.ITEM()
Wenn Sie nun wissen möchten, wie der erste ausgewählte Eintrag
einer Liste heißt, kombinieren Sie SELECT()
und
ITEM()
auf folgende Weise:
nummer = meineListe.SELECT()
name = meineListe.ITEM( nummer )
Oder als klassischen Einzeiler:
name = meineListe.ITEM( meineListe.SELECT() )
Eine sehr nützliche Erweiterung zu
den Listboxen ist die Anweisung bzw. Funktion VALUE
, mit der man
einen zusätzlichen Wert zu einem Listeneintrag speichern kann. Sie
können sich das als eine zusätzliche, unsichtbare Spalte der
Liste vorstellen. Beim Hinzufügen eines Eintrags zu einer Liste
wird mittels eines Folgeaufrufs der mitzuspeichernde Wert abgelegt. Das
ist dann sehr nützlich, wenn man z.B. mit Querverweisen zwischen
mehreren Listboxen arbeitet. In einer späteren Ausgabe werden wir
uns damit näher beschäftigen, nur so viel sei gesagt: Dieser
zusätzliche Wert wird auch mittels der hier beschriebenen Funktion
ITEM()
in Zusammenhang mit einem weiteren Parameter abgefragt.
Eigentlich sind diese combo boxes nichts anderes als Kombinationen aus eines listbox und einem entry field... aber das ist natürlich nicht alles. ;) Die Unterschiede beginnen bereits zur Entwicklungszeit: Combo boxes können entweder eine geöffnete Liste enthalten oder eine ausklappbare Liste, die zur Laufzeit zunächst wie ein Eingabefeld aussehen, an dessen rechtem Rand sich ein 'Ausklappschalter' befindet. Während man beim ersten Typ (mit der geöffneten Liste) zur Entwicklungszeit die tatsächliche Größe der Liste festlegt, ist das beim Typ mit der 'ausklappbaren' Liste anders: Zur Laufzeit wird diese Art der combo box zunächst in der Größe eines normalen Eingabefelds angezeigt, jedoch ist die Größe der 'ausgeklappten' Liste davon abhängig, wie groß man die Liste während der Entwicklungszeit festgelegt hat. Klar? Na, schauen Sie lieber einfach mal die beiden Abbildungen an:
Festlegen der Größe (für eine drop down list)zur Entwicklungszeit | Und so sieht's dann zur Laufzeit aus |
Wenn Sie sich den Style-Dialog einer combo box anschauen, werden Sie
drei verschiedene Typen finden: Simple, Drop down
und Drop down list. Aber
was ist jetzt der Unterschied zwischen diesen Typen? Ihr Verhalten
natürlich. ;) Die Simple
combobox ist ein Eingabefeld mit einer dazugehörigen Liste. Sie
können entweder frei etwas darin eingeben, oder den Eingabetext in
Kombination mit den Cursortasten auf/ab verwenden, um die Liste auf
einen entsprechend lautenden Eintrag vorzupositionieren. Dieser Typ wird
meistens dann verwendet, wenn der Anwender neben einer vordefinierten
Auswahl auch eigene Eingaben machen dürfen soll. Das gilt auch
für den zweiten Typ Drop down,
nur daß der Listenteil anfänglich unsichtbar bleibt und erst
auf Anforderung 'ausgeklappt' wird, wodurch man einiges an Platz im
Dialogfenster spart. Nach wie vor darf der Anwender aber neben der
Auswahl aus den Einträgen auch eigene Eingaben vornehmen.
Manchmal jedoch möchte man sicherstellen, daß der Anwender
keine eigenen Eingaben machen können darf und lediglich aus einer
vordefinierten Liste auswählen kann. Hier kommt der dritte typ ins
Spiel: Die Drop down list.
Obwohl diese Liste anfänglich wie ein Eingabefeld aussieht,
können keine Eingaben darin gemacht werden. Stattdessen erfolgt
beim Drücken eines Buchstabens eine Vorpositioniereung der Liste
auf den ersten Eintrag, der mit dem gedrückten Buchstaben beginnt
und der (falls es einen solchen gibt) dann in das Eingabefeld
übernommen wird. Jetzt fragen Sie bloß nicht, was man macht, um
eine vordefinierte "NUR-AUSWAHL"-Liste anzuzeigen, die nicht ausgeklappt
wird sondern immer sichtbar ist, denn die Antwort darauf lautet einfach:
Das ist eine Standardlistbox, Mensch! ;)
Über die horizontal scroll bar
werden wir hier nicht sprechen - es ist
identisch mit der bei den Listboxen.
Während ENTER
und SELECT
dasselbe bewirken,
wie bei einer Listbox und INIT
und DROP
sich genauso
verhalten, wie bei allen anderen controls, gibt es hier noch das
CHANGED
Ereignis, welches wir
bereits vom entry field (Eingabefeld) kennen. Und genau wie es im entry
field ein SCROLL
-Ereignis gibt, gibt es bei der combo box das
Gegenstück, welches hier allerdings SCROLLENTRY
hei&szllig;t und auch dann auftritt, wenn der Eingabefeldbereich der combobox
horizontal "gescrollt" wurde. Der Grund für die Abweichung im
Namen ist schlicht, daß es bei den Comboboxen ein weiteres
Ereignis gibt, welches sich ums 'Scrollen' dreht:
SCROLLLIST
tritt dann auf, wenn
im Listenbereich einer Combobox
geblättert (gescrollt) wurde. Dann gibt es noch das
SHOWLIST
-Ereignis, welches
ausgelöst wird, wenn der Anwender bei einer ausklappbaren Liste
selbiges angefordert hat, indem er auf die entsprechende
Schaltfläche geklickt hat. Beachten Sie, daß das Ereignis
SHOWLIST
nur dann ausgelöst
wird, wenn durch das Klicken auf die Schaltfläche die Liste
aufgeklappt wurde, nicht, wenn die
Liste durch erneutes Klicken auf die Schaltfläche wieder
ausgeblendet wird.
Zu den Funktionen einer combo box gibt es nichts aufregendes mehr zu
berichten, da es sich tatsächlich um das handelt, was wir bereits
aus den listboxen oder dem entry field kennen, abgesehen von der
Tatsache, daß es keine SELECT()
-Funktion für den
Eingabefeldbereich gibt. Es gibt zwar eine SELECT()
-Funktion, die sich
allerdings auf den Listenteil der combo box bezieht und genau so
funktioniert, wie das Gegenstück der listbox. Andererseits gibt es
aber etwas, das funktioniert, obwohl es nicht
in der Onlinehilfe aufgelistet ist: Wie ich bereits erwähnte, sind
combo boxes eine Kombination von Listbox und Eingabefeld. Obwohl die
TEXT()
-Funktion im Hilfetext der
combobox fehlt, kann man Sie dennoch benutzen. Das ist gut zu wissen,
denn damit könnte man eine 'nur Auswahl'-Liste mit einer nicht
auswählbaren Überschrift machen, wie zum Beispiel mit
call meineListe.TEXT '- Betriebssystem auswählen -'
und das wär's (natürlich
müssen Sie noch ADD()
s einfügen, um die Liste zu füllen).
Solange der Anwender keinen Eintrag der Liste ausgewählt hat, wird
SELECT()
eine 0 (null) zurückgeben, auch wenn die Überschrift
in der Liste steht. Hat der Anwender erst einmal einen Eintrag
ausgewählt, kann er nicht zur Überschrift '- Betriebs...'
zurückkehren, da diese nie Bestandteil der Listeneinträge war
und somit nicht (mehr) auswählbar ist. Ha! Na das ist pfiffig,
oder? ;)
Da gibt es nicht viel zu sagen, wenn wir von dem absehen, was wir bereits vom Thema radio button kennen: Hiermit können controls gruppiert werden. Zur Entwicklungszeit werden beim verschieben eines 'group'-Rahmens alle enthaltenen controls entsprechend mitverschoben. Das Setzen von Position und Größe zur Laufzeit hat allerdings nur Auswirkungen auf den Rahmen selbst - die enthaltenen controls bleiben unverändert. Halftone scheint nicht zu funktionieren - zumindest nicht bei mir, aber DISABLED klappt... abgesehen vom Umstand, daß damit wirklich nur der Rahmen (de)aktiviert wird, nicht die enthaltenen controls. - Ich sage das nur, damit Sie gewarnt sind, alles klar? ;)
Na klar - INIT
und DROP
mal wieder, natürlich.
Aber hey: ShowMenu
ist ja mal was neues! Dieses Ereignis wird
dann ausgelöst, wenn der
Anwender ein Kontextmenü angefordert hat (durch Klick auf Maustaste
2). Dieses Ereignis wird meistens in Zusammenhang mit DrDialogs Befehl
MenuPopup
verwendet, mit dem
selbstdefinierte Menüs als Kontextmenüs angezeigt und
verwendet werden können. Ich muß Sie aber wieder enttäuschen
und darauf hinweisen, daß wir uns zu einem späteren Zeitpunkt
der Serie mit den Menüs beschäftigen werden.
Enable/Disable
Nichts besonderes: Damit können controls zur Laufzeit aktiviert bzw. deaktiviert werden wie z.B. mit
call meineListe.DISABLE
Enabled
Nicht verwechseln mit dem CALL-Aufruf ENABLE
, denn diese
Funktion hier kann auch zum Abfragen verwendet werden, ob ein control
aktiv oder deaktiv ist, während die beiden obigen Vertreter
lediglich den Status setzen, aber nicht abfragen können. Um den
Zustand eines controls abzufragen verwenden Sie
zustand = meineListe.ENABLED()
Rückgabewert ist 1 (enabled) oder 0
(null; disabled). Zum Setzen des Status mittels ENABLED()
verwenden Sie
die gleichen Werte als Parameter für den CALL-Aufruf:
call meineListe.ENABLED 0
Visible
Versteckt ein control zur Laufzeit bzw. zeigt es wieder an und kann auch entsprechend zur Abfrage des Status verwendet werden. Ziemlich nützlich, wenn man wenig Platz auf der Dialogmaske hat - einfach die nicht benötigten Teile verstecken und die benötigten wieder anzeigen. Aber übertreiben Sie's nicht! ;) Die Statuswerte für die Sichtbarkeit eines controls sind leicht zu merken: 0=unsichtbar (versteckt), 1=sichtbar. Um eine Listbox zur Laufzeit beispielsweise zu Verstecken, nimmt man
call meineListe.VISIBLE 0
Und um zu erfahren, ob die gleiche Liste sichtbar ist oder nicht nimmt man entsprechend
zustand = meineListe.VISIBLE()
Bottom/Top
Wenn man hübsche Effekte erreichen will, wie pushbuttons, die in Grafiken eingebettet sind oder mehrere Bitmaps mit anderen controls kombiniert, kann es vorkommen, daß die controls manchmal in der falschen "Z-Reihenfolge" liegen, und daß ein control 'unter' einem anderen versteckt ist, obwohl es genau umgekehrt sein müßte. Um diese "Z-Reihenfolge" ("z-order", abgeleitet vom dreidimensionalen Koordinatenmodell X-Achse, Y-Achse und Z-Achse) zu ändern, können Sie jedem control mitteilen, ob es ganz oben (top) oder ganz unten (bottom) in der Z-Reihenfolge stehen soll. Der Aufruf sind dementsprechend entweder so aus
call meineListe.TOP
oder
call meineListe.BOTTOM
Show/Hide
Jo, das ist cool: Anfänglich denkt man, daß es sich hierbei
nur um eine andere Variante von VISIBLE
handelt, mit der
man auch controls verstecken oder anzeigen kann. Aber obwohl das stimmt,
steckt da einiges mehr unter der Haube als man vermutet, denn
HIDE
kann zusätzlich dazu
verwendet werden, das 'Aktualisieren' eines controls temporär
auszuschalten. Dieser Kniff ist extrem hilfreich, wenn Sie
beispielsweise eine große Menge von Einträgen sortiert in
eine Listbox füllen (z.B. beim INIT
-Ereignis). Jede ADD
-Anweisung
führt zu einem Update der listbox, wodurch diese oder die
Einträge darin unter Umständen flackern. Das läßt sich
vermeiden, indem die Aktualisierung temporär ausgeschaltet, die
Listbox gefüllt und die Aktualisierung danach wieder eingeschaltet
wird. Dann findet einmalig eine Anzeige der Inhalte statt und Sie sind
genau wieder da, wo Sie auch "normalerweise" wären - nur,
daß das Füllen der Liste mit diesem 'Trick' um einen
erheblichen Faktor beschleunigt wird! Beachten Sie, daß das
control selbst nicht versteckt wird sondern lediglich nur die
Aktualisierungen unterdrückt werden.
Um ein control unsichtbar zu machen (wie mit VISIBLE), verwenden Sie
HIDE wie folgt:
call meinControl.HIDE
Um aber nur die Aktualisierung eines controls temporär zu unterdrücken, verwenden Sie
call meinControl.HIDE 'Noupdate'
(Sie können auch einfach 'N'
anstelle von
'Noupdate' angeben, um es abzukürzen). Um die Aktualisierung
wieder zu aktivieren oder ein
verstecktes control wieder anzuzeigen nehmen Sie dann
call meinControl.SHOW
Uff!
Eigentlich sollte der Beitrag für diesen Monat etwas kürzer
ausfallen, aber es gibt so viel zu entdecken, zu erzählen, zu
erklären und zu beachten... und ich habe hier nur die wichtigsten
gemeinsamen controls genommen. Nun ja - es ist mal wieder an der Zeit
Abschied zu nehmen, Leute.
Bis zum nächsten Monat!
Daten und Quellen:
|
[Artikelverzeichnis]
editor@os2voice.org
[Vorherige Seite] [Inhaltsverzeichnis] [Nächste Seite]
VOICE Homepage: http://de.os2voice.org