Eingabeeinheiten

Zu den grundlegensten Ereignissen gehören diejenigen, die durch die Hardware direkt erzeugt werden. Dazu gehört Aktionen der Maus, das Drücken einer Taste oder das Ablaufen eines Timers.

In den meisten Fällen werden diese vom System in andere Ereignisse uminterpretiert. So entsteht ein Menüereignis durch das Drücken der Maustaste oder der Tastatur. Es gibt aber einige Fälle, in denen es notwendig ist, daß die Applikation die Grundereignisse selbst überwacht.

Timerereignisse

Alle grafischen Oberflächen stellen Timer zur Verfügung. Auf den ersten Blick ist dies verblüffend, da nur in wenigen Programmiersprachen eine Timerschnittstelle vorgesehen ist. In einem ereignisorientierten System ist es aber indiskutabel, eine einfache Warteschleife zu schreiben, um eine Verzögerung des Programmablaufs zu erreichen, da sonst auch Fensteraufbauten ins Stocken geraten.

Es gibt zwei Arten, wie der Timer implementiert sein kann. Er kann einmalig gestartet werden, so daß man genau ein Ereignis erhält oder er kann einen regelmäßigen Takt liefern. Ersteres Verfahren ergibt einen Timeout-Mechanismus, mit dessen Hilfe leicht festgestellt werden kann, ob ein Ereignis in einer bestimmten Zeit eingetroffen ist. Intern wird dieses Verfahren zum Beispiel zur Erkennung eines Doppelklicks der Maus benutzt. Das zweite Verfahren ist besonders geeignet, um wiederkehrende Ereignisse zu realisieren, wie das Blinken eines Cursors oder das Ticken einer Uhr. Es ist recht einfach, mit einem Verfahren das jeweils andere zu simulieren. Wird nach jedem Eintreffen eines Timeouts der Timer erneut gestartet, erhält man einen regelmäßigen Puls. Durch Verzögerungen, die durch die interne oder applikationseigene Abarbeitung auftreten, ist dieser Puls allerdings nicht ganz exakt und muß gegebenenfalls mit einer internen Uhr abgeglichen werden. Um mit einem pulsierenden Timer einen Timeout zu simulieren, wird er beim Eintreffen des ersten Ereignisses einfach abgeschaltet.

Beim X-Window-System wird ein Timeout mit der Funktion XtAppAddTimeOut angestoßen.

XtIntervalId XtAppAddTimeOut(XtAppContext ApplikationsHandle,
                             unsigned int Millisekunden,
                             XtTimerCallbackProc timerCallback,
                             XtPointer Clientdaten);

Die Funktion liefert eine eindeutige Kennung vom Typ XtIntervalId zurück. Sie kann verwendet werden, um den Timeout mit Hilfe der Funktion XtRemoveTimeOut vorzeitig abzuschalten. Der einzige Parameter der Funktion ist diese Kennung.

Die Callbackfunktion des Timeout wird nicht durch ein Widget ausgelöst, so daß nicht die typischen Parameter einer normalen Callbackfunktion verwendet werden. Statt dessen ist die Callbackfunktion folgendermaßen definiert:

void timerCallback(XtPointer ClientDaten, XtIntervalId *Kennung);

Ein regelmäßiger Puls wird erzeugt, indem die Callbackfunktion ihrerseits die Funktion XtAppAddTimeOut aufruft.

Leerlauffunktionen

X bietet einen Mechanismus, der intern unter Verwendung eines Timers arbeitet. Es können Funktionen (Workprocedures) definiert werden, die die Leerlaufzeit zwischen den eintreffenden Ereignissen nutzen. Diese Funktionen sind so zu schreiben, daß sie bei jedem Aufruf einen Teil der Arbeit vorantreiben, aber zwischendurch schnell genug zurückkehren, damit der Ablauf der anderen Ereignisse nicht verzögert wird. Eine solche Funktion liefert solange FALSE zurück bis ihre Aufgabe erledigt ist. Bei Rückgabe von TRUE wird die Funktion nicht mehr angesprochen wird. Man kann diese Funktionen beispielsweise dazu verwenden, später benötigte Dialogboxen zu erstellen. Sollte die Dialogbox noch nicht fertig sein, wenn sie zum ersten Mal gebraucht wird, muß die Applikation selbst die Funktion solange direkt aufrufen, bis diese TRUE zurückgibt.

