[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]
{
> I am writing a small replacement for the DOS command TYPE and one
> of the things I would like to add is a scroll back buffer...
> Q: How do I intercept the lines that are scrolling off page?
> Is there a interupt that I may hook in to or ...
Doesn't have a filesize check. Parts of it could be improved.
From: R.A.M.vGeel@kub.nl (GEEL R.A.M.VAN)
}
program show;
uses dos, crt;
const
NoMSG = 0;
msgNoPar = 1;
msgNoFile = 2;
msgNoDrive = 152;
msgNoClose = 10;
msgWrongKey = 100;
type
FileNameString = string[80];
PNewLine = ^NewLine;
NewLine = Record
Line : string[79];
Next, Prev : PNewLine;
end;
TFiler = object
FileName : string[80];
InFile : text;
MSGStatus : byte;
constructor Init;
procedure DoMsg(MsgNr : byte); virtual;
function GetFileName : FileNameString; virtual;
function OpenIt : byte; virtual;
function CloseIt : byte; virtual;
destructor Done; virtual;
end;
TShower = object(TFiler)
Screen : array[1..2000] of word;
Xcor, Ycor : byte;
CurSize : word;
Text : PNewLine;
ScrolFac : integer;
Tmp : PNewLine;
constructor Init;
procedure DoMsg(MsgNr : byte); virtual;
procedure Cursor; virtual;
procedure NoCursor; virtual;
procedure SaveScreen; virtual;
procedure RestoreScreen; virtual;
procedure ReadIn; virtual;
procedure ShowText; virtual;
function UpdatePointer: boolean; virtual;
procedure Go; virtual;
destructor Done; virtual;
end;
var
AShower : TShower;
constructor TFiler.Init;
begin
FileName := GetFileName;
if MSGStatus <> NoMsg then DoMsg(MSGStatus);
MSGSTatus := OpenIt;
if MSGStatus <> NoMSG then DoMSG(MSGStatus);
end;
procedure TFiler.DoMsg(MSGNr : byte);
begin
case MSGNr of
msgNoPar :
begin
writeln('* * SHOW (c) 1994 Robert van Geel * *');
writeln;
writeln('Usage: SHOW <filename>');
halt(1);
end;
msgNoFile :
begin
writeln('File not found');
halt(1);
end;
msgNoClose :
begin
writeln('Could not close file');
MSGStatus := NoMsg;
end;
msgNoDrive :
begin
writeln('Drive not ready');
halt(1);
end;
end;
end;
function TFiler.GetFileName : FileNameString;
begin
If ParamCount > 0 then
GetFileName := ParamStr(1)
else MsgStatus := MSGNoPar;
end;
function TFiler.OpenIt : byte;
var
nr : byte;
begin
{$I-}
assign(InFile, FileName);
reset(InFile);
nr := IOResult;
OpenIt := nr;
{$I+}
end;
function TFiler.CloseIt : byte;
begin
{$I-}
close(InFile);
CloseIt := IOResult;
{$I+}
end;
destructor TFiler.Done;
begin
MsgStatus := CloseIt;
if MSGStatus <> NoMSG
then DoMsg(MSGStatus);
end;
{ ********************************************************************** }
constructor TShower.Init;
begin
inherited init;
SaveScreen;
ReadIn;
NoCursor;
SaveScreen;
{ textcolor(yellow);
textbackground(blue);
} clrscr;
end;
procedure TShower.DoMsg(MSGNr : byte);
begin
inherited DoMsg(MsgNr);
case MSGNr of
msgWrongKey :
begin
gotoxy(1, 24);
writeln('KEY HAS NO FUNCTION HERE');
MsgNr := NoMsg;
end;
end;
end;
procedure TShower.NoCursor;
var s : word;
begin
asm
mov ah,03h
mov bh,0
int 10h
mov s,cx
mov ah,01h
mov bh,0
mov cx,2000h
int 10h
end;
cursize := s;
end;
procedure TShower.Cursor;
var s:word;
begin
s:=CurSize;
asm
mov ah,01h
mov bh,0
mov cx,s
int 10h
end;
end;
procedure TShower.SaveScreen;
begin
move(memw[$B800:$0], Screen, 4000);
XCor := wherex;
YCor := wherey;
end;
procedure TShower.RestoreScreen;
begin
move(Screen, memw[$B800:$0], 4000);
gotoxy(XCor, YCor);
end;
function TShower.UpdatePointer: boolean;
var
k : integer;
changed : boolean;
begin
changed := false;
while (ScrolFac > 0) and (Text^.Next <> nil) do
begin
changed := true;
Text := Text^.Next;
dec(ScrolFac);
end;
while (ScrolFac < 0) and (Text^.Prev <> nil) do
begin
changed := true;
Text := Text^.Prev;
inc(ScrolFac);
end;
Tmp := Text;
UpdatePointer := changed;
end;
procedure TShower.ShowText;
var
LinesWritten : integer;
OneMore : boolean;
begin
LinesWritten := 0;
OneMore := true;
gotoxy(1,1);
while OneMore and (LinesWritten < 25) do
begin
write(tmp^.Line);
clreol;
inc(LinesWritten);
if LinesWritten < 25 then
begin
writeln;
clreol;
end;
if tmp^.next <> nil then tmp := tmp^.Next
else OneMore := false;
end;
while LinesWritten < 24 do
begin
writeln;
clreol;
inc(LinesWritten);
end;
end;
procedure TShower.Go;
var
Ch : char;
begin
tmp := Text;
ShowText;
while Ch <> #01 do
begin
Ch := ReadKey;
case ch of
#0 : ;
#72 : ScrolFac := -1; {omhoog}
#80 : ScrolFac := 1; {omlaag}
#73 : ScrolFac := -25; {page up}
#81 : ScrolFac := 25; {page down}
else Ch := #01;
end;
if ScrolFac <> 0 then
begin
if UpdatePointer then ShowText;
end;
end;
end;
procedure TShower.ReadIn;
var
cur : PNewLine;
begin
new(Text);
with Text^ do
begin
readln(InFile, Line);
Next := nil;
Prev := nil;
end;
cur := Text;
while not EOF(InFile) do
begin
new(tmp);
with tmp^ do
begin
readln(InFile, tmp^.line);
tmp^.prev := cur;
cur^.next := tmp;
tmp^.next := nil;
end;
cur := tmp;
tmp := nil;
end;
cur := nil;
tmp := nil;
end;
destructor TShower.Done;
begin
inherited Done;
while text^.next <> nil do
begin
text := text^.next;
dispose(text^.prev);
text^.prev := nil;
end;
dispose(text);
text := nil;
Cursor;
RestoreScreen;
end;
begin
AShower.Init;
AShower.Go;
AShower.Done;
end.
[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]