17. Arbeit mit der Maus

^

17.1 Überblick

Die meisten GEOS-Objekte können automatisch auf Mausereignisse reagieren. So weiss ein Button was zu tun ist, wenn er mit der Maus angeklickt wird. Hier braucht und kann der R-BASIC Programmierer nicht eingreifen. In vielen Fällen muss der R-BASIC Programmierer jedoch die Reaktion auf ein Mausereignis selbst behandeln. Deshalb gibt es eine Reihe von Objekten, die eine explizite Mausunterstützung anbieten. Das sind die Objekte:

VisContent, BitmapContent, VisObj, Canvas und Image

Dazu sind die folgenden Actionhandler, Instancevariablen und Methoden definiert. Details dazu, insbesondere unter welchen Bedingungen die entsprechenden Handler gerufen werden, finden Sie in den nächsten Abschnitten.

Action-Handler-Typen:

Tabelle


Spezielle Instance-Variablen:

Tabelle


Methoden:

Tabelle


Ein einfaches Beispiel

Canvas MyMouseObj
  OnMouseButton = ButtonPressed
  ...
End Object
MOUSEACTION ButtonPressed
  IF event = ME_LEFT_DOWN THEN MsgBox("Linke Maustaste gedrückt")
End Action

^

17.2 Maus Grabbing

Die folgenden Aussagen gelten nicht für VisContent und BitmapContent Objekte.

Im Normalfall wird ein Mausereignis von einem zum nächsten Objekt weitergereicht, bis es das Objekt erreicht hat, das sich direkt unter dem Mauszeiger befindet. Einige Ereignisse, insbesondere das Loslassen der Maustasten und das Verlassen des Objektbereichs, werden im Normalfall gar nicht durchgestellt.

Es ist deshalb oft erforderlich, dass ein Objekt die Mausereignisse exklusiv und komplett zu sehen bekommt. Dieser Prozess heißt "Grabbing". Das Objekt "greift" sich die Mausereignisse direkt und ohne Umweg. Dafür stehen die folgenden Methoden zur Verfügung:

Tabelle


Syntax im BASIC Code: <obj>.GrabMouse
<obj>.ReleaseMouse

Das Objekt zählt nicht mit, wie oft es die Maus gegrabbt hat. Grabbt ein Objekt die Maus mehrfach so wird trotzdem bei ersten ReleaseMouse die Maus wieder freigegeben.

Durch das Grabben der Maus wird erreicht, dass das System alle Mausereignisse direkt an das Objekt sendet, unabhängig davon, wo sich der Mauspointer gerade befindet. Das bedeutet insbesondere, dass das Objekt auch dann die Mausereignisse erhält, wenn sich der Mauszeiger nicht mehr über dem Objekt befindet.

Das Objekt bekommt solange alle Mausereignisse, bis es die Maus wieder freigibt. In der Zwischenzeit ist weder die Bedienung von Menüs möglich noch kann sich ein anderes Objekt die Maus grabben. Häufig ist es so, dass sich ein Objekt beim Drücken einer Maustaste die Maus grabbt und sie beim Loslassen der Taste wieder freigibt. Ensprechende Beispiele finden Sie in den nächsten Kapiteln.

VisContent und BitmapContent

VisContent und BitmapContent Objekte können die Maus nicht grabben. Die Methoden GrabMouse und ReleaseMouse sind wirkungslos. Im Gegenzug erhalten diese Objekte stets alle Mausevents, so dass ein Grabbing der Maus gar nicht nötig ist. Sobald eine Maustaste über einem VisContent- oder BitmapContent gerückt wird grabbt das Objekt die Maus implizit, d.h. alle Mausereignisse gehen an dieses Objekt, auch wenn der Mauszeiger das zugehörige View zwischenzeitlich verlässt. Im Unterschied zum expliziten Grabbing gehen die Mausereignisse zusätzlich an eventuelle Children des VisContent-Objekts. Diese Children (vom Typ VisObj) können dann die Maus explizit grabben.

^

17.3 Aufruf der Actionhandler

Die Mausereignisse sind in drei Gruppen eingeteilt, für die es jeweils einen eigenen Actionhandler gibt.

Tabelle

Die genannten Ereignisse führen nur dann zum Aufruf des Actionhandlers, wenn die folgenden Bedingungen erfüllt sind

  • Es ist ein Handler zugewiesen.

  • Das entsprechende Bit ist in der Instancevariablen sendMouseEvents gesetzt.

  • Bei den mit (G) gekennzeichneten Ereignissen: Das Objekt hat die Maus "gegrabbt".

    Diese Beschränkung gilt nicht für VisContent und BitmapContent. Für sie gelten nur die ersten beiden Bedingungen.