Mausprogrammierung

Viele Aktionen, die der Benutzer mit der Maus auslöst, wertet das System aus. Das Anklicken eines Menüs beispielsweise erfährt das Programm als Menüereignis. Ob es mit der Maus ausgelöst wurde, interessiert das Programm nur sekundär. Wenn die Maus dagegen innerhalb eines eigenen Fenster angeklickt wird, muß dies die Applikation erkennen und selbst in entsprechende Aktionen umsetzen. In bestimmten Fällen ist es erforderlich, zu ermitteln, wo sich die Maus derzeit befindet, zum Beispiel um an dieser Stelle ein Popup-Menü erscheinen zu lassen.

Ein weiterer Bereich der Mausbetreuung besteht im Verändern des Aussehens des Mauszeigers. Am bekanntesten ist die Veränderung des Mauszeigers direkt nach dem Starten einer länger dauernden Aktion. Hier erscheint eine Sanduhr, Armbanduhr oder ein fleißiges Bienchen und zeigt damit die Beschäftigung des Systems an.

Mausereignisse

Solange die Maus Kontrollelemente der Benutzeroberfläche bedient, braucht der Programmierer sich nicht näher mit dem Tierchen zu beschäftigen. Anders steht die Lage, wenn sich der Mauszeiger über dem eigenen Fenster bewegt oder dort geklickt wird. Hier ist der Programmierer selbst für das Empfangen der Mausereignisse und die Reaktionen auf diese Ereignisse zuständig.

Alle Systeme erzeugen ein Ereignis, wenn eine Maustaste gedrückt wird, das an das Programm weitergeleitet wird. Mit dieser Nachricht empfängt das Programm auch die Information, an welcher Bildschirmposition sich der Mauszeiger zu jenem Zeitpunkt befand.

Position und Status

MS-Windows und PM senden ständig Nachrichten über die aktuellen Aktionen der Maus an die zuständige Fensterfunktion. Damit ist die Fensterfunktion immer über den aktuellen Zustand der Maus informiert. Es gibt Ereignisse für das Drücken jeder Maustaste, das Loslassen jeder Maustaste und jede Positionsänderung. Werden vom Programm Informationen über die Maus benötigt, sind die entsprechenden Ereignisse zu protokollieren. So weiß die Anwendung ständig, wo sich die Maus befindet.

GEM verwendet ein anderes Verfahren. Wenn der Programmierer wissen will, wo die Maus ist, soll er fragen! Dadurch erspart sich das System, für jede Bewegung der Maus eine Nachricht zu versenden. Es gibt nur Nachrichten bei Maustastenklicks.4 Will das Programm Informationen über die aktuelle Mausposition oder den Maustastenstatus haben, gibt es dazu die Funktion graf_mkstate. Der Vorteil dieses Vorgehens liegt in der deutlichen Reduzierung des Nachrichtenverkehrs. Der Nachteil ist eine in manchen Fällen etwas unflexiblere Behandlung der Mausaktionen.

Der Doppelklick

Ein Doppelklick wird unter GEM dadurch erkannt, daß beim Ereignis eines Mausklicks im Parameter für die Anzahl der Mausklicks den Wert zwei erhält. Es muß dazu bei der Maske für die zu erkennenden Ereignisse allerdings auch angegeben sein, daß man auch auf mehrere Klicks wartet. Das Ereignis Doppelklick ist also ein anderes Ereignis als Einfachklick. Unter PM oder MS-Windows werden zwei Ereignisse ausgelöst. Zuerst erhält die Anwendung den ersten Klick als Einfachklick und anschließend eine zweite spezielle Nachricht für den doppelten Klick. Das hat zur Konsequenz, daß die Aktion für einen Doppelklick auf dem Ereignis für den Einfachklick aufbaut. Anders ausgedrückt, ist die Aktion für den Einfachklick im allgemeinen bereits abgelaufen, wenn der Doppelklick empfangen wird. Alle Aktionen, die durch einen Doppelklick ausgelöst werden, müssen mit einem vorher erfolgten Einfachklick vereinbar sein. Idealerweise basieren beide Aktionen aufeinander. Auch wenn unter GEM dieser Ablauf nicht erforderlich ist, ist die Semantik des Doppelklicks sinnvollerweise entsprechend zu realisieren. So führt ein Einfachklick meist zum Selektieren eines Objekts und der Doppelklick zu einem Aktivieren des entsprechenden Objekts.

