Einige Stze ber WIND_UPDATE:

WIND_UPDATE (im folgenden mit WU abgekrzt) dient der Synchronisation der
Bildschirmausgabe verschiedener Programme und Accessoires, und der Sperrung
von Maus- und Tastatureingaben. Ihre Verwendung merkt man auf dem Bildschirm
nicht, doch hat ihre Nichtverwendung je nach Standpunkt interessante oder
rgerliche Folgen, zum Beispiel durch Dialoge hindurchgehende Mausklicks oder
Unsauberkeiten beim Bildschirmredraw.
Mit anderen Worten, diese Funktion ist WICHTIG! Unter MultiTOS und anderen
Multitaskern ist ihre Verwendung Pflicht, sonst bricht auf dem Bildschirm das
Chaos aus!

I. zu WIND_UPDATE(xxx_UPDATE):

  Durch BEG_UPDATE wird jeder AES-Prozess solange angehalten, bis kein anderer
  Prozess mehr auf den Bildschirm schreibt. Erst dann wird der Programmablauf
  fortgesetzt und der Proze schreibt _alleine_ auf den Bildschirm, bis er
  WIND_UPDATE(END_UPDATE) aufruft.
  ==> WIND_UPDATE(xxx_UPDATE) immer paarweise aufrufen.

  Dieses Verfahren funktioniert natrlich nur dann, wenn alle Prozesse
  WIND_UPDATE korrekt benutzen. D.h., da alle Ausgaben auf den Bildschirm,
  bzw. Vernderungen desselben in WU(xxx_UPDATE) geklammert sein mssen.
  Um andere Prozesse nicht zu lange zu behindern, sollte WU nur sparsam
  genutzt werden, also nach Mglichkeit direkt vor der Bildschirmausgabe
  aufgerufen werden und direkt danach beendet werden:
   ~WIND_UPDATE(BEG_UPDATE)
   PRINT "Hallo Welt"       ! i know, it's Bios. Nethertheless, this is only
   ~WIND_UPDATE(END_UPDATE) ! an example.

  Soweit, so einfach. Leider gibt es ein noch ein paar Probleme zu beachten:
  - Whrend der Auswertung der Rechteckliste (beim Redraw eines Fensters) kann
    diese unter Umstnden verndert werden, so da der Redraw eventuell
    unvollstndig erfolgt. WU(xxx_update) wirkt auch dagegen und sollte also
    wie folgt verwendet werden:
      IF redrawmessage THEN
        VOID WIND_UPDATE(BEG_UPDATE)
        eigentlicher Redraw mit Auswertung der Rechteckliste
        VOID WIND_UPDATE(END_UPDATE)
      END

  - hnliches gilt fr WIND_GET(x,WF_TOP,xx): Auch das oberste Fenster kann
    wechseln. Es gibt interessante Effekte, wenn whrend des Bildschirmaufbaus
    ein anderes Fenster nach oben geklickt wird, deshalb:
      WIND_UPDATE(BEGUPDATE);  (* die Reihenfolge dieser beiden NICHT *)
      WIND_GET(0,WFTOP,handle,3 dummys); (* vertauschen !!*)
      IF (handle = myhandle) THEN
        zeichnen des Fensters;
      ELSE
        mglicherweise Senden einer Redrawmessage an sich selbst;
      END;
      WIND_UPDATE(END_UPDATE)

  - Bei Diskettenfehlern wirft das System eine Alertbox auf den Bildschirm. So
    nett das auch ist, verursacht es doch ein Problem, da das AES nicht
    reentrant ist. Bse Abstrze knnen die Folge sein, wenn z.B. bei
    RSRC_LOAD keine Diskette eingelegt ist!
    Auch hier bietet WIND_UPDATE die Lsung des Problems: Um alle  Datei- oder
    Diskoperationen, egal ob auf BIOS-, AES-, GEMDOS- oder VDI-Ebene gehrt
    ein WIND_UPDATE(xxx_UPDATE).
    ABER: Bitte nicht das gesamte Einlesen oder Schreiben einer Datei in
    WIND_UPDATE klammern! Ich mchte ganz gerne, whrend mein Graphikprogramm
    eine lange Datei ldt, noch mit dem Editor arbeiten knnen! Also bitte NUR
    die I/O-Befehle selbst schtzen!

  - Vor WIND_NEW mu ein WIND_UPDATE(BEG_UPDATE) stehen, nach WIND_NEW sind
    alle WIND_UPDATE's aufgehoben! Also Vorsicht.

  Faustregel:
  WIND_UPDATE(xxx_UPDATE) gehrt:
  - um alle Vernderungen des Bildschirmaufbaus, die nicht nur durch
   AES-Fensterfunktionen geschehen.
  - um alle Datei/Diskoperationen. RSRC_LOAD, VST_LOAD_FONTS nicht
   vergessen!
  - um Abfragen der Rechteckliste und des Bildschirmaufbaus.
  - nicht um WIND_SET,CREATE,OPEN, CLOSE, DELETE, CALC und _nicht_ um die
   Eventfunktionen.
  - um alle bildschirmverndernden (ausgebenden) VDI-Funktionen.
  - Vor WIND_NEW.

