1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090 |
- {
- 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;
- 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: char); virtual;
- procedure WriteCharRaw(C: char); 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: char); 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: char); 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: char); 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: char); virtual;
- procedure WriteCharRaw(C: char); 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: char); 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: char);
- begin
- WriteChar(C);
- end;
- procedure TConsoleObject.WriteChar(C: char);
- begin
- Abstract;
- end;
- procedure TConsoleObject.WriteCharRaw(C: char);
- 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: char);
- {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: char);
- 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 char 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 char 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: char);
- 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: char);
- 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 char;
- 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: char);
- 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 char;
- 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.
|