Die zweite Maustaste

Welche Maustaste gedrückt worden ist, wird unterschiedlich ermittelt. Beim Macintosh hat man hier die geringsten Probleme: er besitzt nur eine Maustaste. Bei anderen Systemen erhält das Programm für jede Taste eine unterschiedliche Nachricht. Bei GEM ist die Verwendung der zweiten Maustaste nicht ganz trivial und kaum dokumentiert. Das ist auch der Grund, warum sie viele GEM-Programme ignorieren.

Um auch die rechte Maustaste erkennen zu können, muß der Funktion evnt_multi mitgeteilt werden, daß das Drücken der linken oder der rechten Maustaste ein Ereignis auslösen sollen.5 Dies erfolgt anhand der Übergabeparameter, die festlegen, welche Ereignisse zur Kenntnis genommen werden sollen,

Drei Parameter der Funktion sind dafür zuständig, welche Mausereignisse empfangen werden:

Klicks: Anzahl der maximal zu registrierenden Klicks (2 für Doppelklick)
Maske: Welche Taste wird erkannt? Bit 0: linke, Bit 1: rechte Maustaste
Status: Welcher Zustand wird erkannt? 0: nicht gedrückt, 1: gedrückt

Setzt man die Anzahl der Klicks auf 2, empfängt man Einzel- oder Doppelklicks. Leider bewirkt im Gegensatz dazu das Setzen einer Maske für beide Tasten, daß nur dann ein Ereignis eintrifft, wenn die erste und die zweite, also beide Tasten gleichzeitig gedrückt sind. Man will aber erkennen, ob eine oder die andere Taste gedrückt wurde. Dies läßt sich nur über die (leider nicht offiziell dokumentierte) Möglichkeit erreichen, daß man im Highbyte des Parameters Klicks eine 1 setzt. Dies interpretiert GEM als Negation. Damit ergibt sich bei Maske=3 und Status=0 der logische Ausdruck, daß nicht die linke und nicht die rechte Maustaste ungedrückt sind. Nach De Morgan ergibt sich daraus das gewünschte Ereignis, daß die linke oder die rechte Taste gedrückt wurde.

Um also beide Tasten auf maximal Doppelklick abzuhorchen, werden die Parameter wie folgt gesetzt: Klicks=256+2, Maske=3 und Status=0. Im Parameter Knopf findet man nach dem Aufruf eine 1 für linke Taste und eine 2 für rechte Taste.6


Das Beispiel zeigt zwei Dinge. Erstens ist es möglich, daß Systemaufrufe bei der Variation von Parametern einiges an Funktionen bringen, die man nicht erwartet hätte. Es lohnt sich oft, mehrere Dokumentationen zu lesen, um die Leistung einer Funktion vollständig zu erkennen. Zweitens sieht man, welchen Wert Zeitschriften für Programmierer haben, die unter grafischen Oberflächen arbeiten. Hier findet man immer wieder Erfahrungen anderer Programmierer, die mit ähnlichen Problemen zu kämpfen haben.

Mauszeigergestaltung

Jedes System bietet Möglichkeiten, die Gestalt des Maussymbols vom Programm aus zu verändern. Neben dem üblichen Pfeil gibt es diverse andere Zeichen, die das System zur Verfügung stellt. Das wichtigste Symbol ist das Zeichen für ein beschäftigtes System. Es verhindert, daß der Benutzer bei länger dauernden Aktionen wild auf dem Programm herumklickt und damit Aktionen auslöst, die er gar nicht wollte. Andererseits meldet der wieder erscheinende Pfeil, daß die Aktion beendet ist und verhindert damit, daß der Benutzer längere Zeit vor dem Bildschirm wartet, weil er glaubt, das Programm sei noch nicht so weit. Je nach Oberfläche ist das Zeichen für ein beschäftigtes Programm eine Sanduhr, eine Armbanduhr oder auch eine Biene. Dieses Symbol sollte man auch in der eigenen Anwendung verwenden.

