Home Programmierung
und BIOS
Shareware-
FAQ
Kontakt u.
Infos

Pascal-Toolbox Nr. 3

(Meldungs-) Fenster ohne Turbo Vision (DOS)

Diesmal wollen wir eine Unit erstellen, die uns die bekannten Meldungsfenster mit Schatten erstellt.

Ich habe hierbei auf Mausunterstützung, Cursorabschaltung (demnächst in einer Toolbox zu finden...) und Buttons verzichtet, da dies (a) zu umfangreich werden würde und (b) bei Bedarf relativ schnell realisiert werden kann.


Zuerst erstellen wir den Unit-Kopf mit der Angabe der öffentlichen Prozeduren. Diese sind PopUp und MessageBox. Erstere erzeugt ein Fenster mit Schatten und Titel, letztere erzeugt unter Verwendung von PopUp ein Meldungsfenster mit Titel sowie Text- und Tastenzeile.


UNIT Fenster;

INTERFACE

PROCEDURE PopUp (XX, YY, Breit, Hoch:Integer; Title:String; BkColor, Color:Word);

PROCEDURE MessageBox(Title, InfoText, Tasten:String; BkColor, Color:Byte);

IMPLEMENTATION

USES DOS,CRT;

Zuerst definieren wir die Hilfsfunktionen:

Für den Schatten benötigen wir eine Prozedur, die den Bildschirminhalt an bestimmten Stellen auslesen kann. ReadChar übernimmt diese Aufgabe. Über Interrupt $10 (Funktion $8) läßt sich das Zeichen an der aktuellen Cursorposition auslesen. Es ist nur vorher die aktuelle Bildschirmseite in das Register BH einzutragen, welche wir aus dem BIOS-Datenbereich entnehmen. Als Ergebnis liefert der Aufruf das Char (in AL) und dessen Attribut (in AH) an der aktuellen Cursorposition.


PROCEDURE ReadChar(VAR Wort, Color:Byte);

VAR D,C,Seite:Byte;

BEGIN

  Seite:=Mem[$0040:$62];

  ASM

    Mov AH,$08;

    Mov BH,Seite;

    Int $10;

    Mov C,AL;

    Mov D,AH;

  END;

  Wort:=C;

  Color:=D;

END;

Diese grundlegende Prozedur verwenden wir nun in der folgenden Prozedur, welche den Text an der aktuellen Cursorposition schattenartig verdunkelt.
Das Zeichen an der Position wird ausgelesen, die entsprechenden Textattribute für Schatten gesetzt und das Zeichen mit den neuen Attributen geschrieben.


PROCEDURE MakeShadow;

VAR A,B:Byte;

BEGIN

  ReadChar(A,B);

  TextColor (Darkgray);

  TextBackground (Black);

  Write (Chr(A));

END;

Für die Zentrierung von Text benötigen wir später die folgende Funktion. Sie tut nichts weiter, als den übergebenen String zentriert in der aktuellen Zeile auf dem Bildschirm auszugeben.


PROCEDURE Center(Wort:String);

BEGIN

  GotoXY (40-(Length(Wort) DIV 2),WhereY);

  Write (Wort);

END;

Jetzt geht's los.
In der folgenden Funktion wird das Fenster erstellt und mit Titel und Schatten versehen.


PROCEDURE PopUp (XX, YY, Breit, Hoch:Integer; Title:String; BkColor, Color:Word);

VAR X,I:Integer;

    Middle:ShortInt;

    OldColor:Byte;

(XX:YY) gibt den Ursprung des Fensters an, Breit die Breite, Hoch die Höhe (jeweils in Zeichen), Title den Titel, der über dem Fenster stehen soll, BkColor die Hintergrund- und Color die Vordergrundfarbe.
X und I sind Hilfsvariablen, Middle dient zur Zentrierung des Titels, OldColor speichert die ursprünglichen Textattribute zwischen (sonst muß später nach Aufruf der Prozedur immer TextColor aufgerufen werden, und das ist ja nicht im Sinne des Erfinders :-))


