home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
sibdemo3.zip
/
SOURCE.DAT
/
SOURCE
/
RTL
/
WINCRT.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1997-11-09
|
45KB
|
1,598 lines
UNIT WinCrt;
INTERFACE
{$H-}
{$IFDEF OS2}
USES Os2Def,PmWin,PmGpi,BseDos,BseTib;
CONST
{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;
VAR
CheckBreak: BOOLEAN; { Ctrl-Break check }
CheckEOF: BOOLEAN; { Ctrl-Z for EOF? }
NormAttr:WORD; { Normal text attribute}
PROCEDURE ClrScr;
PROCEDURE GotoXY(X,Y:BYTE);
PROCEDURE Window(X1,Y1,X2,Y2:BYTE);
PROCEDURE TextColor(Color:BYTE);
PROCEDURE TextBackground(Color:BYTE);
FUNCTION WhereX: Byte;
FUNCTION WhereY: WORD;
PROCEDURE ClrEol;
PROCEDURE InsLine;
PROCEDURE DelLine;
PROCEDURE LowVideo;
PROCEDURE NormVideo;
PROCEDURE HighVideo;
FUNCTION KeyPressed: BOOLEAN;
FUNCTION ReadKey: CHAR;
PROCEDURE TextMode(Mode: Integer);
PROCEDURE Delay(ms:LONGWORD);
{Sound/NoSound are not implemented, they are replaced by beep}
PROCEDURE Beep(Freq,duration:LONGWORD);
TYPE
PScreenBuffer=^TScreenBuffer;
TScreenBuffer=ARRAY[1..50,1..80] OF CHAR;
PColorBuffer=^TColorBuffer;
TColorBuffer=ARRAY[1..51,1..81] OF BYTE;
TYPE
TWinCrtScreenInOutClass=CLASS
PRIVATE
ScreenBuffer:PScreenBuffer;
ColorBuffer:PColorBuffer;
BufferSize:WORD;
xPos,yPos:WORD;
MaxX,MaxY:WORD;
Handle,FrameHandle:HWND;
PUBLIC
PROCEDURE WriteStr(CONST s:STRING);VIRTUAL;
PROCEDURE WriteCStr(CONST s:CSTRING);VIRTUAL;
PROCEDURE WriteLF;VIRTUAL;
PROCEDURE ReadLF(VAR s:STRING);VIRTUAL;
PROCEDURE GotoXY(x,y:BYTE);VIRTUAL;
CONSTRUCTOR Create;
PROCEDURE SetupScreenBuffer(x,y:WORD);
PROCEDURE CreateWindow;
PROCEDURE RedrawAll;
PROCEDURE Redraw(_hps:HPS;rc:RECTL);
PROCEDURE DrawLine(_hps:HPS;y:BYTE;createfont:BOOLEAN);
PROCEDURE SetCursor(x,y:BYTE);
END;
IMPLEMENTATION
PROCEDURE WinCrtError;
BEGIN
Writeln('Textmode Linker mode does not support PM screen IO.');
Writeln('Use the unit Crt if you wish to use text');
Writeln('screen IO inside textmode applications.');
Halt(0);
END;
FUNCTION ConvertColor(c:BYTE):LONGINT;
BEGIN
CASE c OF
Black : ConvertColor:= CLR_BLACK;
Blue : ConvertColor:= CLR_DARKBLUE;
Green : ConvertColor:= CLR_DARKGREEN;
Cyan : ConvertColor:= CLR_DARKCYAN;
Red : ConvertColor:= CLR_DARKRED;
Magenta : ConvertColor:= CLR_DARKPINK;
Brown : ConvertColor:= CLR_BROWN;
LightGray : ConvertColor:= CLR_PALEGRAY;
DarkGray : ConvertColor:= CLR_DARKGRAY;
LightBlue : ConvertColor:= CLR_BLUE;
LightGreen : ConvertColor:= CLR_GREEN;
LightCyan : ConvertColor:= CLR_CYAN;
LightRed : ConvertColor:= CLR_RED;
LightMagenta : ConvertColor:= CLR_PINK;
Yellow : ConvertColor:= CLR_YELLOW;
White : ConvertColor:= CLR_WHITE;
END; {case}
END;
PROCEDURE ClrScr;
VAR Win:TWinCrtScreenInOutClass;
Color:LONGINT;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
Color:=ConvertColor(TextAttr AND 15);
WinSetPresParam(Win.Handle,PP_FOREGROUNDCOLORINDEX,4,Color);
Color:=ConvertColor((TextAttr SHR 4) AND 15);
WinSetPresParam(Win.Handle,PP_BACKGROUNDCOLORINDEX,4,Color);
FillChar(Win.ScreenBuffer^,Win.BufferSize,32);
FillChar(Win.ColorBuffer^,Win.BufferSize,TextAttr);
Win.RedrawAll;
END;
PROCEDURE GotoXY(X,Y:BYTE);
VAR Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
Win.SetCursor(X,Y);
END;
{Define a text window}
PROCEDURE Window(X1,Y1,X2,Y2: BYTE);
VAR MWindMax:WORD;
begin
ASM
MOV AX,SYSTEM.MaxWindMax
MOV MWindMax,AX
END;
IF X1<=X2 THEN IF Y1<=Y2 THEN
BEGIN
Dec(X1);
Dec(Y1);
IF X1>=0 THEN IF Y1>=0 THEN
BEGIN
Dec(Y2);
Dec(X2);
IF X2<lo(MWindMax)+1 THEN IF Y2<Hi(MWindMax)+1 THEN
BEGIN
WindMin := X1 + WORD(Y1) SHL 8;
WindMax := X2 + WORD(Y2) SHL 8;
GotoXY(1,1);
END;
END;
END;
END;
PROCEDURE TextColor(Color:BYTE);
BEGIN
TextAttr := (TextAttr AND 240) OR Color;
END;
PROCEDURE TextBackground(Color:BYTE);
BEGIN
TextAttr := (TextAttr AND 7) OR ((Color AND 15) SHL 4);
END;
FUNCTION WhereX: Byte;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
WhereX:=Win.xPos-lo(WindMin);
END;
FUNCTION WhereY: WORD;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
WhereY:=Win.yPos-hi(WindMin);
END;
PROCEDURE ClrEol;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
WinShowCursor(Win.Handle,FALSE);
fillchar(Win.ScreenBuffer^[Win.yPos][Win.xPos],(lo(WindMax)-Win.xPos)+2,32);
fillchar(Win.ColorBuffer^[Win.yPos,Win.xPos],(lo(WindMax)-Win.xpos)+2,textattr);
Win.DrawLine(0,Win.yPos,TRUE);
WinShowCursor(Win.Handle,TRUE);
END;
PROCEDURE InsLine;
VAR t:BYTE;
Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
FOR t:=hi(WindMax)+1 DOWNTO Win.yPos+1 DO
BEGIN
move(Win.ScreenBuffer^[t-1][lo(WindMin)],
Win.ScreenBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
move(Win.ColorBuffer^[t-1][lo(WindMin)],
Win.ColorBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
END;
fillchar(Win.ScreenBuffer^[Win.yPos][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,32);
fillchar(Win.ColorBuffer^[Win.yPos][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,TextAttr);
Win.RedrawAll;
END;
PROCEDURE DelLine;
VAR t:BYTE;
Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
FOR t:=Win.yPos TO hi(WindMax) DO
BEGIN
move(Win.ScreenBuffer^[t+1][lo(WindMin)],
Win.ScreenBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
move(Win.ColorBuffer^[t+1][lo(WindMin)],
Win.ColorBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
END;
fillchar(Win.ScreenBuffer^[hi(WindMax)+1][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,32);
fillchar(Win.ColorBuffer^[hi(WindMax)+1][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,TextAttr);
Win.RedrawAll;
END;
PROCEDURE LowVideo;
BEGIN
TextAttr := TextAttr AND $F7;
END;
PROCEDURE NormVideo;
BEGIN
TextAttr := NormAttr;
END;
PROCEDURE HighVideo;
BEGIN
TextAttr := TextAttr OR $08;
END;
CONST CrtKeyCount:BYTE=0;
VAR
CrtKeyBuffer:ARRAY[0..40] OF BYTE;
FUNCTION KeyPressed: BOOLEAN;
VAR _qmsg:QMSG;
Win:TWinCrtScreenInOutClass;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
IF CrtKeyCount=0 THEN
BEGIN
IF WinPeekMsg(AppHandle,_qmsg,0,0,0,PM_NOREMOVE) THEN
BEGIN
IF not WinGetMsg(AppHandle,_qmsg,0,0,0) THEN Halt; {WM_QUIT}
WinDispatchMsg(AppHandle,_qmsg);
END;
END;
IF CrtKeyCount>0 THEN KeyPressed:=TRUE
ELSE KeyPressed:=FALSE;
DosSleep(10);
END;
FUNCTION ReadKey: CHAR;
VAR t:BYTE;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
REPEAT
Delay(20);
UNTIL KeyPressed;
ReadKey:=CHAR(CrtKeyBuffer[0]);
Dec(CrtKeyCount);
FOR t:=0 to CrtKeyCount do CrtKeyBuffer[t]:=CrtKeybuffer[t+1];
END;
PROCEDURE TextMode(Mode: Integer);
BEGIN
END;
PROCEDURE Delay(ms:LONGWORD);
VAR Queue: QMSG; { Message-Queue }
Win:TWinCrtScreenInOutClass;
THandle: HTIMER;
tib:PTIB;
pib:PPIB;
BEGIN
IF ApplicationType<>1 THEN WinCrtError;
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
DosGetInfoBlocks(tib,pib);
IF ((tib<>NIL)AND(tib^.tib_ptib2<>NIL)) THEN
THandle:=tib^.tib_ptib2^.tib2_ultid
ELSE raise EProcessTerm.Create('Can''t retrieve thread-id');
THandle:=(THandle)MOD(TID_DELAY_END-TID_DELAY_START);
THandle:=WinStartTimer(AppHandle,Win.Handle,TID_DELAY_START+THandle,ms);
IF THandle=0 THEN raise EProcessTerm.Create('No more timers');
WHILE WinGetMsg(AppHandle,Queue,0,0,0) DO
BEGIN
If LO(Queue.mp1) = THandle THEN Break;
WinDispatchMsg(AppHandle,Queue);
END;
If not WinStopTimer(AppHandle,Win.Handle,THandle) then writeln('Error');
(*
ASM
PUSHL $ms
MOV AL,1
CALLDLL DosCalls,229 //DosSleep
ADD ESP,4
END;
*)
END;
{Sound/NoSound are not implemented, they are replaced by beep}
PROCEDURE Beep(Freq,duration:LONGWORD);
BEGIN
ASM
PUSH DWORD PTR duration
PUSH DWORD PTR freq
MOV AL,2
CALLDLL DOSCALLS,286 //DosBeep
ADD ESP,8
END;
END;
PROCEDURE TWinCrtScreenInOutClass.WriteStr(CONST s:STRING);
VAR
ps:^STRING;
by,by1:BYTE;
LABEL l;
BEGIN
IF Handle=0 THEN CreateWindow;
WinShowCursor(Handle,FALSE);
ps:=@s;
IF length(ps^)>(Lo(WindMax)-Lo(WindMin)-WhereX)+1 THEN
BEGIN
by:=(Lo(WindMax)-Lo(WindMin)-WhereX)+2;
by1:=length(s)-by;
l:
move(ps^[1],ScreenBuffer^[yPos][xPos],by);
fillchar(ColorBuffer^[yPos,xPos],by,textattr);
DrawLine(0,yPos,TRUE);
inc(ps,by);
WriteLF;
WinShowCursor(Handle,FALSE);
IF by1>by THEN
BEGIN
by:=(Lo(WindMax)-Lo(WindMin)-WhereX)+2;
dec(by1,by);
goto l;
END;
move(ps^[1],ScreenBuffer^[yPos][xPos],by1);
fillchar(ColorBuffer^[yPos,xPos],by1,textattr);
DrawLine(0,yPos,TRUE);
WinShowCursor(Handle,TRUE);
GotoXY(WhereX+by1,WhereY);
exit;
END;
move(ps^[1],ScreenBuffer^[yPos][xPos],length(ps^));
fillchar(ColorBuffer^[yPos,xPos],length(ps^),textattr);
DrawLine(0,yPos,TRUE);
WinShowCursor(Handle,TRUE);
GotoXY(WhereX+length(s),WhereY);
END;
PROCEDURE TWinCrtScreenInOutClass.WriteCStr(CONST s:CSTRING);
VAR s1:STRING;
BEGIN
IF Handle=0 THEN CreateWindow;
s1:=s;
WriteStr(s1);
END;
PROCEDURE TWinCrtScreenInOutClass.WriteLF;
VAR t,Start:BYTE;
BEGIN
IF Handle=0 THEN CreateWindow;
IF ypos>hi(WindMax) THEN
BEGIN
Start:=hi(WindMin)+1;
FOR t:=Start TO hi(WindMax) DO
BEGIN
Move(ScreenBuffer^[t+1,lo(WindMin)],
ScreenBuffer^[t,lo(WindMin)],(lo(WindMax)-lo(WindMin))+2);
Move(ColorBuffer^[t+1,lo(WindMin)],
ColorBuffer^[t,lo(WindMin)],(lo(WindMax)-lo(WindMin))+2);
END;
FillChar(ScreenBuffer^[hi(WindMax)+1,lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2,32);
FillChar(ColorBuffer^[hi(WindMax)+1,lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2,TextAttr);
GotoXY(1,WhereY);
RedrawAll;
END
ELSE GotoXY(1,WhereY+1);
END;
PROCEDURE TWinCrtScreenInOutClass.ReadLF(VAR s:STRING);
VAR ch:CHAR;
BEGIN
IF Handle=0 THEN CreateWindow;
ch:=Readkey;
s:='';
WHILE ch<>#13 DO
BEGIN
IF ch=#0 THEN
BEGIN
IF CrtKeyCount>0 THEN dec(CrtKeyCount);
END
ELSE
BEGIN
IF ch=#8 THEN
BEGIN
IF length(s)>0 THEN
BEGIN
dec(s[0]);
IF WhereX=1 THEN GotoXY(lo(WindMax)-lo(WindMin)+1,WhereY-1)
ELSE GotoXY(WhereX-1,WhereY);
WriteStr(' ');
IF WhereX=1 THEN GotoXY(lo(WindMax)-lo(WindMin)+1,WhereY-1)
ELSE GotoXY(WhereX-1,WhereY);
END;
END
ELSE
BEGIN
IF length(s)<255 THEN s:=s+ch;
WriteStr(ch);
END;
END;
ch:=readkey;
END;
WriteLF;
END;
PROCEDURE TWinCrtScreenInOutClass.GotoXY(x,y:BYTE);
BEGIN
IF Handle=0 THEN CreateWindow;
SetCursor(x,y);
END;
PROCEDURE CreateLogFont(_HPS:HPS;CONST facename:CSTRING;hei,len,
SelAttr:LONGWORD);
VAR fat:FATTRS;
BEGIN
fat.szFaceName:=facename;
fat.usRecordLength:=sizeof(FATTRS);
fat.fsSelection:=SelAttr;
fat.lMatch:=1;
fat.idRegistry:=0;
fat.usCodePage:=0; {default}
fat.lMaxbaseLineExt:=hei;
fat.lAveCharWidth:=len;
fat.fsType:=0;
fat.fsFontUse:=0;
GpiCreateLogFont(_hps,@facename,1,fat);
GpiSetCharSet(_hps,1);
END;
FUNCTION WinCrtHandler(Win:HWND;msg,para1,para2:ULONG):ULONG;CDECL;
VAR _hps:HPS;
rc:RECTL;
Objekt:TWinCrtScreenInOutClass;
Color:LONGINT;
BEGIN
Objekt:=TWinCrtScreenInOutClass(ScreenInOut);
CASE Msg OF
WM_CLOSE:
BEGIN
Halt;
END;
WM_PAINT:
BEGIN
_hps:=WinBeginPaint(Win,0,rc);
Objekt.Redraw(_hps,rc);
WinEndPaint(_hps);
END;
WM_SETFOCUS: {EingabeFocus neu setzen}
BEGIN
IF para2=0 THEN
BEGIN //Window is loosing focus
WinDestroyCursor(Win);
END
ELSE //Window is getting focus
BEGIN
WinCreateCursor(Win,40,40,8,3,CURSOR_SOLID OR CURSOR_FLASH,NIL);
Objekt.SetCursor(Objekt.xPos,Objekt.yPos);
END;
END;
WM_ERASEBACKGROUND:
BEGIN
_hps:=HPS(para1);
rc:=PRECTL(Para2)^;
Color:=ConvertColor((TextAttr SHR 4) AND 15);
WinFillRect(_hps,rc,Color);
WinCrtHandler:=0;
END;
WM_CHAR:
BEGIN
if CrtKeyCount < 33 then
begin
IF lo(Para1) AND KC_KEYUP=KC_KEYUP THEN
BEGIN
IF lo(lo(para2))=224 THEN
BEGIN
CrtKeyBuffer[CrtKeyCount]:=0;
CrtKeyBuffer[CrtKeyCount+1]:=hi(lo(para2));
inc(CrtKeyCount,2); {RANGE ERROR?}
END
ELSE
BEGIN
CrtKeyBuffer[CrtKeyCount]:=lo(para2);
inc(CrtKeyCount);
END;
END;
end;
WinCrtHandler:=0;
END;
ELSE WinCrtHandler:=WinDefWindowProc(Win,msg,para1,para2);
END; {case}
END;
PROCEDURE TWinCrtScreenInOutClass.CreateWindow;
VAR
ClassName:CSTRING;
ClassStyle:LONGWORD;
FrameFlags:LONGWORD;
Title:CSTRING;
ScreenCX,ScreenCY:LONGWORD;
WX,WY:LONGINT;
Color:LONGINT;
BEGIN
IF Handle<>0 THEN exit;
InitPM;
Title:=ParamStr(0);
ClassName:='SP/2 WinCrt Window';
ClassStyle:=CS_SIZEREDRAW OR CS_MOVENOTIFY;
FrameFlags:=FCF_TASKLIST OR FCF_DLGBORDER OR FCF_TITLEBAR
OR FCF_SYSMENU;
WinRegisterClass(AppHandle,ClassName,@WinCrtHandler,ClassStyle,0);
FrameHandle:=WinCreateStdWindow(HWND_DESKTOP,0,FrameFlags,
ClassName,Title,
0,0,0,Handle);
ScreenCX:=WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
ScreenCY:=WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
WX:=((ScreenCX-80*8) DIV 2);
WY:=((ScreenCY-25*16) DIV 2);
Color:=ConvertColor(TextAttr AND 15);
WinSetPresParam(Handle,PP_FOREGROUNDCOLORINDEX,4,Color);
Color:=ConvertColor((TextAttr SHR 4) AND 15);
WinSetPresParam(Handle,PP_BACKGROUNDCOLORINDEX,4,Color);
WinSetWindowPos(FrameHandle,0,WX,WY,80*8,((25+2)*16)-4,
SWP_SHOW OR SWP_SIZE OR SWP_MOVE OR SWP_ACTIVATE OR
SWP_FOCUSACTIVATE);
ClrScr;
END;
PROCEDURE InitWinCrt;
VAR ScreenInOutPM:TWinCrtScreenInOutClass;
BEGIN
ScreenInOutPM.Create;
ScreenInOut:=TScreenInOutClass(ScreenInOutPM);
END;
PROCEDURE TWinCrtScreenInOutClass.Redraw(_hps:HPS;rc:RECTL);
VAR rc1:RECTL;
loy,hiy:WORD;
t:BYTE;
BEGIN
CreateLogFont(_hps,'System VIO',16,8,0);
WinQueryWindowRect(Handle,rc1);
loy:=rc1.yTop-rc.yTop;
loy:=loy DIV 16;
hiy:=rc1.yTop-rc.yBottom;
hiy:=hiy DIV 16;
IF loy=0 THEN loy:=1;
WinShowCursor(Handle,FALSE);
FOR t:=loy-1 TO hiy+1 DO DrawLine(_hps,t,false);
WinShowCursor(Handle,TRUE);
END;
PROCEDURE TWinCrtScreenInOutClass.DrawLine(_hps:HPS;y:BYTE;createfont:BOOLEAN);
VAR
PSCreated:BOOLEAN;
pt:POINTL;
rc,rc1:RECTL;
Actual,Start:LONGWORD;
xpos:LONGWORD;
Len:LONGWORD;
Color:LONGINT;
BEGIN
WinQueryWindowRect(Handle,rc);
IF _hps=0 THEN
BEGIN
PSCreated:=TRUE;
_hps:=WinGetPS(Handle);
END
ELSE PSCreated:=FALSE;
IF CreateFont THEN CreateLogFont(_hps,'System VIO',16,8,0);
IF ((y=0)OR(y>MaxY)) THEN exit;
IF y=MaxY THEN
BEGIN
Color:=ConvertColor((TextAttr SHR 4) AND 15);
rc1.xleft:=0;
rc1.xright:=MaxX*8;
rc1.yBottom:=0;
rc1.yTop:=10;
WinFillRect(_hps,rc1,Color);
END;
pt.y:=(rc.yTop-(y*16))+4;
Actual:=1;
xPos:=0;
GpiSetBackMix(_hps,BM_OVERPAINT);
Color:=ColorBuffer^[y][Actual];
Len:=0;
Start:=1;
WHILE Actual<=MaxX DO
BEGIN
IF ((Color<>ColorBuffer^[y][Actual])OR(Actual=MaxX)) THEN
BEGIN
GpiSetColor(_hps,ConvertColor(Color AND 15));
GpiSetBackColor(_hps,ConvertColor((Color SHR 4) AND 15));
pt.x:=xpos;
GpiCharStringAt(_hps,pt,len,ScreenBuffer^[y][Start]);
Color:=ColorBuffer^[y][Actual];
inc(xpos,len*8);
Len:=0;
Start:=Actual;
IF Actual=MaxX THEN inc(Actual); //terminate
END
ELSE
BEGIN
inc(Len);
inc(Actual);
END;
END;
IF PSCreated THEN WinReleasePS(_hps);
END;
PROCEDURE TWinCrtScreenInOutClass.RedrawAll;
VAR t:BYTE;
_hps:HPS;
BEGIN
WinShowCursor(Handle,FALSE);
_hps:=WinGetPS(Handle);
CreateLogFont(_hps,'System VIO',16,8,0);
FOR t:=1 TO Hi(WindMax)+1 DO DrawLine(_hps,t,false);
WinReleasePS(_hps);
WinShowCursor(Handle,TRUE);
END;
PROCEDURE TWinCrtScreenInOutClass.SetCursor(X,Y:BYTE);
VAR tx,ty:LONGWORD;
rc:RECTL;
BEGIN
IF Handle=0 THEN CreateWindow;
inc(X,lo(WindMin));
inc(Y,hi(WindMin));
IF X>lo(WindMax)+1 THEN X:=1;
IF Y>hi(WindMax)+1 THEN Y:=hi(WindMax)+1;
IF X<lo(WindMin)+1 THEN X:=lo(WindMin)+1;
IF Y<hi(WindMin)+1 THEN Y:=hi(WindMin)+1;
xPos:=X;
yPos:=Y;
WinQueryWindowRect(Handle,rc);
tx:=(xPos-1)*8;
ty:=rc.yTop-yPos*16;
WinCreateCursor(Handle,tx,ty-2,8,3,CURSOR_SETPOS OR CURSOR_FLASH,NIL);
WinShowCursor(Handle,TRUE);
END;
PROCEDURE TWinCrtScreenInOutClass.SetupScreenBuffer(x,y:WORD);
BEGIN
TextAttr:=(White SHL 4)+Black; {Black on White}
NormAttr:=TextAttr;
CheckBreak:=FALSE;
xPos:=1;
yPos:=1;
IF BufferSize<>0 THEN
BEGIN
FreeMem(ScreenBuffer,BufferSize);
FreeMem(ColorBuffer,BufferSize);
END;
BufferSize:=(x+1)*(y+1);
GetMem(ScreenBuffer,BufferSize);
GetMem(ColorBuffer,BufferSize);
FillChar(ScreenBuffer^,x*y,32); {Space}
FillChar(ColorBuffer^,x*y,TextAttr); {LightGray on black}
WindMin:=0;
WindMax:=x+y SHL 8;
MaxX:=x;
MaxY:=y;
END;
CONSTRUCTOR TWinCrtScreenInOutClass.Create;
BEGIN
Inherited Create;
ScreenInOut:=TScreenInOutClass(SELF);
LastMode:=CO80;
WindMin:=0;
WindMax:=80+WORD(25) SHL 8;
MaxX:=80;
MaxY:=25;
ScreenBuffer:=NIL;
ColorBuffer:=NIL;
Handle:=0;
BufferSize:=0;
SetupScreenBuffer(lo(WindMax),hi(WindMax));
SetCursor(xpos,yPos);
END;
BEGIN
IF ApplicationType=1 THEN {nur für PM Modus}
BEGIN
ScreenInOut.Destroy; {delete old}
InitWinCrt;
END;
END.
{$ENDIF}
{$IFDEF WIN32}
CONST
{ CRT modes }
BW40 = 0; { 40x25 B/W on Color Adapter }
CO40 = 1; { 40x25 Color on Color Adapter }
BW80 = 2; { 80x25 B/W on Color Adapter }
CO80 = 3; { 80x25 Color on Color Adapter }
Mono = 7; { 80x25 on Monochrome Adapter }
Font8x8 = 256; { Add-in for 8x8 font }
VAR
WindMin: WORD; { Window upper left coordinates }
WindMax: WORD; { Window lower right coordinates }
LastMode: Word; { Current text mode }
TextAttr: BYTE; { Current text attribute }
CONST
{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;
VAR
CheckBreak: BOOLEAN; { Ctrl-Break check }
CheckEOF: BOOLEAN; { Ctrl-Z for EOF? }
NormAttr:WORD; { Normal text attribute}
PROCEDURE ClrScr;
PROCEDURE GotoXY(X,Y:BYTE);
PROCEDURE Window(X1,Y1,X2,Y2:BYTE);
PROCEDURE TextColor(Color:BYTE);
PROCEDURE TextBackground(Color:BYTE);
FUNCTION WhereX: Byte;
FUNCTION WhereY: WORD;
PROCEDURE ClrEol;
PROCEDURE InsLine;
PROCEDURE DelLine;
PROCEDURE LowVideo;
PROCEDURE NormVideo;
PROCEDURE HighVideo;
FUNCTION KeyPressed: BOOLEAN;
FUNCTION ReadKey: CHAR;
PROCEDURE TextMode(Mode: Integer);
PROCEDURE Delay(ms:LONGWORD);
{Sound/NoSound are not implemented, they are replaced by beep}
//PROCEDURE Beep(Freq,duration:LONGWORD);
IMPLEMENTATION
USES WinUser,WinGdi,WinBase,WinDef;
TYPE
PScreenBuffer=^TScreenBuffer;
TScreenBuffer=ARRAY[1..50,1..80] OF CHAR;
PColorBuffer=^TColorBuffer;
TColorBuffer=ARRAY[1..51,1..81] OF BYTE;
TYPE
TWinCrtScreenInOutClass=CLASS
PRIVATE
ScreenBuffer:PScreenBuffer;
ColorBuffer:PColorBuffer;
BufferSize:WORD;
xPos,yPos:WORD;
MaxX,MaxY:WORD;
Handle,FrameHandle:HWND;
cxChar,cyChar:LONGINT;
PUBLIC
PROCEDURE WriteStr(CONST s:STRING);VIRTUAL;
PROCEDURE WriteCStr(CONST s:CSTRING);VIRTUAL;
PROCEDURE WriteLF;VIRTUAL;
PROCEDURE ReadLF(VAR s:STRING);VIRTUAL;
PROCEDURE GotoXY(x,y:BYTE);VIRTUAL;
CONSTRUCTOR Create;
PROCEDURE SetupScreenBuffer(x,y:WORD);
PROCEDURE CreateWindow;
PROCEDURE RedrawAll;
PROCEDURE Redraw(_hps:HDC;rc:RECTL);
PROCEDURE DrawLine(_hps:HDC;y:BYTE;createfont:BOOLEAN);
PROCEDURE SetCursor(x,y:BYTE);
END;
FUNCTION ConvertColor(c:BYTE):LONGINT;
BEGIN
CASE c OF
Black : ConvertColor:= $00000000;
Blue : ConvertColor:= $00FF0000;
Green : ConvertColor:= $00008000;
Cyan : ConvertColor:= $00FFFF00;
Red : ConvertColor:= $000000FF;
Magenta : ConvertColor:= $00800080;
Brown : ConvertColor:= $00FF00FF;
LightGray : ConvertColor:= $00C0C0C0;
DarkGray : ConvertColor:= $00808080;
LightBlue : ConvertColor:= $00FF0000;
LightGreen : ConvertColor:= $00008000;
LightCyan : ConvertColor:= $00FFFF00;
LightRed : ConvertColor:= $000000FF;
LightMagenta : ConvertColor:= $00800080;
Yellow : ConvertColor:= $0000FFFF;
White : ConvertColor:= $00FFFFFF;
END; {case}
END;
PROCEDURE ClrScr;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
FillChar(Win.ScreenBuffer^,Win.BufferSize,32);
FillChar(Win.ColorBuffer^,Win.BufferSize,TextAttr);
Win.RedrawAll;
END;
PROCEDURE GotoXY(X,Y:BYTE);
VAR Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
Win.SetCursor(X,Y);
END;
PROCEDURE Window(X1,Y1,X2,Y2:BYTE);
BEGIN
IF X1<=X2 THEN IF Y1<=Y2 THEN
BEGIN
Dec(X1);
Dec(Y1);
IF X1>=0 THEN IF Y1>=0 THEN
BEGIN
Dec(Y2);
Dec(X2);
IF X2<lo(WindMax)+1 THEN IF Y2<Hi(WindMax)+1 THEN
BEGIN
WindMin := X1 + WORD(Y1) SHL 8;
WindMax := X2 + WORD(Y2) SHL 8;
GotoXY(1,1);
END;
END;
END;
END;
PROCEDURE TextColor(Color:BYTE);
BEGIN
TextAttr := (TextAttr AND 240) OR Color;
END;
PROCEDURE TextBackground(Color:BYTE);
BEGIN
TextAttr := (TextAttr AND 7) OR ((Color AND 15) SHL 4);
END;
FUNCTION WhereX: Byte;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
WhereX:=Win.xPos-lo(WindMin);
END;
FUNCTION WhereY: WORD;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
WhereY:=Win.yPos-hi(WindMin);
END;
PROCEDURE ClrEol;
VAR Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
HideCaret(Win.Handle);
fillchar(Win.ScreenBuffer^[Win.yPos][Win.xPos],(lo(WindMax)-Win.xPos)+2,32);
fillchar(Win.ColorBuffer^[Win.yPos,Win.xPos],(lo(WindMax)-Win.xpos)+2,textattr);
Win.DrawLine(0,Win.yPos,TRUE);
ShowCaret(Win.Handle);
END;
PROCEDURE InsLine;
VAR t:BYTE;
Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
FOR t:=hi(WindMax)+1 DOWNTO Win.yPos+1 DO
BEGIN
move(Win.ScreenBuffer^[t-1][lo(WindMin)],
Win.ScreenBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
move(Win.ColorBuffer^[t-1][lo(WindMin)],
Win.ColorBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
END;
fillchar(Win.ScreenBuffer^[Win.yPos][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,32);
fillchar(Win.ColorBuffer^[Win.yPos][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,TextAttr);
Win.RedrawAll;
END;
PROCEDURE DelLine;
VAR t:BYTE;
Win:TWinCrtScreenInOutClass;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
FOR t:=Win.yPos TO hi(WindMax) DO
BEGIN
move(Win.ScreenBuffer^[t+1][lo(WindMin)],
Win.ScreenBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
move(Win.ColorBuffer^[t+1][lo(WindMin)],
Win.ColorBuffer^[t][lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2);
END;
fillchar(Win.ScreenBuffer^[hi(WindMax)+1][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,32);
fillchar(Win.ColorBuffer^[hi(WindMax)+1][lo(WindMin)],(lo(WindMax)-lo(WindMin))+2,TextAttr);
Win.RedrawAll;
END;
PROCEDURE LowVideo;
BEGIN
TextAttr := TextAttr AND $F7;
END;
PROCEDURE NormVideo;
BEGIN
TextAttr := NormAttr;
END;
PROCEDURE HighVideo;
BEGIN
TextAttr := TextAttr OR $08;
END;
CONST CrtKeyCount:BYTE=0;
VAR
CrtKeyBuffer:ARRAY[0..40] OF BYTE;
FUNCTION KeyPressed: BOOLEAN;
VAR
Win:TWinCrtScreenInOutClass;
aMsg:MSG;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
IF Win.Handle=0 THEN Win.CreateWindow;
IF CrtKeyCount=0 THEN
BEGIN
IF PeekMessage(aMsg,0,0,0,PM_NOREMOVE) THEN
BEGIN
IF not GetMessage (amsg, 0, 0, 0) THEN Halt; {WM_QUIT}
TranslateMessage(amsg);
DispatchMessage (amsg);
END;
END;
IF CrtKeyCount>0 THEN KeyPressed:=TRUE
ELSE KeyPressed:=FALSE;
END;
FUNCTION ReadKey: CHAR;
VAR t:BYTE;
BEGIN
REPEAT UNTIL KeyPressed;
ReadKey:=CHAR(CrtKeyBuffer[0]);
Dec(CrtKeyCount);
FOR t:=0 to CrtKeyCount do CrtKeyBuffer[t]:=CrtKeybuffer[t+1];
END;
PROCEDURE TextMode(Mode: Integer);
BEGIN
END;
PROCEDURE Delay(ms:LONGWORD);
BEGIN
Sleep(ms);
END;
{Sound/NoSound are not implemented, they are replaced by beep}
{
PROCEDURE Beep(Freq,duration:LONGWORD);
BEGIN
SYSTEM.Beep(Freq,Duration);
END;
}
PROCEDURE TWinCrtScreenInOutClass.WriteStr(CONST s:STRING);
VAR
ps:^STRING;
by,by1:BYTE;
LABEL l;
BEGIN
IF Handle=0 THEN CreateWindow;
HideCaret(Handle);
ps:=@s;
IF length(ps^)>(Lo(WindMax)-Lo(WindMin)-WhereX)+1 THEN
BEGIN
by:=(Lo(WindMax)-Lo(WindMin)-WhereX)+2;
by1:=length(s)-by;
l:
move(ps^[1],ScreenBuffer^[yPos][xPos],by);
fillchar(ColorBuffer^[yPos,xPos],by,textattr);
DrawLine(0,yPos,TRUE);
inc(ps,by);
WriteLF;
HideCaret(Handle);
IF by1>by THEN
BEGIN
by:=(Lo(WindMax)-Lo(WindMin)-WhereX)+2;
dec(by1,by);
goto l;
END;
move(ps^[1],ScreenBuffer^[yPos][xPos],by1);
fillchar(ColorBuffer^[yPos,xPos],by1,textattr);
DrawLine(0,yPos,TRUE);
ShowCaret(HANDLE);
GotoXY(WhereX+by1,WhereY);
exit;
END;
move(ps^[1],ScreenBuffer^[yPos][xPos],length(ps^));
fillchar(ColorBuffer^[yPos,xPos],length(ps^),textattr);
DrawLine(0,yPos,TRUE);
ShowCaret(HANDLE);
GotoXY(WhereX+length(s),WhereY);
END;
PROCEDURE TWinCrtScreenInOutClass.WriteCStr(CONST s:CSTRING);
VAR s1:STRING;
BEGIN
IF Handle=0 THEN CreateWindow;
s1:=s;
WriteStr(s1);
END;
PROCEDURE TWinCrtScreenInOutClass.WriteLF;
VAR t,Start:BYTE;
BEGIN
IF Handle=0 THEN CreateWindow;
IF ypos>hi(WindMax)-1 THEN
BEGIN
Start:=hi(WindMin)+1;
FOR t:=Start TO hi(WindMax) DO
BEGIN
Move(ScreenBuffer^[t+1,lo(WindMin)],
ScreenBuffer^[t,lo(WindMin)],(lo(WindMax)-lo(WindMin))+2);
Move(ColorBuffer^[t+1,lo(WindMin)],
ColorBuffer^[t,lo(WindMin)],(lo(WindMax)-lo(WindMin))+2);
END;
FillChar(ScreenBuffer^[hi(WindMax)+1,lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2,32);
FillChar(ColorBuffer^[hi(WindMax)+1,lo(WindMin)],
(lo(WindMax)-lo(WindMin))+2,TextAttr);
GotoXY(1,WhereY);
RedrawAll;
END
ELSE GotoXY(1,WhereY+1);
END;
PROCEDURE TWinCrtScreenInOutClass.ReadLF(VAR s:STRING);
VAR ch:CHAR;
BEGIN
IF Handle=0 THEN CreateWindow;
ch:=Readkey;
s:='';
WHILE ch<>#13 DO
BEGIN
IF ch=#0 THEN
BEGIN
IF CrtKeyCount>0 THEN dec(CrtKeyCount);
END
ELSE
BEGIN
IF ch=#8 THEN
BEGIN
IF length(s)>0 THEN
BEGIN
dec(s[0]);
IF WhereX=1 THEN GotoXY(lo(WindMax)-lo(WindMin)+1,WhereY-1)
ELSE GotoXY(WhereX-1,WhereY);
WriteStr(' ');
IF WhereX=1 THEN GotoXY(lo(WindMax)-lo(WindMin)+1,WhereY-1)
ELSE GotoXY(WhereX-1,WhereY);
END;
END
ELSE
BEGIN
IF length(s)<255 THEN s:=s+ch;
WriteStr(ch);
END;
END;
ch:=readkey;
END;
WriteLF;
END;
PROCEDURE TWinCrtScreenInOutClass.GotoXY(x,y:BYTE);
BEGIN
IF Handle=0 THEN CreateWindow;
SetCursor(x,y);
END;
FUNCTION CreateLogFont(_HPS:HDC):HFONT;
BEGIN
CreateLogFont:=SelectObject(_HPS,GetStockObject(SYSTEM_FIXED_FONT));
END;
FUNCTION WndProc(ahwnd:HWND;amsg:ULONG;awParam:WPARAM;alParam:LPARAM):LRESULT;APIENTRY;
VAR Win:TWinCrtScreenInOutClass;
rc:RECT;
ScanCode:BYTE;
BEGIN
Win:=TWinCrtScreenInOutClass(ScreenInOut);
CASE amsg OF
WM_DESTROY:
BEGIN
PostQuitMessage(0);
WndProc:=0;
END;
WM_SETFOCUS: //Window is getting focus
BEGIN
CreateCaret(Win.Handle,0,8,3);
Win.SetCursor(Win.xPos,Win.yPos);
WndProc:=0;
END;
WM_KEYUP:
BEGIN
IF CrtKeyCount<32 THEN
BEGIN
CASE awParam OF
VK_CLEAR,VK_PAUSE,VK_CAPITAL,VK_END,VK_HOME,
VK_LEFT,VK_UP,VK_RIGHT,VK_DOWN,VK_INSERT,VK_DELETE,
VK_PRIOR,VK_NEXT,VK_F1,VK_F2,VK_F3,VK_F4,VK_F5,
VK_F6,VK_F7,VK_F8,VK_F9,VK_F10,VK_F11,VK_F12,VK_F13,
VK_F14,VK_F15,VK_F16,VK_F17,VK_F18,VK_F19,VK_F20,
VK_F21,VK_F22,VK_F23,VK_F24:
BEGIN
ScanCode:=alParam SHR 16;
CrtKeyBuffer[CrtKeyCount]:=0;
CrtKeyBuffer[CrtKeyCount+1]:=ScanCode;
inc(CrtKeyCount,2);
END;
END; {case}
END;
WndProc:=0;
END;
WM_CHAR:
BEGIN
if CrtKeyCount < 33 then
begin
CrtKeyBuffer[CrtKeyCount]:=awParam;
inc(CrtKeyCount);
end;
WndProc:=0;
END;
WM_KILLFOCUS: //Window is loosing focus
BEGIN
DestroyCaret;
WndProc:=0;
END;
ELSE WndProc:=DefWindowProc(ahwnd,amsg,awParam,alParam);
END; {case}
END;
FUNCTION WinCrtHandler(Win:HWND;amsg:ULONG;awParam:WPARAM;alParam:LPARAM):LRESULT;APIENTRY;
VAR _hps:HDC;
rc:RECTL;
Objekt:TWinCrtScreenInOutClass;
Color:LONGINT;
ps:PAINTSTRUCT;
ahFont:HFONT;
tm:TEXTMETRIC;
BEGIN
Objekt:=TWinCrtScreenInOutClass(ScreenInOut);
CASE aMsg OF
WM_CREATE:
BEGIN
_hps:=GetDC(Win);
ahFont:=CreateLogFont(_hps);
GetTextMetrics(_hps,tm);
Objekt.cxChar:=tm.tmAveCharWidth;
Objekt.cyChar:=tm.tmHeight+tm.tmExternalLeading;
DeleteObject(SelectObject(_hps,ahFont));
ReleaseDC(Win,_hps);
WinCrtHandler:=0;
END;
WM_PAINT:
BEGIN
IF GetUpdateRect(Win,NIL,FALSE) THEN
BEGIN
_hps:=BeginPaint(Win,ps);
GetUpdateRect(Win,rc,FALSE);
Objekt.Redraw(_hps,rc);
EndPaint(Win,ps);
END;
WinCrtHandler:=0;
END;
WM_ERASEBKGND:
BEGIN
WinCrtHandler:=1;
END;
ELSE WinCrtHandler:=DefWindowProc(Win,amsg,awParam,alParam);
END; {case}
END;
PROCEDURE TWinCrtScreenInOutClass.CreateWindow;
VAR
ClassName,ChildClassName:CSTRING;
ClassStyle:LONGWORD;
FrameFlags:LONGWORD;
Title:CSTRING;
ScreenCX,ScreenCY:LONGWORD;
WX,WY:LONGINT;
Color:LONGINT;
windowclass:WNDCLASS;
rc,rc1:RECT;
BEGIN
IF Handle<>0 THEN exit;
ClassName:='SP/2 WinCrt Window';
windowclass.style := CS_HREDRAW OR CS_VREDRAW OR CS_SAVEBITS;
windowclass.lpfnWndProc := @WndProc;
windowclass.cbClsExtra := 0;
windowclass.cbWndExtra := 0;
windowclass.hInstance := DllModule;
windowclass.hIcon := 0;
windowclass.hCursor := LoadCursor(0,IDC_ARROW);
windowclass.hbrBackground := COLOR_APPWORKSPACE+1;
windowclass.lpszMenuName := NIL;
windowclass.lpszClassName := @ClassName;
RegisterClass(windowclass);
ChildClassName:='SP/2 WinCrt Child Window';
windowclass.lpfnWndProc := @WinCrtHandler;
windowclass.hbrBackground := COLOR_WINDOW+1;
windowclass.lpszMenuName := NIL;
windowclass.lpszClassName := @ChildClassName;
RegisterClass(windowclass);
Title:=ParamStr(0);
ScreenCX:=GetSystemMetrics(SM_CXSCREEN);
ScreenCY:=GetSystemMetrics(SM_CYSCREEN);
WX:=((ScreenCX-80*8) DIV 2);
WY:=((ScreenCY-25*12) DIV 2);
FrameHandle:= WinUser.CreateWindow (ClassName, Title,
WS_OVERLAPPED OR WS_CAPTION OR WS_SYSMENU OR
WS_CLIPCHILDREN OR WS_DLGFRAME,
WX, WY,80*8,(25)*16,
0, 0, DllModule, NIL);
GetClientRect(FrameHandle,rc);
Handle:= WinUser.CreateWindow (ChildClassName,ChildClassName,
WS_CHILD OR WS_CLIPSIBLINGS OR WS_VISIBLE,
0,0,rc.Right-rc.Left,rc.Bottom-rc.Top,
FrameHandle,0, DllModule , NIL);
ShowWindow (FrameHandle,10);
ShowWindow (Handle,10);
UpdateWindow(FrameHandle);
UpdateWindow(Handle);
ClrScr;
END;
PROCEDURE InitWinCrt;
VAR ScreenInOutPM:TWinCrtScreenInOutClass;
BEGIN
ScreenInOutPM.Create;
ScreenInOut:=TScreenInOutClass(ScreenInOutPM);
END;
PROCEDURE TWinCrtScreenInOutClass.Redraw(_hps:HDC;rc:RECT);
VAR
loy,hiy:WORD;
t:BYTE;
ahFont:HFONT;
BEGIN
ahFont:=CreateLogFont(_hps);
loy:=rc.Bottom;
loy:=1{loy DIV cyChar};
hiy:=rc.Top;
hiy:=25{hiy DIV cyChar};
IF loy=0 THEN loy:=1;
HideCaret(Handle);
FOR t:=loy-1 TO hiy+1 DO DrawLine(_hps,t,false);
DeleteObject(SelectObject(_hps,ahFont));
ShowCaret(Handle);
END;
PROCEDURE TWinCrtScreenInOutClass.DrawLine(_hps:HDC;y:BYTE;createfont:BOOLEAN);
VAR rc:RECT;
PSCreated:BOOLEAN;
Color:LONGINT;
pt:POINT;
Actual,Start,xPos:LONGINT;
Len:LONGINT;
ahFont:HFONT;
ahBrush:HBRUSH;
s:STRING;
c:CSTRING;
BEGIN
IF ((y=0)OR(y>MaxY)) THEN exit;
GetWindowRect(Handle,rc);
IF _hps=0 THEN
BEGIN
PSCreated:=TRUE;
_hps:=GetDC(Handle);
END
ELSE PSCreated:=FALSE;
IF CreateFont THEN ahFont:=CreateLogFont(_hps);
IF y=MaxY THEN
BEGIN
Color:=ConvertColor((TextAttr SHR 4) AND 15);
ahBrush:=CreateSolidBrush(Color);
SelectObject(_hps,ahBrush);
SetBkMode(_hps,OPAQUE);
Rectangle(_hps,0,(rc.Bottom-rc.Top)-12,MaxX*cxChar,
rc.Bottom-rc.Top);
DeleteObject(SelectObject(_hps,ahBrush));
END;
pt.y:=(y-1)*cyChar;
Actual:=1;
xPos:=0;
SetBkMode(_hps,OPAQUE);
Color:=ColorBuffer^[y][Actual];
Len:=0;
Start:=1;
WHILE Actual<=MaxX DO
BEGIN
IF ((Color<>ColorBuffer^[y][Actual])OR(Actual=MaxX)) THEN
BEGIN
SetTextColor(_hps,ConvertColor(Color AND 15));
SetBkColor(_hps,ConvertColor((Color SHR 4) AND 15));
pt.x:=xpos;
TextOut(_hps,pt.x,pt.y,CSTRING(ScreenBuffer^[y][Start]),len+1);
SetTextAlign(_hps,TA_LEFT OR TA_TOP);
Color:=ColorBuffer^[y][Actual];
inc(xpos,len*cxChar);
Len:=0;
Start:=Actual;
IF Actual=MaxX THEN inc(Actual); //terminate
END
ELSE
BEGIN
inc(Len);
inc(Actual);
END;
END;
IF PSCreated THEN ReleaseDC(Handle,_hps);
IF CreateFont THEN DeleteObject(SelectObject(_hps,ahFont));
END;
PROCEDURE TWinCrtScreenInOutClass.RedrawAll;
VAR t:BYTE;
_hps:HDC;
ahfont:HFONT;
BEGIN
HideCaret(Handle);
_hps:=GetDC(Handle);
ahFont:=CreateLogFont(_hps);
FOR t:=1 TO Hi(WindMax)+1 DO DrawLine(_hps,t,false);
DeleteObject(SelectObject(_hps,ahFont));
ReleaseDC(Handle,_hps);
ShowCaret(Handle);
END;
PROCEDURE TWinCrtScreenInOutClass.SetCursor(X,Y:BYTE);
VAR tx,ty:LONGWORD;
rc:RECT;
BEGIN
IF Handle=0 THEN CreateWindow;
inc(X,lo(WindMin));
inc(Y,hi(WindMin));
IF X>lo(WindMax)+1 THEN X:=1;
IF Y>hi(WindMax)+1 THEN Y:=hi(WindMax)+1;
IF X<lo(WindMin)+1 THEN X:=lo(WindMin)+1;
IF Y<hi(WindMin)+1 THEN Y:=hi(WindMin)+1;
xPos:=X;
yPos:=Y;
GetWindowRect(Handle,rc);
tx:=(xPos-1)*cxChar;
ty:=yPos*cyChar;
CreateCaret(Handle,0,8,3);
SetCaretPos(tx,ty-2);
ShowCaret(Handle);
END;
PROCEDURE TWinCrtScreenInOutClass.SetupScreenBuffer(x,y:WORD);
BEGIN
TextAttr:=(White SHL 4)+Black; {Black on White}
NormAttr:=TextAttr;
CheckBreak:=FALSE;
xPos:=1;
yPos:=1;
IF BufferSize<>0 THEN
BEGIN
FreeMem(ScreenBuffer,BufferSize);
FreeMem(ColorBuffer,BufferSize);
END;
BufferSize:=(x+1)*(y+1);
GetMem(ScreenBuffer,BufferSize);
GetMem(ColorBuffer,BufferSize);
FillChar(ScreenBuffer^,x*y,32); {Space}
FillChar(ColorBuffer^,x*y,TextAttr); {LightGray on black}
WindMin:=0;
WindMax:=x+y SHL 8;
MaxX:=x;
MaxY:=y;
END;
CONSTRUCTOR TWinCrtScreenInOutClass.Create;
BEGIN
Inherited Create;
ScreenInOut:=TScreenInOutClass(SELF);
LastMode:=CO80;
WindMin:=0;
WindMax:=80+WORD(25) SHL 8;
MaxX:=80;
MaxY:=25;
ScreenBuffer:=NIL;
ColorBuffer:=NIL;
Handle:=0;
BufferSize:=0;
cxChar:=8;
cyChar:=12;
SetupScreenBuffer(lo(WindMax),hi(WindMax));
SetCursor(xpos,yPos);
END;
BEGIN
ScreenInOut.Destroy; {delete old}
InitWinCrt;
END.
{$ENDIF}