123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092 |
- {
- This file is part of the Free Pascal Integrated Development Environment
- Copyright (c) 1996-2000 by Berczi Gabor
- ANSI support
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {.$DEFINE DEBUG}
- unit WANSI;
- {$H-}
- interface
- uses Objects,Drivers,
- {$ifdef WITH_CRT}
- Crt,
- {$endif WITH_CRT}
- Dos,Views,App;
- const
- {$ifndef WITH_CRT}
- { Foreground and background color constants }
- Black = 0;
- Blue = 1;
- Green = 2;
- Cyan = 3;
- Red = 4;
- Magenta = 5;
- Brown = 6;
- LightGray = 7;
- { Foreground color constants }
- DarkGray = 8;
- LightBlue = 9;
- LightGreen = 10;
- LightCyan = 11;
- LightRed = 12;
- LightMagenta = 13;
- Yellow = 14;
- White = 15;
- { Add-in for blinking }
- Blink = 128;
- {$endif not WITH_CRT}
- ANSIMaxParamLen = 30; { max ANSI escape sequence length }
- ANSICurPosStackSize = 20; { max number of cursor positions stored at the same time }
- Esc = #27;
- { BoundCheck constants }
- bc_MinX = 1;
- bc_MinY = 2;
- bc_MaxX = 4;
- bc_MaxY = 8;
- bc_X = bc_MinX or bc_MaxX;
- bc_Y = bc_MinY or bc_MaxY;
- bc_Min = bc_MinX or bc_MinY;
- bc_Max = bc_MaxX or bc_MaxY;
- bc_All = bc_X or bc_Y;
- type
- TANSIParam = string[ANSIMaxParamLen];
- PHookProc = ^THookProc;
- THookProc = procedure (S: string);
- PConsoleObject = ^TConsoleObject;
- TConsoleObject = object(TObject)
- CurPos : TPoint;
- Size : TPoint;
- TextAttr : byte;
- BoldOn : boolean;
- BlinkOn : boolean;
- BoundChecks: byte;
- LineWrapping: boolean;
- ReplyHook : PHookProc;
- KeyHook : PHookProc;
- WriteHook : PHookProc;
- constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- procedure Home; virtual;
- procedure ClrScr; virtual;
- procedure FillScreen(B: byte); virtual;
- procedure ClrEol; virtual;
- procedure GotoXY(X,Y: integer); virtual;
- procedure Write(Const S: string); virtual;
- procedure WriteLn(Const S: string); virtual;
- procedure WriteChar(C: AnsiChar); virtual;
- procedure WriteCharRaw(C: AnsiChar); virtual;
- procedure DelLine(LineCount: integer); virtual;
- procedure InsLine(LineCount: integer); virtual;
- procedure HighVideo; virtual;
- procedure BlinkVideo; virtual;
- procedure NoBlinkVideo; virtual;
- procedure NormVideo; virtual;
- procedure LowVideo; virtual;
- procedure TextBackground(Color: byte); virtual;
- procedure TextColor(Color: byte); virtual;
- function WhereX: integer; virtual;
- function WhereY: integer; virtual;
- procedure CursorOn; virtual;
- procedure CursorOff; virtual;
- procedure UpdateCursor; virtual;
- { --- Hook procedures --- }
- procedure Reply(S: string); virtual;
- procedure PutKey(S: string); virtual;
- destructor Done; virtual;
- private
- procedure ProcessChar(C: AnsiChar); virtual;
- end;
- PANSIConsole = ^TANSIConsole;
- TANSIConsole = object(TConsoleObject)
- ANSIParam : TANSIParam;
- ANSILevel : byte;
- ANSICurPosStack : array[1..ANSICurPosStackSize] of TPoint;
- ANSICurPosStackPtr : byte;
- constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- procedure ProcessChar(C: AnsiChar); virtual;
- function GetANSIParam: integer; virtual;
- { --- ANSI functions --- }
- procedure PushCurPos; virtual;
- procedure PopCurPos; virtual;
- procedure CursorUp(LineCount: integer); virtual;
- procedure CursorDown(LineCount: integer); virtual;
- procedure CursorForward(CharCount: integer); virtual;
- procedure CursorBack(CharCount: integer); virtual;
- procedure SetAttr(Color: integer); virtual;
- end;
- {$ifdef WITH_CRT}
- PCrtConsole = ^TCrtConsole;
- TCrtConsole = object(TANSIConsole)
- constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- procedure CursorOn; virtual;
- procedure CursorOff; virtual;
- procedure ClrScr; virtual;
- procedure ClrEol; virtual;
- procedure WriteChar(C: AnsiChar); virtual;
- procedure DelLine(LineCount: integer); virtual;
- procedure InsLine(LineCount: integer); virtual;
- procedure UpdateCursor; virtual;
- procedure TextBackground(Color: byte); virtual;
- procedure TextColor(Color: byte); virtual;
- end;
- {$endif WITH_CRT}
- const
- MaxVideoLine = 65520 div (2*MaxViewWidth); { maximum number of lines that fit in 64K }
- type
- TAnsiBuffer = array[0..MaxViewWidth*MaxVideoLine] of word;
- PAnsiBuffer = ^TAnsiBuffer;
- PANSIView = ^TANSIView;
- PANSIViewConsole = ^TANSIViewConsole;
- TANSIViewConsole = object(TANSIConsole)
- Owner : PANSIView;
- constructor Init(AOwner: PANSIView);
- procedure CursorOn; virtual;
- procedure CursorOff; virtual;
- procedure ClrScr; virtual;
- procedure ClrEol; virtual;
- procedure WriteChar(C: AnsiChar); virtual;
- procedure WriteCharRaw(C: AnsiChar); virtual;
- procedure DelLine(LineCount: integer); virtual;
- procedure InsLine(LineCount: integer); virtual;
- procedure UpdateCursor; virtual;
- procedure GotoXY(X,Y: integer); virtual;
- end;
- TANSIView = object(TScroller)
- Console : PANSIViewConsole;
- Buffer : PAnsiBuffer;
- LockCount : word;
- constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:PScrollBar);
- function LoadFile(const FileName: string): boolean;
- procedure Draw; virtual;
- destructor Done; virtual;
- procedure Write(Const S: string); virtual;
- procedure WriteLn(Const S: string); virtual;
- procedure Lock; virtual;
- procedure UnLock; virtual;
- procedure ChangeBounds(var Bounds: TRect); virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- private
- end;
- PANSIBackground = ^TANSIBackground;
- PANSIBackgroundConsole = ^TANSIBackgroundConsole;
- TANSIBackgroundConsole = object(TANSIConsole)
- Owner : PANSIBackground;
- constructor Init(AOwner: PANSIBackground);
- procedure CursorOn; virtual;
- procedure CursorOff; virtual;
- procedure ClrScr; virtual;
- procedure ClrEol; virtual;
- procedure WriteChar(C: AnsiChar); virtual;
- procedure DelLine(LineCount: integer); virtual;
- procedure InsLine(LineCount: integer); virtual;
- procedure UpdateCursor; virtual;
- procedure GotoXY(X,Y: integer); virtual;
- end;
- TANSIBackground = object(TBackground)
- Console : PANSIBackgroundConsole;
- Buffer : TAnsiBuffer;
- LockCount : word;
- constructor Init(var Bounds: TRect);
- function LoadFile(const FileName: string): boolean;
- procedure Draw; virtual;
- destructor Done; virtual;
- procedure Write(Const S: string); virtual;
- procedure WriteLn(Const S: string); virtual;
- procedure Lock; virtual;
- procedure UnLock; virtual;
- procedure ChangeBounds(var Bounds: TRect); virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- private
- end;
- implementation
- uses WUtils;
- constructor TConsoleObject.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- begin
- inherited Init;
- ReplyHook:=AReplyHook; KeyHook:=AKeyHook; WriteHook:=AWriteHook;
- BoundChecks:=bc_All; LineWrapping:=true;
- TextColor(LightGray); TextBackground(Black);
- NormVideo;
- ClrScr;
- end;
- procedure TConsoleObject.Home;
- begin
- GotoXY(1,1);
- end;
- procedure TConsoleObject.ClrScr;
- begin
- Abstract;
- end;
- procedure TConsoleObject.FillScreen(B: byte);
- var X,Y: integer;
- S : string;
- begin
- GotoXY(1,1);
- for Y:=1 to Size.Y do
- begin
- S:='';
- for X:=1 to Size.X do S:=S+chr(B);
- WriteLn(S);
- end;
- end;
- procedure TConsoleObject.ClrEol;
- begin
- Abstract;
- end;
- procedure TConsoleObject.GotoXY(X,Y: integer);
- begin
- if (BoundChecks and bc_MinX)<>0 then X:=Max(X,1);
- if (BoundChecks and bc_MaxX)<>0 then
- if LineWrapping then while (X>Size.X) and (Size.X<>0)
- do begin
- Inc(Y);
- X:=X-Size.X;
- end
- else X:=Min(X,Size.X);
- if (BoundChecks and bc_MinY)<>0 then Y:=Max(Y,1);
- if (BoundChecks and bc_MaxY)<>0 then Y:=Min(Y,Size.Y);
- CurPos.X:=X; CurPos.Y:=Y;
- UpdateCursor;
- end;
- procedure TConsoleObject.ProcessChar(C: AnsiChar);
- begin
- WriteChar(C);
- end;
- procedure TConsoleObject.WriteChar(C: AnsiChar);
- begin
- Abstract;
- end;
- procedure TConsoleObject.WriteCharRaw(C: AnsiChar);
- begin
- Abstract;
- end;
- procedure TConsoleObject.Write(Const S: string); {assembler;
- asm
- push ds
- lds si, S
- lodsb
- xor ah, ah
- mov cx, ax
- @loop:
- or cx, cx
- je @exitloop
- lodsb
- pop ds
- push ax
- call ProcessChar
- push ds
- dec cx
- jmp @loop
- @exitloop:
- pop ds
- end;}
- var Len: byte;
- I : byte;
- begin
- Len:=length(S);
- for I:=1 to Len do ProcessChar(S[I]);
- end;
- procedure TConsoleObject.WriteLn(Const S: string);
- begin
- Write(S);Write(#10);
- end;
- procedure TConsoleObject.DelLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TConsoleObject.InsLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TConsoleObject.NormVideo;
- begin
- BoldOn:=false; BlinkOn:=false;
- TextColor(LightGray);
- TextBackground(Black);
- end;
- procedure TConsoleObject.BlinkVideo;
- begin
- BlinkOn:=true;
- TextBackground(TextAttr shr 4);
- end;
- procedure TConsoleObject.NoBlinkVideo;
- begin
- BlinkOn:=false;
- TextAttr:=TextAttr and $7f;
- TextBackground(TextAttr shr 4);
- end;
- procedure TConsoleObject.HighVideo;
- begin
- BoldOn:=true;
- TextColor(TextAttr);
- end;
- procedure TConsoleObject.LowVideo;
- begin
- BoldOn:=false;
- TextAttr:=TextAttr and not $08;
- TextColor(TextAttr);
- end;
- procedure TConsoleObject.TextBackground(Color: byte);
- begin
- TextAttr:=(TextAttr and $0f) or (Color shl 4) or byte(BlinkOn)*$80;
- end;
- procedure TConsoleObject.TextColor(Color: byte);
- begin
- TextAttr:=((TextAttr and $f0) or (Color and $0f) or byte(BoldOn)*$08);
- end;
- function TConsoleObject.WhereX: integer;
- begin
- WhereX:=CurPos.X;
- end;
- function TConsoleObject.WhereY: integer;
- begin
- WhereY:=CurPos.Y;
- end;
- procedure TConsoleObject.CursorOn;
- begin
- Abstract;
- end;
- procedure TConsoleObject.CursorOff;
- begin
- Abstract;
- end;
- procedure TConsoleObject.UpdateCursor;
- begin
- Abstract;
- end;
- procedure TConsoleObject.Reply(S: string);
- begin
- if ReplyHook<>nil then ReplyHook^(S);
- end;
- procedure TConsoleObject.PutKey(S: string);
- begin
- if KeyHook<>nil then KeyHook^(S);
- end;
- destructor TConsoleObject.Done;
- begin
- inherited Done;
- end;
- {$ifdef WITH_CRT}
- constructor TCrtConsole.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- begin
- inherited Init(AReplyHook, AKeyHook, AWriteHook);
- Size.X:=Lo(Crt.WindMax); Size.Y:=Hi(Crt.WindMax);
- end;
- procedure TCrtConsole.CursorOn;
- begin
- end;
- procedure TCrtConsole.CursorOff;
- begin
- end;
- procedure TCrtConsole.ClrScr;
- begin
- Crt.ClrScr;
- GotoXY(Crt.WhereX,Crt.WhereY);
- end;
- procedure TCrtConsole.ClrEol;
- begin
- Crt.ClrEol;
- GotoXY(Crt.WhereX,Crt.WhereY);
- end;
- procedure TCrtConsole.WriteChar(C: AnsiChar);
- {var OK: boolean;}
- begin
- { OK:=((C>=#32) and (WhereX<Size.X)) or (C<#32);
- if OK then
- begin}
- System.Write(C);
- GotoXY(Crt.WhereX,Crt.WhereY);
- { end
- else Inc(CurPos.X);}
- end;
- procedure TCrtConsole.DelLine(LineCount: integer);
- var I: integer;
- begin
- for I:=1 to LineCount do Crt.DelLine;
- end;
- procedure TCrtConsole.InsLine(LineCount: integer);
- var I: integer;
- begin
- for I:=1 to LineCount do Crt.InsLine;
- end;
- procedure TCrtConsole.UpdateCursor;
- begin
- Crt.GotoXY(CurPos.X,CurPos.Y);
- end;
- procedure TCrtConsole.TextBackground(Color: byte);
- begin
- inherited TextBackground(Color);
- Crt.TextAttr:=TextAttr;
- end;
- procedure TCrtConsole.TextColor(Color: byte);
- begin
- inherited TextColor(Color);
- Crt.TextAttr:=TextAttr;
- end;
- {$endif WITH_CRT}
- constructor TANSIConsole.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
- begin
- inherited Init(AReplyHook, AKeyHook, AWriteHook);
- BoundChecks:=bc_MaxX;
- ANSIParam:=''; ANSILevel:=0; ANSICurPosStackPtr:=0;
- end;
- procedure TANSIConsole.ProcessChar(C: AnsiChar);
- var SkipThis : boolean;
- ANSIDone : boolean;
- X,Y,Z : integer;
- begin
- SkipThis:=false;
- if C=Esc then
- begin
- { Treat EscEsc as a request to print a single Escape #27 AnsiChar PM }
- if AnsiLevel=0 then
- begin
- ANSILevel:=1;
- SkipThis:=true;
- end
- else
- begin
- AnsiLevel:=0;
- WriteCharRaw(c);
- SkipThis:=true;
- end;
- end
- else if (ANSILevel=1) then
- begin
- ANSILevel:=0;
- case C of
- '[' : begin
- ANSILevel:=2;
- SkipThis:=true;
- end;
- else
- { Treat Esc+ AnyChar as a request to print that single AnsiChar raw PM }
- begin
- WriteCharRaw(c);
- SkipThis:=true;
- end;
- end;
- end;
- if SkipThis=false then
- if (ANSILevel=2)
- then begin
- ANSIDone:=true;
- case C of
- 'H','f' : if ANSIParam='' then GotoXY(1,1) else
- begin
- X:=WhereX; Y:=WhereY;
- Z:=Pos(';',ANSIParam);
- if Z=0
- then Y:=GetANSIParam
- else if Z=1 then X:=GetANSIParam
- else begin Y:=GetANSIParam; X:=GetANSIParam; end;
- GotoXY(X,Y);
- end;
- 'A' : if ANSIParam='' then CursorUp(1)
- else CursorUp(GetANSIParam);
- 'B' : if ANSIParam='' then CursorDown(1)
- else CursorDown(GetANSIParam);
- 'C' : if ANSIParam='' then CursorForward(1)
- else CursorForward(GetANSIParam);
- 'D' : if ANSIParam='' then CursorBack(1)
- else CursorBack(GetANSIParam);
- 's' : if ANSIParam='' then PushCurPos;
- 'u' : if ANSIParam='' then PopCurPos;
- 'J' : if ANSIParam='2' then begin ANSIParam:=''; ClrScr; end
- else FillScreen(GetANSIParam);
- 'K' : if ANSIParam='' then ClrEol;
- 'L' : if ANSIParam='' then InsLine(1)
- else InsLine(GetANSIParam);
- 'M' : if ANSIParam='' then DelLine(1)
- else DelLine(GetANSIParam);
- 'm' : while ANSIParam<>'' do SetAttr(GetANSIParam);
- else
- begin
- {ANSIParam:=ANSIParam+C;}
- System.Insert(C,AnsiParam,Length(AnsiParam)+1);
- ANSIDone:=false;
- end;
- end;
- if ANSIDone then
- begin
- {$IFDEF DEBUG}
- if ANSIParam<>'' then RunError(240);
- {$ENDIF}
- ANSIParam:=''; ANSILevel:=0;
- end;
- end
- else begin
- WriteChar(C);
- if C=#10 then WriteChar(#13);
- end;
- end;
- function TANSIConsole.GetANSIParam: integer;
- var P: byte;
- I,C: integer;
- begin
- P:=Pos(';',ANSIParam);
- if P=0 then P:=length(ANSIParam)+1;
- Val(copy(ANSIParam,1,P-1),I,C);
- if C<>0 then I:=0;
- Delete(ANSIParam,1,P);
- GetANSIParam:=I;
- end;
- procedure TANSIConsole.CursorUp(LineCount: integer);
- begin
- GotoXY(WhereX,WhereY-LineCount);
- end;
- procedure TANSIConsole.CursorDown(LineCount: integer);
- begin
- GotoXY(WhereX,WhereY+LineCount);
- end;
- procedure TANSIConsole.CursorForward(CharCount: integer);
- var X, Y: integer;
- begin
- X:=WhereX; Y:=WhereY;
- X:=X+CharCount;
- while (X>Size.X) do
- begin Inc(Y); Dec(X,Size.X); end;
- GotoXY(X,Y);
- end;
- procedure TANSIConsole.CursorBack(CharCount: integer);
- var X, Y: integer;
- begin
- X:=WhereX; Y:=WhereY;
- X:=X-CharCount;
- while (X<1) do begin Dec(Y); Inc(X,Size.X); end;
- GotoXY(X,Y);
- end;
- procedure TANSIConsole.PushCurPos;
- begin
- if ANSICurPosStackPtr=ANSICurPosStackSize then Exit;
- Inc(ANSICurPosStackPtr);
- ANSICurPosStack[ANSICurPosStackPtr].X:=WhereX;
- ANSICurPosStack[ANSICurPosStackPtr].Y:=WhereY;
- end;
- procedure TANSIConsole.PopCurPos;
- begin
- if ANSICurPosStackPtr=0 then Exit;
- GotoXY(ANSICurPosStack[ANSICurPosStackPtr].X,ANSICurPosStack[ANSICurPosStackPtr].Y);
- Dec(ANSICurPosStackPtr);
- end;
- procedure TANSIConsole.SetAttr(Color: integer);
- const ColorTab : array[0..7] of byte =
- (Black,Red,Green,Brown,Blue,Magenta,Cyan,LightGray);
- begin
- case Color of
- 0 : NormVideo;
- 1 : HighVideo;
- 5 : BlinkVideo;
- 7,27 : TextAttr:=(TextAttr shl 4) or (TextAttr shr 4);
- 8 : TextColor(TextAttr shr 4);
- 21,22 : LowVideo;
- 25 : NoBlinkVideo;
- 30..37 : TextColor(ColorTab[Color-30]);
- 40..47 : TextBackground(ColorTab[Color-40]);
- (* else {$IFDEF DEBUG}begin system.writeln('Unknown attr : ',Color); Halt; end{$ENDIF};*)
- end;
- end;
- constructor TANSIViewConsole.Init(AOwner: PANSIView);
- begin
- if AOwner=nil then Fail;
- inherited Init(nil,nil,nil);
- Owner:=AOwner;
- Size:=Owner^.Size;
- end;
- procedure TANSIViewConsole.CursorOn;
- begin
- Owner^.ShowCursor;
- end;
- procedure TANSIViewConsole.CursorOff;
- begin
- Owner^.HideCursor;
- end;
- procedure TANSIViewConsole.ClrScr;
- var X,Y: word;
- Pos: longint;
- begin
- GotoXY(1,1);
- if Owner<>nil then
- for X:=0 to MaxViewWidth-1 do for Y:=0 to Size.Y-1 do
- begin
- Pos:=(Owner^.Delta.Y+Y)*MaxViewWidth+X;
- Owner^.Buffer^[Pos]:=32+256*word(TextAttr);
- end;
- end;
- procedure TANSIViewConsole.ClrEol;
- var X,Y: word;
- Pos: longint;
- begin
- if Owner<>nil then
- begin
- Y:=CurPos.Y;
- for X:=CurPos.X to MaxViewWidth-1 do
- begin
- Pos:=(Owner^.Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
- Owner^.Buffer^[Pos]:=32+256*word(TextAttr);
- end;
- end;
- end;
- procedure TANSIViewConsole.WriteChar(C: AnsiChar);
- var Pos: longint;
- begin
- case C of
- #8 : begin
- CursorBack(1);
- Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
- Owner^.Buffer^[Pos]:=ord(' ')+256*word(TextAttr);
- end;
- #0..#7,#9,
- #11..#12,
- #14..#31,
- #32..#255
- : begin
- Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
- Owner^.Buffer^[Pos]:=ord(C)+256*word(TextAttr);
- GotoXY(WhereX+1,WhereY);
- end;
- #10 :
- GotoXY(WhereX,WhereY+1);
- #13 :
- GotoXY(1,WhereY);
- else {$IFDEF DEBUG}RunError(241){$ENDIF};
- end;
- end;
- procedure TANSIViewConsole.WriteCharRaw(C: AnsiChar);
- var Pos: longint;
- begin
- Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
- Owner^.Buffer^[Pos]:=ord(C)+256*word(TextAttr);
- GotoXY(WhereX+1,WhereY);
- end;
- procedure TANSIViewConsole.DelLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TANSIViewConsole.InsLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TANSIViewConsole.UpdateCursor;
- begin
- if Owner<>nil then
- if Owner^.LockCount=0 then Owner^.SetCursor(WhereX-1,WhereY-1);
- end;
- procedure TANSIViewConsole.GotoXY(X,Y: integer);
- var W: word;
- begin
- if Owner<>nil then
- while Y>MaxVideoLine do
- begin
- Move(Owner^.Buffer^[MaxViewWidth],Owner^.Buffer,SizeOf(Owner^.Buffer^)-(MaxViewWidth*2));
- W:=(MaxViewWidth*MaxVideoLine)-1-(MaxViewWidth);
- FillChar(Owner^.Buffer^[W],MaxViewWidth*2,0);
- Dec(Y);
- end;
- inherited GotoXY(X,Y);
- end;
- constructor TANSIView.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
- PScrollBar);
- begin
- inherited Init(Bounds,AHScrollBar,AVScrollBar);
- LockCount:=0; Options:=Options or ofTopSelect;
- GrowMode:=gfGrowHiX or gfGrowHiY;
- New(Buffer);
- SetLimit({MaxViewWidth}80,MaxVideoLine);
- New(Console, Init(@Self));
- Console^.Size.X:=80; Console^.Size.Y:=25;
- Console^.ClrScr;
- Console^.CursorOn;
- end;
- function TANSIView.LoadFile(const FileName: string): boolean;
- var S: PBufStream;
- OK: boolean;
- B: array[0..1023] of AnsiChar;
- I,FragSize: integer;
- begin
- {$I-}
- New(S, Init(FileName, stOpenRead, 4096));
- OK:=Assigned(S);
- Lock;
- while OK and (S^.Status=stOK) do
- begin
- FragSize:=Min(Sizeof(B),S^.GetSize-S^.GetPos);
- if FragSize=0 then Break;
- S^.Read(B,FragSize);
- OK:=(S^.Status=stOK);
- if OK then
- for I:=0 to FragSize-1 do
- self.Write(B[I]);
- end;
- Unlock;
- if Assigned(S) then Dispose(S, Done); S:=nil;
- {$I+}
- LoadFile:=OK;
- end;
- procedure TANSIView.Draw;
- var I: integer;
- Pos: longint;
- X,Y: integer;
- begin
- if LockCount<>0 then Exit;
- for I:=0 to Size.Y-1 do
- begin
- Pos:=Delta.X+(Delta.Y+I)*MaxViewWidth;
- WriteLine(0,I,Size.X,1,Buffer^[Pos]);
- end;
- if Console=nil then Exit;
- X:=Console^.WhereX-Delta.X; Y:=Console^.WhereY-Delta.Y;
- if (X<0) or (Y<0) or (X>Size.X-1) or (Y>Size.X-1)
- then HideCursor
- else begin
- ShowCursor;
- SetCursor(X-1,Y-1);
- end;
- end;
- procedure TANSIView.Write(Const S: string);
- begin
- Console^.Write(S);
- DrawView;
- end;
- procedure TANSIView.WriteLn(Const S: string);
- begin
- Console^.WriteLn(S);
- DrawView;
- end;
- procedure TANSIView.Lock;
- begin
- Inc(LockCount);
- end;
- procedure TANSIView.UnLock;
- begin
- Dec(LockCount);
- if LockCount=0 then DrawView;
- end;
- procedure TANSIView.ChangeBounds(var Bounds: TRect);
- begin
- inherited ChangeBounds(Bounds);
- { Console^.Size.X:=Size.X; Console^.Size.Y:=Size.Y;}
- end;
- procedure TANSIView.HandleEvent(var Event: TEvent);
- begin
- inherited HandleEvent(Event);
- { if Event.What=evKeyDown then
- begin
- if VScrollBar<>nil then VScrollBar^.HandleEvent(Event);
- if HScrollBar<>nil then HScrollBar^.HandleEvent(Event);
- end;}
- end;
- destructor TANSIView.Done;
- begin
- Dispose(Console, Done);
- Dispose(Buffer);
- inherited Done;
- end;
- constructor TANSIBackgroundConsole.Init(AOwner: PANSIBackground);
- begin
- if AOwner=nil then Fail;
- inherited Init(nil,nil,nil);
- Owner:=AOwner;
- Size:=Owner^.Size;
- end;
- procedure TANSIBackgroundConsole.CursorOn;
- begin
- Owner^.ShowCursor;
- end;
- procedure TANSIBackgroundConsole.CursorOff;
- begin
- Owner^.HideCursor;
- end;
- procedure TANSIBackgroundConsole.ClrScr;
- var X,Y: word;
- Pos: longint;
- begin
- GotoXY(1,1);
- if Owner<>nil then
- for X:=0 to MaxViewWidth-1 do
- for Y:=0 to Size.Y-1 do
- begin
- Pos:=X+Y*MaxViewWidth;
- Owner^.Buffer[Pos]:=32+256*word(TextAttr);
- end;
- end;
- procedure TANSIBackgroundConsole.ClrEol;
- var X,Y: word;
- Pos: longint;
- begin
- if Owner<>nil then
- begin
- Y:=CurPos.Y;
- for X:=CurPos.X to MaxViewWidth-1 do
- begin
- Pos:=X+Y*MaxViewWidth;
- Owner^.Buffer[Pos]:=32+256*word(TextAttr);
- end;
- end;
- end;
- procedure TANSIBackgroundConsole.WriteChar(C: AnsiChar);
- var Pos: longint;
- begin
- case C of
- #8 : begin
- CursorBack(1);
- Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
- Owner^.Buffer[Pos]:=ord(' ')+256*word(TextAttr);
- end;
- #0..#7,#9,
- #11..#12,
- #14..#31,
- #32..#255
- : begin
- Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
- Owner^.Buffer[Pos]:=ord(C)+256*word(TextAttr);
- GotoXY(WhereX+1,WhereY);
- end;
- #10 :
- GotoXY(WhereX,WhereY+1);
- #13 :
- GotoXY(1,WhereY);
- else {$IFDEF DEBUG}RunError(241){$ENDIF};
- end;
- end;
- procedure TANSIBackgroundConsole.DelLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TANSIBackgroundConsole.InsLine(LineCount: integer);
- begin
- Abstract;
- end;
- procedure TANSIBackgroundConsole.UpdateCursor;
- begin
- if Owner<>nil then
- if Owner^.LockCount=0 then Owner^.SetCursor(WhereX-1,WhereY-1);
- end;
- procedure TANSIBackgroundConsole.GotoXY(X,Y: integer);
- var W: word;
- begin
- if Owner<>nil then
- while Y>MaxVideoLine do
- begin
- Move(Owner^.Buffer[MaxViewWidth],Owner^.Buffer,SizeOf(Owner^.Buffer)-(MaxViewWidth*2));
- W:=(MaxViewWidth*MaxVideoLine)-1-(MaxViewWidth);
- FillChar(Owner^.Buffer[W],MaxViewWidth*2,0);
- Dec(Y);
- end;
- inherited GotoXY(X,Y);
- end;
- constructor TANSIBackground.Init(var Bounds: TRect);
- begin
- inherited Init(Bounds,' ');
- LockCount:=0;
- GrowMode:=gfGrowHiX or gfGrowHiY;
- New(Console, Init(@Self));
- Console^.Size.X:=Bounds.B.X+1; Console^.Size.Y:=Bounds.B.Y+1;
- Console^.ClrScr;
- Console^.CursorOn;
- end;
- function TANSIBackground.LoadFile(const FileName: string): boolean;
- var S: PBufStream;
- OK: boolean;
- B: array[0..1023] of AnsiChar;
- I,FragSize: integer;
- begin
- {$I-}
- New(S, Init(FileName, stOpenRead, 4096));
- OK:=Assigned(S);
- while OK and (S^.Status=stOK) do
- begin
- FragSize:=Min(Sizeof(B),S^.GetSize-S^.GetPos);
- if FragSize=0 then Break;
- S^.Read(B,FragSize);
- OK:=(S^.Status=stOK);
- if OK then
- for I:=0 to FragSize-1 do
- self.Write(B[I]);
- end;
- if Assigned(S) then Dispose(S, Done); S:=nil;
- {$I+}
- LoadFile:=OK;
- end;
- procedure TANSIBackground.Draw;
- var I: integer;
- Pos: longint;
- X,Y: integer;
- begin
- if LockCount<>0 then Exit;
- for I:=0 to Size.Y-1 do
- begin
- Pos:=I*MaxViewWidth;
- WriteLine(0,I,Size.X,1,Buffer[Pos]);
- end;
- if Console=nil then Exit;
- X:=Console^.WhereX; Y:=Console^.WhereY;
- if (X<0) or (Y<0) or (X>Size.X-1) or (Y>Size.X-1)
- then HideCursor
- else begin
- ShowCursor;
- SetCursor(X-1,Y-1);
- end;
- end;
- procedure TANSIBackground.Write(Const S: string);
- begin
- Console^.Write(S);
- DrawView;
- end;
- procedure TANSIBackground.WriteLn(Const S: string);
- begin
- Console^.WriteLn(S);
- DrawView;
- end;
- procedure TANSIBackground.Lock;
- begin
- Inc(LockCount);
- end;
- procedure TANSIBackground.UnLock;
- begin
- Dec(LockCount);
- if LockCount=0 then DrawView;
- end;
- procedure TANSIBackground.ChangeBounds(var Bounds: TRect);
- begin
- inherited ChangeBounds(Bounds);
- { Console^.Size.X:=Size.X; Console^.Size.Y:=Size.Y;}
- end;
- procedure TANSIBackground.HandleEvent(var Event: TEvent);
- begin
- inherited HandleEvent(Event);
- { if Event.What=evKeyDown then
- begin
- if VScrollBar<>nil then VScrollBar^.HandleEvent(Event);
- if HScrollBar<>nil then HScrollBar^.HandleEvent(Event);
- end;}
- end;
- destructor TANSIBackground.Done;
- begin
- Dispose(Console, Done);
- inherited Done;
- end;
- END.
|