BEGIN

  OldColor:=TextAttr;

  TextColor (Color);

  TextBackground (BkColor);

  GotoXY (XX,YY);

  Write (#201);

  FOR I:=1 TO Breit DO Write (#205);

  Writeln (#187);

  FOR X:=1 TO Hoch DO BEGIN

    GotoXY (XX,YY+X);

    Write (#186);

    FOR I:=1 TO Breit DO Write (' ');

    Writeln (#186);

  END;

  GotoXY (XX,YY+Hoch+1);

  Write (#200);

  FOR I:=1 TO Breit DO Write (#205);

  Write (#188);

  IF Title<>'' THEN BEGIN

    Middle:=Length(Title) DIV 2;

    GotoXY (XX+(Breit DIV 2)-Middle,YY);

    Write (' ',Title,' ');

  END;

Zuerst werden die aktuellen Textattribute aus der Konstante TextAttr gesichert. Dann werden die neuen Farben gesetzt und das Fenster gezeichnet (mit einer Übersicht über die einzelnen Zeichenwerte kann ich leider nicht dienen, schaut einfach mal in einer ASCII-Tabelle nach). Zum Schluß wird noch, wenn vorhanden, der Titel zentriert auf das Fenster gesetzt.


  FOR I:=1 TO Hoch+2 DO BEGIN

    GotoXY (XX+Breit+2,YY+I);

    MakeShadow;

    GotoXY (XX+Breit+3,YY+I);

    MakeShadow;

  END;

  FOR I:=1 TO Breit+1 DO BEGIN

    GotoXY (XX+I+1,YY+Hoch+2);

    MakeShadow;

  END;

  TextColor (OldColor MOD 16);

  TextBackground (OldColor DIV 16);

END;

Jetzt wird der Schatten erzeugt. Aufgrund des Dos-Zeichenformats (8x16) brauchen wir in der Breite doppelt so viele verdunkelte Zeichen wie in der Höhe, damit ein einheitliches Bild entsteht. Am Ende werden dann nur noch die Textattribute wieder zurückgesetzt.

Jetzt kommen wir zu der Meldungsbox-Prozedur:


PROCEDURE MessageBox(Title, InfoText, Tasten:String; BkColor, Color:Byte);

VAR X,XX,Posi:ShortInt;

    OldColor:Byte;

Title gibt wieder den Titel an, InfoText den Text, der angezeigt werden soll, Tasten kann entweder noch zusätzlichen Text enthalten oder die Tasten anzeigen, die gedrückt werden sollen (z.B. "Beliebige Taste drücken zum Fortfahren!"), BkColor und Color geben wieder die Farben des Fensters an.
Position und Größe des Fensters brauchen nicht angegeben werden, da die Prozedur das Fenster automatisch anpaßt und zentriert.
OldColor sichert wieder die TextAttribute, X, XX, Posi sind Hilfsvariablen.


BEGIN

  OldColor:=TextAttr;

  X:=0;

  Posi:=1;

  IF Length(InfoText)>=Length(Title) THEN X:=Length(InfoText)

  ELSE X:=Length(Title);

  IF (X<Length(Tasten)) THEN X:=Length(Tasten);

  X:=X+6;

  IF Odd(X) THEN Dec(X);

  XX:=40-(X DIV 2);

  IF Odd(XX) THEN Dec(XX);

  PopUp (XX,10,X,5,Title,BkColor,Color);

  TextColor (Color); TextBackground (BkColor);

  GotoXY (1,12);

  Center (InfoText);

  GotoXY (1,14);

  Center (Tasten);

  TextColor (OldColor MOD 16);

  TextBackground (OldColor DIV 16);

END;

END.

Zuerst werden wieder die Textattribute gesichert. Als nächstes wird bestimmt, welcher der drei übergebenen Strings der längste ist und dessen Länge in X gesichert. Dieser Wert wird dann um 6 Einheiten erhöht und in eine gerade Zahl umgewandelt (wenn nötig; Funktion Odd bzw. Dec), damit der Text nicht bündig mit dem Rand des Fensters ist, sondern mehr im Fenster ist. Dann wird X halbiert, auf eine gerade Zahl gebracht und in XX gesichert. Nun wird ein Fenster (mittels PopUp) erzeugt, und zwar mit X als Breite und XX als X-Koordinate. Die Y-Koordinate sowie die Höhe sind standardisiert und brauchen nicht verändert werden.
Nach Aufruf der Prozedur PopUp werden erneut die Farben für das Fenster gesetzt (PopUp hat ja schön brav alles wiederhergestellt), um noch die Inhalte von InfoText und Tasten mittels der Prozedur Center in das Fenster zu plazieren. Danach werden dann wieder die alten Textattribute wiederhergestellt.
Die Prozeduren sind damit komplett.

Ein Testprogramm könnte dann zum Beispiel so aussehen:


USES Crt,Fenster;

VAR X,Y:Integer;

BEGIN

  TextBackGround (Lightgray);

  TextColor (White);

  ClrScr;

  FOR X:=1 TO 79 DO

    FOR Y:=1 TO 24 DO BEGIN GotoXY(X,Y); Write (Chr(Random (26)+65)); END;

  MessageBox ('Wichtige Meldung','Dies ist ein Test','Beliebige Taste fährt fort...',Blue,Yellow);

  ReadKey;

  TextBackGround (Black);

  TextColor (Lightgray);

  ClrScr;

END.

Anmerkung: die ersten Zeilen (bis Write (Chr(Random...) sind nur dazu da, den Schatteneffekt zu verdeutlichen.

Einschränkungen der Prozeduren: Es erfolgt keine Prüfung, ob (a) die Texte länger als 80 Zeichen sind (unschöne Bildschirmausgabe) oder (b) ob das Fenster komplett auf den Bildschirm paßt.
Diese Prüfungen muß das aufrufende Programm durchführen (oder sie müssen in diese Prozeduren nachträglich noch eingebaut werden).

Die fertige Unit (ca. 2 KB) könnt Ihr hier downloaden.

Alle Angaben ohne Gewähr.

Achtung: bitte Hinweise zur Aktualitšt der Daten beachten! Copyright