Event
Übersicht
Windows
Ressourcen
Beispiele
Erweiterungen
 

Allgemeines zur Message-Queue unter Windows

Windows setzt jede Aktion des Benutzers in eine Nachricht um und speichert diese in einer Nachrichtenwarteschlange Jede Anwendung muß diese Nachrichtenwarteschlange zyklisch abfragen.
Windows ermittelt für jede Nachricht den zugehörigen Empfänger in Abhängigkeit von der Sichtbarkeit.
Wird von einem Programm ein Fenster erstellt, so wird für dieses von Windows eine Message-Queue (Nachrichtenwarteschlange) angelegt.
Das ist eine Speicherstruktur ähnlich einer Liste von Arbeitsschritten.
In diese Liste werden alle das Fenster und seine Unterfenster betreffenden auftretenden Ereignisse, wie z.B. Mausveränderungen (Position, Bewegungen, Clicks, ...), Fensterveränderungen (Ort, Größe, Position, ...) u.v.a. eingefügt.
Was ganz vorne steht, kann als nächstes vom WindowCallback verarbeitet werden, der Rest wartet bis er ganz vorne auf der Liste ist.
Dabei werden die Ereignisse aber nicht einfach nur ‚hinten angefügt’, sondern aufgrund verschiedener Prioritäten teilweise bevorzugt behandelt.
Zudem gibt es noch Echtzeit-Ereignisse, die rennen gleich an der ganzen Schlange vorbei und regeln ganz vorne ihre Angelegenheit bis sie fertig sind, während die anderen warten.

Event handling

Es gibt zwei Funktionen, mit welchen ein Ereignis abgefragt werden kann.
Diese sind WindowEvent und WaitEvent, wobei der einzige Unterschied darin besteht, das WaitEvent darauf wartet bis etwas geschieht und erst dann einen Wert ausgibt, während WindowEvent bei jedem Aufruf entweder das Event, oder solange nichts passiert ist, den Wert '0' zurück gibt.
WindowEvent sollte vermieden werden, da das Programm auch wenn es nicht benutzt wird die CPU stark belastet.

Do 'warte auf "Fenster schließen" Loop Until WaitEvent = EventClose Vom Programm aus muss immer wieder überprüft werden, ob in der Message-Queue neue Anweisungen für das Fenster vorliegen, so dass darauf entsprechend reagiert werden kann.
Dies geschieht unter Windows normalerweise über eine Callback-Prozedur (eine von außen meist häufig wiederkehrend aufgerufene Prozedur). Dem WindowCallback.

Windows9 bietet da aber zusätzlich mit WaitEvent und WindowEvent zwei bequeme Alternativen. Diese beiden Funktionen verwalten intern den WindowCallback eigenständig und kümmern sich dabei um einen Teil der Ereignisse selbst.
Nach ‚Außen’ - als Rückgabewert an das Programm - schicken sie nur solche Ereignisse, die in den meisten Fällen vom Programmierer behandelt werden wollen (spezielle Ereignisse werden also von WindowEvent nicht an das Programm weitergegeben, z.B. für diese muss ein eigener WindowCallback verwendet werden.).
Dies erlaubt dem Programmierer sofortige Konzentration auf die individuellen Nutzereingaben über Menüs, Gadgets, etc., lässt sich aber trotzdem mit Wissen der Message-Konstanten und/oder einem eigenen Window-Callback beliebig erweitern.

Timer

Eine Möglichkeit regelmäßig wiederkehrende Aufgaben zu erledigen sind Timer.
Hier ein Beispiel zur Anzeige der Uhrzeit, die über einen Timer jede Sekunde erneuert wird.
#Include Once "window9.bi" Var hwnd = OpenWindow("Nr. 4b",30,30,300,150) 'Fenster erstellen TextGadget(11,50,20,200,55,Time,SS_CENTER Or SS_SUNKEN) 'Textfeld SetGadgetFont(11,Cast(Integer,LoadFont("arial",36))) 'große Zahlen Dim As Integer Timer1 SetTimer(hwnd, Timer1, 1000, NULL) 'Timer initialisieren Do Var event=WindowEvent() If event=EventClose Then 'Fenster geschlossen? KillTimer(hwnd, Timer1) 'Timer löschen End EndIf If event=EventTimer Then 'Timer Ereignis? SetGadgetText(11,Time) 'dann neu schreiben EndIf Loop
In diesem Beispiel wird der Timer einmal pro Sekunde, solange das Fenster aktiv ist, aufgerufen.
Sobald der Timer abgelaufen ist liefert WindowEvent einen Rückgabewert vom Typ EventTimer.
Der Timer wird nun erneut mit dem Wert von 1000ms gestartet bis er durch KillTimer beendet wird.

EventGadget

Um mehrere verschiedene Gadgets benutzen zu können benötigt man den EventGadget(). Sollte man wie es in größeren Programmen üblich ist mehrere Gadgets auf einem Fenster haben bietet es sich an diese auch über ein Select / Case zu verwalten.
#Include Once "window9.bi" Var hwnd = OpenWindow("Nr. 3",30,30,480,320,WS_VISIBLE Or WS_SYSMENU) WindowColor(hwnd, BGR(200,200,200)) CenterWindow(hwnd) ButtonGadget(1,30,250,100,20,"&Hilfe") ButtonGadget(2,190,250,100,20,"&Info") ButtonGadget(3,350,250,100,20,"&Ende") Do Var event=WindowEvent() If event=EventClose Then End If event=EventGadget Then Select Case EventNumber Case 1 : MessBox("Hilfe","Dies ist die Hilfe!") Case 2 : MessBox("Info", "Dies ist ein Info!") Case 3 : MessBox("Ende", "Dies ist das Ende!") : End End Select EndIf Loop

EventPaint

Wird das Fenster verschoben, überdeckt oder der Zeichenbereich sonst gestört, muß es neu gezeichnet werden. Genau das wird durch EvenPaint ausgelöst.
#Include Once "window9.bi" Var hwnd=OpenWindow("Nr. 5",100,100,300,300) CenterWindow(hwnd) Do Var event=WindowEvent() If event=EventClose Then End If event=EventPaint Then WindowStartDraw(hwnd) 'LineDraw (Startpunkt x, y, Endpunkt x, y,Strichstärke,Farbe,Style) LineDraw(65, 65,200,200,10,&h0000ff) LineDraw(65,200,200, 65,10,&hff0000) StopDraw EndIf Loop

alle Events


Auf dieser Übersicht finden sich alle Events, die in Window9 mit WaitEvent abgefangen werden können.
Bezeichnung ID
EventSize &h005
EventActivate &h006
EventPaint &h00F
EventClose &h010
EventKeyDown &h100
EventKeyUp &h101
EventTimer &h113
EventMouseMove &h200
EventLBDown &h201
EventLBUp &h202
EventRBDown &h204
EventRBUp &h205
EventMBDown &h207
EventMBUp &h208
EventMouseWheel &h20A
EventGadget &h401
EventMenu &h402