Die Systeme stellen auch andere Symbole zur Verfügung. Es gibt Fadenkreuze für Positionierung von Punkten, Hände zum Verschieben von Objekten und andere Symbole, die der jeweiligen Dokumentation zu entnehmen sind. Man sollte eine solche Änderung des Mauszeigers immer dann einsetzen, wenn das Programm in einem anderen Modus arbeitet.

Bei GEM und Macintosh gilt das Ändern der Mauszeigerform für den ganzen Bildschirm. Dagegen kontrolliert eine Anwendung bei den anderen Systemen nur den Bereich der eigenen Fenster, so daß nur in diesem Bereich die Änderung des Mauszeigers wirkt. Als Beispiel soll hier die Umstellung des Mauszeigers für ein X-Programm dargestellt werden.

Cursor busyPointer;

    /* --- Umschalten des Mauszeigers auf Armbanduhr --- */
    /* Erzeuge das Bitmap fuer die Armbanduhr */
    busyPointer = XCreateFontCursor(display, XC_watch);
    /* schalte fuer das Applikationsfenster um */
    XDefineCursor(display, XtWindow(aussenwidget), busyPointer);

    ...

    /* Ruecksetzen des Original-Mauszeigers */
    XUndefineCursor(display, XtWindow(aussenwidget);

An dem Namen der Funktionen wird bereits deutlich, daß der Mauszeiger von der Xlib verändert wird. Der Mauszeiger ist eine kleine Grafik, die zunächst aus den vordefinierten Zeichen gewählt und erzeugt wird. Zum Umschalten wird der Bildschirm und das Fenster angegeben, für das die Umschaltung gelten soll. Da die Xlib mit einem Widget nichts anfangen kann, wird das hinter dem äußeren Widget liegende Fenster mit der Funktion XtWindow ermittelt. Im Bereich dieses Rechtecks wird der Mauszeiger verändert. Nachdem die Operation beendet ist, wird die Definition des Mauszeigers wieder zurückgenommen, so daß jedes einzelne Widget wieder die gewohnte Gestaltung übernimmt.


Statt die Grafik, die sich hinter dem Variablentyp Cursor verbirgt, aus dem Systemsatz zu erstellen, kann eine Applikation auch einen eigenen Mauszeiger definieren. Auch dieses ist grundsätzlich bei allen Systemen möglich und wird nicht selten benutzt. Allerdings sagt die Darstellung einer Kaffeetasse statt der Uhr mehr über den Spieltrieb des Programmierers als über den Beschäftigungsgrad des Systems aus.

Markierung

Das Klicken der Maus führt bei allen Systemen zu einem Ereignis. Befindet sich unter dem Mauszeiger ein anwählbares Element, wird man dies als selektiert markieren.

Darstellung der Selektion

Ein angewähltes Objekt wird markiert, indem man es invertiert darstellt. Dies ist solange relativ einfach und effizient zu realisieren, wie man lediglich mit schwarz und weiß zu tun hat. Hier genügt es, den zu markierenden Bereich mit einem Wert, dessen Bits durchweg 1 sind, exklusiv zu odern. Das Zurücknehmen der Invertierung wird durch Wiederholung der gleichen Operation erreicht. So wie bei Invertieren aus schwarz weiß wurde, wird nun aus weiß wieder schwarz. Da das exklusive Odern ein einfacher CPU-Befehl ist, ist dieser Vorgang recht schnell.

Bei der Verwendung von Farbe ist dieses Prinzip auch anwendbar. Auch hier erscheint durch zweimaliges Invertieren die Ausgangsfarbe. Leider entspricht aber das invertierte Objekt nicht unbedingt den Erwartungen des Benutzers. Wurde beispielsweise ein grünes Objekt auf weißem Grund invertiert, ist dieses nach seiner Invertierung wahrscheinlich violett auf schwarzem Grund. Aus diesem Grund wird unter X beim Invertieren die Hintergrundfarbe und die Vordergrundfarbe ausgetauscht. Das Ergebnis entspricht nun den Erwartungen des Benutzers, ist aber deutlich langsamer, da alle Objekte neu gezeichnet werden müssen. Aber auch dies funktioniert nur, solange nicht mehr als zwei Farben im Spiel sind.

Eine weitere Problematik ergibt sich beim Invertieren von Symbolen. Diese haben nicht immer ein rechteckiges Äußeres. Wird hier das umfassende Rechteck invertiert, ist davon ebenfalls ein Teil des Hintergrundes betroffen. Aus diesem Grund werden vom System für das Invertieren von Symbolen eigene Masken definiert, die den Umriß bezeichnen oder man legt für jedes Symbol ein zusätzliches an, daß im Invertierungsfall dargestellt wird.

Markierung mehrerer Objekte

Will der Benutzer mehrere Objekte anwählen, so wird er die Maustaste gedrückt halten und über die Objekte einen Rahmen spannen wollen, die er berücksichtigt haben möchte. Allein das Gedrückthalten der Maustaste ist aber noch kein eindeutiger Hinweis darauf, daß der Benutzer mehrere Objekte erfassen will. Es kann auch sein, daß der Benutzer ein Objekt verschieben möchte. Um dieses zu vereinfachen, wird beim PM das Verschieben eines Objekts mit der rechten Maustaste ausgelöst. Intuitiver ist sicher die Verwendung der linken Maustaste. Dennoch sollten PM-Programme aus Gründen der Konsistenz ebenfalls die rechte Maustaste verwenden. Bei der Verwendung der linken Maustaste für Verschieben und Aufspannen des Markierungsbereichs, ist es von entscheidender Bedeutung, ob sich die Anfangsposition der Maus über einem Objekt befand oder nicht. Ist die Mausposition an der Stelle eines Objektes, will der Benutzer verschieben. Befindet sich der Mauszeiger in einem leeren Raum, will er einen Bereich markieren. Das bedeutet aber auch, daß Objekte durch einen leeren Raum getrennt sein müssen, um dem Benutzer überhaupt zu erlauben, einen Bereich aufzuspannen.


Unter GEM löst das Ziehen einer gedrückten Maus erst einmal ein normales Klickereignis aus. Nach dem Erkennen des Mausklickereignis wird der Status der Maus erfragt. Ist nach Eintreffen der Nachricht die Maustaste immer noch gedrückt, wird die Aktion nicht als einfacher Klick, sondern als Ziehen der Maus interpretiert. Ein Problem besteht darin, daß die Abfrage des Mausstatus recht schnell nach dem Eintreffen des Mausereignis ausgelöst wird und damit ein etwas langsamer Klick leicht als Ziehen interpretiert werden kann. Um die Unterscheidung eindeutiger zu machen, kann man einen Timer starten und den Mausstatus bei Eintreffen des Timerereignisses abfragen.

Um einen Rahmens aufziehen zu können, bietet GEM eine Funktion zum Aufspannen eines sogenannten Gummibandes. Die Funktion ist recht einfach benutzbar. Empfängt man ein Mausklickereignis und stellt danach fest, daß die Taste anschließend noch gedrückt ist, merkt sich das Progamm die Ausgangsposition der Maus und ruft diese Funktion. Das Betriebssystem wird solange das Gummiband aufspannen, bis die Maustaste wieder losgelassen wird. In dieser Zeit übernimmt das System die Kontrolle. Die Anwendung arbeitet erst nach dem Loslassen weiter. Durch Erfragen der Mausposition erhält das Programm auch die Endposition des Gummibandes. Damit ist der markierte Bereich bekannt. Es ist nun erforderlich, alle Objekte als markiert zu kennzeichnen, die in das aufgespannte Rechteck fallen.7

Schwieriger wird es, wenn nicht die standardmäßigen Funktionen verwendet werden können. Beispielsweise ist das Gummiband kein besonders geeignetes Mittel, wenn man eine Textverarbeitung programmiert. Hier will der Benutzer vermutlich nicht ein Rechteck aus dem Text ausschneiden, sondern eine Passage seines Textes markieren. Diese beginnt an der Mausposition und streicht über die vollständigen Folgezeilen bis zu der Endposition der Maus. Hier kommt als zusätzliche Problematik hinzu, daß der Benutzer eventuell mehr markieren will, als derzeit im Fenster sichtbar ist. Eine Bewegung der Maus außerhalb des Fensters ist also ein Zeichen dafür, daß das Programm den Bildschirm scrollen soll. Dies ist nicht mit Hilfe der Systemfunktion möglich, da diese das Programm nicht mehr zum Zuge kommen lassen wird, bis der Benutzer die Maustaste wieder losläßt. In diesem Fall muß das Programm selbst die Kontrolle übernehmen, indem es in einer Schleife überprüft, ob die Maustaste noch gedrückt ist. Die jeweilige Mausposition wird ermittelt und der hinzugekommenen Bereich wird markiert. Ist der Bereich des Fensters verlassen worden, muß ein Scrolling eingeleitet werden und auch der neu erscheinende Text markiert werden. Es bedarf nicht allzu großer Phantasie, zu erfassen, daß hier viel Eigenarbeit erforderlich ist.


Unter MS-Windows und PM wird mit einer anderen Technik gearbeitet. Die Applikation empfängt ständig Nachrichten über Aktivitäten der Maus. Dabei lösen das Niederdrücken, das Loslassen und die Bewegung der Maus Ereignisse aus. Wird die Maustaste heruntergedrückt oder losgelassen, merkt sich das Programm den Zustand der Maustaste in einer statischen Variablen. Empfängt man ein Ereignis für die Bewegung der Maus und in der statischen Variablen ist der Wert für eine niedergedrückte Maustaste enthalten, handelt es sich um ein Ziehen der Maus. Soll ein Gummiband verwendet werden, muß es die Applikation selbst erzeugen. Zu diesem Zweck wird eine Rechtecklinie über die Anfangsposition und die aktuelle Mausposition gebildet und dieser Rahmen durch exklusives Odern über den Hintergrund gelegt. Damit das Gummiband an der alten Stelle wieder verschwindet, wird die alte Position vorher ebenfalls invertiert und damit der Originalzustand wiederhergestellt. In diesem Falle ist das exklusive Odern auch bei Farbschirmen sinnvoll, da lediglich eine Linie verwendet wird, die sich vom Hintergrund abheben muß. Daß dabei ungewöhnliche Farben entstehen, dürfte der Benutzer nicht einmal bemerken. In jedem Fall ist er sicher eher bereit, dies zu tolerieren als ein ruckelndes Aufspannen.

Sobald das Ereignis für das Loslassen der Maustaste eintrifft, wird die Selektion beendet. Dabei tritt ein Problem auf: Würde der Mauszeiger bei gedrückter Taste außerhalb des Fenster gezogen, erhielte die Fensterfunktion die Nachricht zum Loslassen der Maustaste nicht mehr. Aus diesem Grund muß beim Niederdrücken die Funktion WinSetCapture aufgerufen werden. Dadurch werden alle folgenden Mausereignisse auf die aktuelle Fensterfunktion umgeleitet. Dieses Einfangen der Mausereignisse darf natürlich nur solange durchgeführt werden, wie die Maustaste nicht wieder losgelassen wird. Sobald die Nachricht über das Loslassen der Maustaste eintrifft, wird durch nochmaliges Aufrufen von WinSetCapture mit anderen Parametern die Maus wieder für andere Fensterfunktionen freigegeben.

Tastatur

In den Programmiersprachen werden Tastatureingaben als einzige Eingabeform standardmäßig unterstützt. Ihre Unterstützung betrifft aber meist nur die Eingabe einer vollständigen Zeile, so daß das Programm erst nach Drücken der Returntaste wieder die Kontrolle erhält. In professionellen Programmen reichen aber diese spracheigenen Funktionen bereits nicht mehr aus, wenn Funktionstasten unterstützt werden sollen oder wenn die Eingabe formatiert erfolgen soll. Die grafischen Oberflächen nehmen Tastatureingaben im Normalfall über Eingabefelder oder ähnliche Kontrollelemente entgegen. Eine weitere Bearbeitung oder Formatierung ist dann nicht notwendig. In einigen Fällen reichen aber die Standardkontrollelemente nicht aus. Man denke hier nur an eine Textverarbeitung. Dann ist es notwendig, daß die Applikation die Tastatureingaben selbst auswertet.

Alle Systeme senden der Applikation ein Ereignis, wenn eine Taste gedrückt wurde. Zusätzlich wird bei den meisten Systemen ein Ereignis gesendet, wenn die Taste wieder losgelassen wird. Letzteres Ereignis ist für die meisten Applikationen allerdings nicht von Interesse, so daß es normalerweise ignoriert wird.

Die Nachricht über das Drücken einer Taste liefert den zur Taste gehörigen ASCII-Code. Um auch Funktionstasten auswerten zu können, wird entweder zusätzlich der Scancode übergeben, der angibt, an welcher Position der Tastatur sich die gedrückte Taste befindet, oder das System gibt für jede Sondertaste eine eigene Kennung an.


Ein Problem stellt oft die Wiederholungsfunktion der Tastatur, besonders der Cursortasten dar. Da die parallel laufende Ausgabe durch ihren grafischen Charakter deutlich langsamer abläuft als die Wiederholfrequenz der Tastatur, empfängt das Programm noch lange Tastennachrichten, obwohl der Benutzer bereits die Finger von der Tastatur genommen hat. So kann es passieren, daß der Anwender auf der Suche nach einer bestimmten Passage durch den Text scrollt und bei Auffinden der Stelle nur noch hilflos zusehen kann, wie das Programm scheinbar endlos weiterscrollt und an der gesuchten Stelle vorbei läuft.

Dieses Problem betrifft eigentlich nur die Cursortasten in Verbindung mit dem Scrollen des Bildschirms, das meist sehr viel Zeit in Anspruch nimmt. Bei den anderen Tasten ist es durchaus erwünscht, das die Tastendrücke gepuffert werden, damit auch bei einem Schnellschreiber keine Tasten verloren gehen.

MS-Windows und PM stellen einen hilfreichen Mechanismus zur Verfügung. Stellt das System fest, daß bei einem längeren Niederdrücken der Taste die Nachrichten nicht schnell genug abgearbeitet werden, wird nicht eine neue Nachricht erstellt, sondern nur ein Zähler in der bisher vorliegenden Nachricht erhöht. Das Programm kann dadurch leicht feststellen, daß die Tastatureingänge schneller kommen, als das Programm sie verarbeiten kann.

Unter anderen Oberflächen wie etwa GEM oder X ist dieses Verfahren leider nicht implementiert, so daß es aufwendiger ist, eine solche Situation abzufangen. Man kann mit Hilfe eines Timers die Bearbeitung einer Taste verzögern. Dazu werden die Cursortasten nicht direkt nach Eintreffen verarbeitet, sondern je in einer statischen Variablen gezählt. Parallel läßt man einen Timer regelmäßig laufen. Immer wenn dieser abgelaufen ist, wird geprüft, ob und wieviele Cursortasten vorliegen und entsprechend verarbeitet.


4 Dies ist nicht die ganze Wahrheit. Man kann GEM dazu auffordern, ein Ereignis zu senden, wenn der Mauszeiger in ein vorher festgelegtes Rechteck eintritt.

5 Wie man noch sehen wird, ist dieses Oder von besonderer Bedeutung.

6 vgl. Andreas Kromke: Tiefen einer Oberfläche. c't 5/90, Seite 198-203.

7 Zum Umgang mit Gummibändern unter GEM siehe Andreas Kromke: Tiefen einer Oberfläche. c't 5/90, Seite 200.


Homepage - Inhaltsverzeichnis (C) Copyright 1993-1999 Arnold Willemer