II. zu WIND_UPDATE(xxx_MCTRL)

  WU(xxx_MCTRL) lenkt ALLE Maus- und Tastaturevents auf das eigene Programm
  um. Ohne WIND_UPDATE(xxx_MCTRL) gehen die Tastaturevents an den Prozess mit
  dem obersten Fenster und alle Mausevents an den "Besitzer" des betroffenen
  Bildschirmausschnitts.
  Zuviel davon ist fr Multitasking schdlich, da unter anderem auch die
  Menleiste gesperrt wird.

  MCTRL sollte man deshalb nur sehr sparsam verwenden, also nur dort, wo es
  sein MUSS. Dies ist der Fall bei:
  - FORM_DO-Aufrufen. Sie mssen in WU(x_MCTRL) geklammert sein, da sonst die
    Mausklicks an das Fenster darunter gemeldet werden - ein sehr
    "interessanter", aber auch strender Effekt.
  - GRAF_SLIDEBOX, GRAF_RUBBOX, GRAF_DRAGBOX.
  - Aufrufen des Fileselectors. Der ist intern nichts anderes als eine
    Dialogbox und sollte auch so behandelt werden.

  Faustregel:
  WIND_UPDATE(xxx_MCTRL) sollte immer dann verwendet werden, wenn man die
  Mausklicks auf dem gesamten Bildschirm (also nicht nur fr die eigenen
  Fenster) selbst verwalten will oder Dialogboxen aufruft. Auch dann ist es
  nach Mglichkeit sehr sparsam zu verwenden.


III Typische Fehler
  - Mausklick geht durch den Dialog hindurch?
       ==> WIND_UPDATE(xxx_MCTRL) vergessen.
  - whrend des Redraws kann ein anderes Fenster getopped werden und wird
    berzeichnet?
       ==> WIND_UPDATE(xxx_UPDATE) vergessen.
  - In der Fileselectbox kann die Menleiste bedient werden?
       ==> WIND_UPDATE(xxx_MCTRL) vergessen.
  - Beim Verschieben von Icons werden darunterliegende Fenster getopped?
       ==> WIND_UPDATE(xxx_MCTRL) vergessen.
  - Menleiste kann nicht angefahren werden?
       ==> Irgendwo im Programm oder ACC wurde WIND_UPDATE falsch benutzt, die
           Aufrufe haben sich nicht aufgehoben. Eine beliebte Ursache ist, da
           irgendwann statt eines WIND_UPDATE(BEG_UPDATE) ein BEG_MCTRL
           gettigt wurde und zum Zurcksetzen ein END_UPDATE.
  - Abstrze bei fehlerhaft verlaufenen Diskoperationen, z.B. nicht
    eingelegter Diskette?
        ==> Mglicherweise WIND_UPDATE(xxx_UPDATE) vergessen.

IV. und dann wre da noch WIND_NEW

  WIND_NEW lscht nicht nur _alle_ Fenster, sondern setzt auch die
  WIND_UPDATE-Schachtelungen zurck. Mit anderen Worten: Die Mauskontrolle ist
  wieder freigegeben, der Bildschirm gehrt niemanden. Vor der nchsten
  Ausgabe MUSS deshalb erneut WIND_UPDATE(BEG_UPDATE) aufgerufen werden.
  Es empfiehlt sich deshalb sehr, mit WIND_NEW vorsichtig umzugehen.

  *Vor* WIND_NEW *mu* ein WIND_UPDATE(BEG_UPDATE), stehen, sonst kann es zu
  Problemen kommen.

V. WIND_UPDATE im GFA-BASIC-Interpreter

  Ein hufig auftretendes Problem ist, da bei Programmabbrchen
  (CTRL-ALT-SHIFT oder Fehler) WIND_UPDATE-Schachtelungen nicht beendet werden
  und beim nchsten Programmlauf die Menleiste nicht mehr anwhlbar ist. Es
  gibt Leute, die lsen dieses Problem durch Reset oder Rckkehr in den
  Desktop, und es gibt Andere, die erledigen dies geschickter.
  Bis zum Wochenende habe ich geglaubt, die zweite Gruppe wre zahlenmig weit
  berlegen, aber am Sonntag hat mir dann ein Bekannter erklrt, da er eben
  auch deshalb nicht unter GEM programmiert. Und ein anderer Bekannter hat 
  dazu mit dem Kopf genickt :-(

  Die Lsung des Problem ist ziemlich simpel, man arbeitet in den
  Programmanfang
    ON ERROR GSOUB ende
    ON BREAK GOSUB ende ! oder eine andere Prozedur, die bei Programmabbruch
    '                     "ende" aufruft.
  ein. Statt eines direkten WIND_UPDATE-Aufrufs ruft man selbstgeschriebene
  Prozeduren auf, die die Anzahl der Aufrufe mitzhlen.
  Die Prozedur "ende" setzt dann die WIND_UPDATE's zurck.

Uwe Ohse @ PB