Syntax UI- Code: OnMouseButon = <Handler>
OnMouseMove = <Handler>
OnMouseOver = <Handler>

Schreiben: <obj>.OnMouseButton = <Handler>
<obj>.OnMouseMove = <Handler>
<obj>.OnMouseOver = <Handler>

Durch Zuweisen des speziellen "Handlers" NoAction kann man die Zuweisung eines Handlers aufheben, z.B.

sender.OnMouseMove = NoAction
NoAction kann mit allen Handlern, nicht nur mit Maushandlern, benutzt werden.

Alle Mausaction Handler haben die folgenden Parameter:

sender: Das Objekt, welches das Mausereignis ausgelöst hat

xPos, yPos: Die Koordinaten des Mauszeigers,
relativ zur linken oberen Ecke des Objekts.

event: Information welches Ereignis zum Aufruf geführt hat.


Für event sind folgenden Konstanten definiert.

Tabelle

Anmerkungen

Doppelklicks:
Drückt der Nutzer z.B. die linke Maustaste erstmalig so wird zunächst ein LEFT_DOWN-Ereignis erzeugt. Lässt der Nutzer die Taste kurz darauf los und drückt sie ein zweites Mal (dh. er führt einen Doppelklick aus) so wird zusätzlich ein LEFT_DOUBLE-Ereignis erzeugt.

Hold-Ereignisse
Drückt der Nutzer z.B. die linke Maustaste so wird zunächst wieder ein LEFT_DOWN-Ereignis erzeugt. Hält er jetzt die Maustaste für eine bestimmte Zeit gedrückt (ca. 0,5 Sekunden) so wird zusätzlich ein LEFT_HOLD-Ereignis erzeugt. Sie können damit z.B. unterscheiden ob der Nutzer etwas nur anklicken oder es festhalten und bewegen will.

sendMouseEvents

Die Instancevariable sendMouseEvents bietet die Möglichkeit die Behandlung von Mausereignissen schnell ein- und auszuschalten. Das ist wesentlich effektiver als jedes Mal den entsprechenden Handler aufzurufen und dort abzufragen, ob er aktuell auch erwünscht ist. Insbesondere der OnMouseMove Handler wird, wenn sich die Maus über dem Objekt befindet, extrem häufig gerufen. Das kann zu einer unerwünschten Belastung und zur Verlangsamung des System führen.

SendMouseEvents ist ein Bitfeld, d.h. jedes Bit hat eine bestimmte Bedeutung. Die Bits sind identisch mit den ME_-Werten aus der Tabelle oben.

Hinweis: Per default sind alle Bits gesetzt, die sollten daher im UI-Code immer genau die Bits (ME_-Werte) setzen, die Sie benötigen. Nicht in der Tabelle aufgeführte Bits sind reserviert und sollten Null bleiben.


SyntaxUI-Code: sendMouseEvents = bits [ , mode ]
bits: Kombination der ME_-Werte (siehe oben)
mode: bestimmt, wie der übergebene Bit-Wert zu behandeln ist (siehe Tabelle unten). Defaultwert: 0(REPALACE_BITS)

Lesen: <numVar> = <obj>.sendMouseEvents (0)
Die BASIC Syntax verlangt beim Lesen von sendMouseEvents einen Parameter, weil sendMouseEvents beim Schreiben zwei Parameter hat. Der in der Klammer stehende Wert wird jedoch ignoriert.

Schreiben: <obj>.sendMouseEvents = bits [ , mode ]

Für Mode sind die folgenden Konstanten definiert:

Tabelle

Beispiele

' Ein und Ausschalten der Mauszeiger-Ereignisse
  MyMouseObj.sendMouseEvents = ME_MOVE, SET_BITS
  MyMouseObj.sendMouseEvents = ME_MOVE, CLEAR_BITS
' Lesen des sendMouseEvents-Werts und Prüfen, ob ME_MOVE
' gesetzt ist
  DIM bits as WORD
  bits = MyMouseObj.sendMouseEvents ( 0 )
  IF bits AND ME_MOVE THEN MsgBox "Ja"
' Prüfen ob ME_MOVE ODER ME_LEFT_UP gesetzt ist
  IF bits AND ( ME_MOVE OR ME_LEFT_UP) THEN  MsgBox "Ja"

^

Weiter...