Die direkte Nachrichtenverarbeitung

Macintosh und GEM sind durch ein prozedurales Konzept bei der Bearbeitung der vom System eintreffendenden Nachrichten geprägt. Um eine Nachricht entgegen zu nehmen, wird eine Funktion aufgerufen, die als Rückgabeparameter das nächste anstehende Ereignis und dessen Randbedingungen liefert. Es folgt eine Unterscheidung nach dem Nachrichtentyp und jeweils ein Unterprogrammaufruf der bearbeitenden Applikationsfunktionen. Diese Abfolge wird ständig wiederholt bis ein Ereignis eintritt, das das Programm als Endebedingung interpretiert. Als Beispiel für eine direkte Nachrichtenverarbeitung soll hier ein Rumpfprogramm für GEM betrachtet werden.

int GrafikHandle, ApplikationsHandle;

/* Daten zur Kommunikation mit dem System */
int work_in[11], work_out[57];
int main(void)
{
#define ENDE = -1;
int aktion = 0;

   ApplikationsHandle = appl_init();   /* Melde Applikation an */
   GrafikHandle = graf_handle( ...  );    /* Ermittle das Handle */
   for (i=0; i<10; work_in[i++] =1); work_in[10]=2;
   /* Eroeffnen der virtuellen Workstation */
   v_opnvwrk(work_in, &GrafikHandle, work_out);

   . . .

   do {
      event = evnt_multi (MU_MESAG|MU_KEYBD|MU_BUTTON,
                     ..., msg, ...);
      if (event & MU_MESAG) { /* Nachricht */
         switch (msg[0]) {
         case MN_SELECTED: /* Menuepunkt ausgewaehlt */
         switch .... {
            /* Menuepunkt unterscheiden */
         }
         case WM_REDRAW:
            /* ein Fensterbereich muss neu gezeichnet werden */
            NeuZeichnen(msg); break;
         case WM_TOPPED:
            /* Anderes Fenster ist nach vorn geholt worden */
         case WM_CLOSED: /* Fenster geschlossen */
            aktion = ENDE; break;
         case WM_SIZED:
            /* Fenster wurde in der Groesse veraendert */
         }
      }
      if (event & MU_KEYBD) {
         /* Taste gedrueckt: Scancode und ASCII untersuchen */
         aktion = ENDE;
      }
      if (event & MU_BUTTON) {
         /* Maustaste wurde betaetigt */
      }
   } (aktion != ENDE);

   v_clsvwk(GrafikHandle);  /* schliesse die Workstation wieder */
   appl_exit();      /* Applikation abmelden */
}
Zu Anfang werden Applikationshandle und Grafikhandle angefordert. Wobei unter GEM das Grafikhandle für fast alle Funktionsaufrufe verwendet wird. Anschließend wird die virtuelle Workstation eröffnet. Diese entspricht dem Applikationsfenster der anderen Oberflächen, nur daß ein GEM-Programm den gesamten Bildschirm zur Verfügung hat. Das dabei übermittelte Array work_out enthält die wichtigsten Informationen über die Workstation wie Auflösung, Farbe und so weiter.

In der durch Punkte angedeuteten Lücke würden dann die Fenster angemeldet, die Menüleiste geladen und so weiter. Anschließend betritt das Programm eine Schleife, in der die Funktion evnt_multi alle anstehenden Ereignisse empfangen kann, die es als Maske in einer seiner Parameter spezifiziert. Anschließend wird in einer Fallunterscheidung die eingetroffene Nachricht bearbeitet. Bestimmte Ereignisse können in einer Nachricht zusammengefaßt sein. Aus diesem Grund wird der Rückgabewert nicht einfach per switch unterschieden, sondern auf die Existenz des signifikanten Bits für die jeweilige Nachricht untersucht. Viele Ereignisse liefern neben der Nachricht Parameter, die in einem Nachrichtenpuffer abgelegt sind. Im Beispiel heißt dieser msg.

Die Ereignisse, die eintreffen können, sind nur zum Teil direkt durch Aktionen des Benutzers bestimmt. Es ist auch mit Ereignissen zu rechnen, die vom System her kommen. Dazu zählen ablaufende Timer und die Meldung, daß ein Teilbereich eines Fensters wieder neu gezeichnet werden muß. Letzteres kann beispielsweise dadurch entstehen, daß ein Benutzer in Fenster so verschoben hat, daß ein unterliegendes Fenster wieder sichtbar wird. Die Schleife endet hier dadurch, daß die Variable aktion den Wert ENDE erhält. Im obigen Beispiel wird diese Zuweisung ausgeführt, wenn eine Taste gedrückt wurde (MU_KEYBD) oder bei einem Fenster die Schließbox angeklickt wurde (WM_CLOSED). Die Endebedingung des Programms liegt frei in der Gestaltung des Programmierers. Vergißt er, eine Endebedingung zu definieren, kann das Programm nur noch durch Reset des Rechners beendet werden. Es gibt also keine vom System vorgegebene Endebedingung. Zum Schluß wird die virtuelle Workstation wieder geschlossen und anschließend die Applikation beendet.

Dieses Prinzip wird auch beim Macintosh verfolgt. Einige Unterschiede sind jedoch feststellbar. Der Macintosh kennt kein Applikationshandle, stattdessen wird beim Starten des Programmes jeder benötigte Manager initialisiert. Zunächst wird die Grafikschicht, das QuickDraw angestoßen, auf das auch die anderen Manager zurückgreifen. Es folgt je nach Bedarf die Initialisierung des Fontmanagers, des Window- und des Dialogmanagers. In der Ereignisschleife erhält der Macintosh nur die fundamentalen Ereignisse, zum Beispiel, daß eine Maustaste gedrückt oder losgelassen wurde. Ob sich der Mauszeiger zu diesem Zeitpunkt in einem Menü oder im Bereich des applikationseigenen Fensters befand, muß durch Aufruf der Funktion FindWindow ermittelt werden. Deren Rückgabewert liefert erst die Information, wie das Ereignis zu interpretieren ist. Typische Werte sind:

inDesk Mauszeiger auf Hintergrund
inMenuBar Menüauswahl
inSysWindow im Fenster eines Desk-Accessories
inContent im Fensterinhalt
inDrag im Titelbalken des Fensters
inGrow Die Vergrößerungsecke
inZoomIn Box zur Vergrößerung auf Maximalgröße
inZoomOut Box zur Verkleinerung auf Ausgangsgröße


Inhaltsverzeichnis (C) Copyright 1993-1999 Arnold Willemer