home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* SCROLL.PAS *)
- (* Anzeigen und Durchblättern einer beliebigen Liste *)
- (* (c) 1988, 1991 Karsten Gieselmann & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$R-,S-,I-,V-,B-,N-}
- (* keine Fehlerprüfung, maximale Geschwindigkeit! *)
- UNIT Scroll;
-
- INTERFACE
-
- USES Crt, Dos;
-
- (* ------------ Initialisierungsroutine ----------------- *)
-
- PROCEDURE SetupScrollArea(DataSize : LONGINT;
- Normal, Selected : POINTER);
- (* definiert das aktuelle Fenster (Window-Befehl) als *)
- (* Scroll-Bereich; die zu durchblätternde Liste umfaßt *)
- (* "DataSize" Elemente(Zeilen), diese werden durch die *)
- (* Routinen bei "Normal"(normale Ausgabe) und "Selected"*)
- (* (ungleich NIL für Leuchtbalken) ausgegeben. Syntax *)
- (* der Ausgaberoutinen: *)
- (* {$F+}
- Procedure WriteLine(Col,Row : BYTE; Index : LONGINT);
- {$F-} *)
-
- (* (Col,Row) ist dabei die Ausgabeposition des ersten *)
- (* Zeichens der durch "Index" gekennzeichneten Textzeile*)
- (* in Fensterkoordinaten! *)
-
- (* --- Ansteuerung und Abfrage des Scroll-Fensters ------ *)
-
- VAR TopIndex : LONGINT;
- (* Index des Listenelements in der obersten
- Textzeile im Scroll-Fenster *)
-
- VAR SelectIndex : LONGINT;
- (* Index der durch Leuchtbalken hervorgehobenen
- Zeile im Scroll-Fenster *)
-
- VAR LinesToScroll : LONGINT;
- (* Elementumfang der anzuzeigenden Liste
- (entspricht der Zeilenzahl) *)
-
- PROCEDURE ScrollResponse(ScanCode : WORD);
- (* wertet den Tastencode "ScanCode" aus und leitet ent- *)
- (* sprechende Maßnahmen ein; über die Variablen *)
- (* "TopIndex" und "SelectIndex" kann der Zustand des *)
- (* Scroll-Fensters jederzeit abgefragt werden. *)
-
- PROCEDURE RedrawScrollArea;
- (* gibt den momentanen Inhalt des Scroll-Fensters (also *)
- (* die ersten Einträge ab "TopIndex" neu aus; die *)
- (* Position eines eventuell vorhandenen Selektbalkens *)
- (* wird dabei nicht verändert. *)
-
- (* - Sichern und Wiederherstellen eines Scroll-Zustands - *)
-
- TYPE
- ScrollPB = RECORD (* Scroll Parameter Block *)
- Left, Top, Right, Bottom : BYTE; (* Fenstergrenzen *)
- LineSave : LONGINT; (* Listenumfang *)
- TopSave, SelectSave : LONGINT; (* Zustands-Ind. *)
- Normal, Selected : POINTER; (* Ausgabe *)
- END;
-
- PROCEDURE SaveScrollArea(VAR Buffer : ScrollPB);
- (* sichert den aktuellen Zustand des Scroll-Systems *)
- (* in "Buffer" *)
-
- PROCEDURE RestoreScrollArea(VAR Buffer : ScrollPB);
- (* reinitialisiert das Scroll-System mit dem Inhalt *)
- (* von "Buffer" *)
-
-
- IMPLEMENTATION
-
- CONST
- Overlap = 1;
- (* Zahl der Überschneidungszeilen bei PgUp/PgDn *)
- VAR
- ColSize, RowSize : BYTE;
- WriteNormalProc, (* Zeiger auf Ausgaberoutinen *)
- WriteSelectedProc : POINTER;
- SelectBar : BOOLEAN;
- (* Anzeige mit Leuchtbalken? *)
-
- FUNCTION Min(a, b : LONGINT) : LONGINT;
- (* Minimum zweier LONG-INTEGER *)
- INLINE(
- $58/ (* POP AX ;Parameter a nach DX:AX *)
- $5A/ (* POP DX ; *)
- $5B/ (* POP BX ;Parameter b nach CX:BX *)
- $59/ (* POP CX ; *)
- $39/$CA/ (* CMP CX,DX ;Hi(a) mit Hi(b) vergl. *)
- $7C/$0A/ (* JL *+10 ;fertig, Hi(a) < Hi(b) *)
- $75/$04/ (* JNE *+04 ;vertauschen, wenn a <> b *)
- $39/$D8/ (* CMP AX,BX ;Lo(a) mit Lo(b) vergl. *)
- $76/$04/ (* JBE *+4 ;fertig, Lo(a) < Lo(b) *)
- $87/$C3/ (* XCHG AX,BX ;a mit b vertauschen *)
- $87/$CA); (* XCHG DX,CX ;Ergebnis steht in DX:AX *)
-
- FUNCTION Max(a, b : LONGINT) : LONGINT;
- (* Maximum zweier LONG-INTEGER *)
- INLINE(
- $58/ (* POP AX ;Parameter a nach DX:AX *)
- $5A/ (* POP DX ; *)
- $5B/ (* POP BX ;Parameter b nach CX:BX *)
- $59/ (* POP CX ; *)
- $39/$CA/ (* CMP CX,DX ;Hi(a) mit Hi(b) vergl. *)
- $7F/$0A/ (* JG *+10 ;fertig, Hi(a) > Hi(b) *)
- $75/$04/ (* JNE *+04 ;vertauschen, wenn a <> b *)
- $39/$D8/ (* CMP AX,BX ;Lo(a) mit Lo(b) vergl. *)
- $73/$04/ (* JAE *+4 ;fertig, Lo(a) > Lo(b) *)
- $87/$C3/ (* XCHG AX,BX ;a mit b vertauschen *)
- $87/$CA); (* XCHG DX,CX ;Ergebnis steht in DX:AX *)
-
- PROCEDURE SetupScrollArea(DataSize : LONGINT;
- Normal, Selected : POINTER);
- (* Definition eines Bereichs und Initialisierung des *)
- (* Scroll-Systems *)
- BEGIN
- LinesToScroll := DataSize;
- WriteNormalProc := Normal;
- WriteSelectedProc := Selected;
- SelectBar := (Selected <> NIL);
- ColSize := Succ(Lo(WindMax)-Lo(WindMin));
- RowSize := Succ(Hi(WindMax)-Hi(WindMin));
- TopIndex := 1;
- SelectIndex := Ord(SelectBar);
- (* Null, falls kein Leuchtbalken *)
- END;
-
- PROCEDURE WriteNormal(Col, Row : BYTE; Index : LONGINT);
- (* springt zur Ausgaberoutine f. normale Listenelemente *)
- INLINE ($FF/$1E/WriteNormalProc);
-
- PROCEDURE WriteSelected(Col, Row : BYTE; Index : LONGINT);
- (* springt zur Ausgaberoutine für Leuchbalken-Element *)
- INLINE ($FF/$1E/WriteSelectedProc);
-
- PROCEDURE WriteList(Index : LONGINT);
- (* listet die ersten ab "Index" beginnenden Einträge *)
- VAR
- Row : BYTE;
- BEGIN
- TopIndex := Index; (* Zeilenzeiger aktualisieren *)
- FOR Row := 1 TO Min(LinesToScroll, RowSize) DO
- IF Pred(Index+Row) <> SelectIndex THEN
- WriteNormal(1, Row, Pred(Index+Row))
- ELSE
- WriteSelected(1, Row, Pred(Index+Row));
- END;
-
- PROCEDURE ScrollResponse(ScanCode : WORD);
- (* Auswertung der Taste "ScanCode" *)
- CONST
- Home = $4700; End_ = $4F00;
- PgUp = $4900; PgDn = $5100;
- Up = $4800; Down = $5000;
-
- PROCEDURE ScrollList(Increment : SHORTINT);
- (* rollt Fenster um "Increment" Zeilen *)
-
- PROCEDURE ScrollWindow(Left,Top,Right,Bottom : BYTE;
- Lines : SHORTINT);
- (* Aufruf der BIOS-Scrollroutine *)
- VAR
- Regs : Registers;
- BEGIN
- WITH Regs do BEGIN
- IF Lines > 0 THEN
- AH := 6 (* Scrolle Bildschirm aufwärts *)
- ELSE
- AH := 7; (* Scrolle Bildschirm abwärts *)
- AL := Abs(Increment);
- (* Zahl der zu scrollenden Zeilen *)
- BH := TextAttr;
- CL := Pred(Left) + Lo(WindMin);
- (* Fenster-Koordinaten *)
- CH := Pred(Top) + Hi(WindMin);
- DL := Pred(Right) + Lo(WindMin);
- DH := Pred(Bottom) + Hi(WindMin);;
- Intr($10, Regs);
- END;
- END;
-
- BEGIN
- ScrollWindow(1, 1, ColSize, RowSize, Increment);
- TopIndex := TopIndex+Increment;
- IF Increment < 0 THEN
- IF SelectBar THEN
- WriteSelected(1, 1, TopIndex)
- ELSE
- WriteNormal(1, 1, TopIndex)
- ELSE
- IF SelectBar THEN
- WriteSelected(1, RowSize, Pred(TopIndex+RowSize))
- ELSE
- WriteNormal(1, RowSize, Pred(TopIndex+RowSize))
- END;
-
- BEGIN
- CASE ScanCode OF
-
- Home : (* Liste von Anfang an zeigen *)
- BEGIN
- IF SelectBar THEN SelectIndex := 1;
- WriteList(1);
- END;
-
- End_ : (* Liste bis zum Ende zeigen *)
- BEGIN
- IF SelectBar THEN SelectIndex := LinesToScroll;
- WriteList(Max(1, LinesToScroll-Pred(RowSize)));
- END;
-
- PgUp : (* eine Seite aufwärts blättern *)
- BEGIN
- IF SelectBar THEN
- SelectIndex :=
- Max(1, LONGINT(SelectIndex)-RowSize+Overlap);
- WriteList(Max(1,
- LONGINT(TopIndex)-RowSize+Overlap));
- END;
-
- PgDn : (* eine Seite abwärts blättern *)
- BEGIN
- IF SelectBar THEN
- SelectIndex :=
- Min(LinesToScroll, SelectIndex+RowSize-Overlap);
- WriteList(Min(Max(1,
- LinesToScroll-Pred(RowSize)),
- TopIndex+RowSize-Overlap));
- END;
-
- Up : (* eine Zeile aufwärts blättern *)
- IF SelectBar THEN
- IF SelectIndex > 1 THEN
- IF SelectIndex = TopIndex THEN BEGIN
- Dec(SelectIndex);
- WriteNormal(1, SelectIndex-TopIndex+2,
- Succ(SelectIndex));
- ScrollList(-1);
- END ELSE BEGIN
- Dec(SelectIndex);
- WriteNormal(1, SelectIndex-TopIndex+2,
- Succ(SelectIndex));
- WriteSelected(1, SelectIndex-Pred(TopIndex),
- SelectIndex);
- END
- ELSE
- ELSE
- IF TopIndex > 1 THEN ScrollList(-1);
-
- Down : (* eine Zeile abwärts blättern *)
- IF SelectBar THEN
- IF SelectIndex < LinesToScroll THEN
- IF SelectIndex = Pred(TopIndex+RowSize)
- THEN BEGIN
- Inc(SelectIndex);
- WriteNormal(1, SelectIndex-TopIndex,
- Pred(SelectIndex));
- ScrollList(+1);
- END ELSE BEGIN
- Inc(SelectIndex);
- WriteNormal(1, SelectIndex-TopIndex,
- Pred(SelectIndex));
- WriteSelected(1, SelectIndex-Pred(TopIndex),
- SelectIndex);
- END
- ELSE
- ELSE
- IF Pred(TopIndex+RowSize) < LinesToScroll THEN
- ScrollList(+1);
- END;
- END;
-
- PROCEDURE RedrawScrollArea;
- (* Neuausgabe der Scroll-Liste ab "TopIndex" *)
- BEGIN
- WriteList(TopIndex);
- END;
-
- PROCEDURE SaveScrollArea(VAR Buffer : ScrollPB);
- (* sichert den aktuellen Zustand des Scroll-Systems *)
- (* in "Buffer" *)
- BEGIN
- WITH Buffer DO BEGIN
- Left := Succ(Lo(WindMin));
- Top := Succ(Hi(WindMin));
- Right := Succ(Lo(WindMax));
- Bottom := Succ(Hi(WindMax));
- LineSave := LinesToScroll;
- TopSave := TopIndex;
- SelectSave := SelectIndex;
- Normal := WriteNormalProc;
- Selected := WriteSelectedProc;
- END;
- END;
-
- PROCEDURE RestoreScrollArea(VAR Buffer : ScrollPB);
- (* reinitialisiert das Scroll-System mit dem Inhalt *)
- (* von "Buffer" *)
- BEGIN
- WITH Buffer DO BEGIN
- Window(Left, Top, Right, Bottom);
- SetupScrollArea(LineSave, Normal, Selected);
- TopIndex := TopSave;
- SelectIndex := SelectSave;
- END;
- END;
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von SCROLL.PAS *)