{$IfDef VER130} {$Define NEW_STYLES} {$EndIf} {$IfDef VER140} {$Define NEW_STYLES} {$EndIf} {..$Define HARD_CRT} {Redirect STD_...} {..$Define CRT_EVENT} {CTRL-C,...} {$Define MOUSE_IS_USED} {Handle mouse or not} {..$Define OneByOne} {Block or byte style write} unit CRT32; Interface {$IfDef Win32} Const { CRT modes of original CRT unit } 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 ROM font } { Mode constants for 3.0 compatibility of original CRT unit } C40 = CO40; C80 = CO80; { Foreground and background color constants of original CRT unit } Black = 0; Blue = 1; Green = 2; Cyan = 3; Red = 4; Magenta = 5; Brown = 6; LightGray = 7; { Foreground color constants of original CRT unit } DarkGray = 8; LightBlue = 9; LightGreen = 10; LightCyan = 11; LightRed = 12; LightMagenta = 13; Yellow = 14; White = 15; { Add-in for blinking of original CRT unit } Blink = 128; { } { New constans there are not in original CRT unit } { } MouseLeftButton = 1; MouseRightButton = 2; MouseCenterButton = 4; var { Interface variables of original CRT unit } CheckBreak: Boolean; { Enable Ctrl-Break } CheckEOF: Boolean; { Enable Ctrl-Z } DirectVideo: Boolean; { Enable direct video addressing } CheckSnow: Boolean; { Enable snow filtering } LastMode: Word; { Current text mode } TextAttr: Byte; { Current text attribute } WindMin: Word; { Window upper left coordinates } WindMax: Word; { Window lower right coordinates } { } { New variables there are not in original CRT unit } { } MouseInstalled: boolean; MousePressedButtons: word; { Interface functions & procedures of original CRT unit } procedure AssignCrt(var F: Text); function KeyPressed: Boolean; function ReadKey: char; procedure TextMode(Mode: Integer); procedure Window(X1, Y1, X2, Y2: Byte); procedure GotoXY(X, Y: Byte); function WhereX: Byte; function WhereY: Byte; procedure ClrScr; procedure ClrEol; procedure InsLine; procedure DelLine; procedure TextColor(Color: Byte); procedure TextBackground(Color: Byte); procedure LowVideo; procedure HighVideo; procedure NormVideo; procedure Delay(MS: Word); procedure Sound(Hz: Word); procedure NoSound; { New functions & procedures there are not in original CRT unit } procedure FillerScreen(FillChar: Char); procedure FlushInputBuffer; function GetCursor: Word; procedure SetCursor(NewCursor: Word); function MouseKeyPressed: Boolean; procedure MouseGotoXY(X, Y: Integer); function MouseWhereY: Integer; function MouseWhereX: Integer; procedure MouseShowCursor; procedure MouseHideCursor; { These functions & procedures are for inside use only } function MouseReset: Boolean; procedure WriteChrXY(X, Y: Byte; Chr: char); procedure WriteStrXY(X, Y: Byte; Str: PChar; dwSize: Integer); procedure OverwriteChrXY(X, Y: Byte; Chr: char); {$EndIf Win32} implementation {$IfDef Win32} uses Windows, SysUtils; type POpenText = ^TOpenText; TOpenText = function(var F: Text; Mode: Word): Integer; far; var IsWinNT: boolean; PtrOpenText: POpenText; hConsoleInput: THandle; hConsoleOutput: THandle; ConsoleScreenRect: TSmallRect; StartAttr: word; LastX, LastY: byte; SoundDuration: integer; SoundFrequency: integer; OldCP: integer; MouseRowWidth, MouseColWidth: word; MousePosX, MousePosY: smallInt; MouseButtonPressed: boolean; MouseEventTime: TDateTime; { } { This function handles the Write and WriteLn commands } { } function TextOut(var F: Text): Integer; far; {$IfDef OneByOne} var dwSize: DWORD; {$EndIf} begin with TTExtRec(F) do begin if BufPos > 0 then begin LastX := WhereX; LastY := WhereY; {$IfDef OneByOne} dwSize := 0; while (dwSize < BufPos) do begin WriteChrXY(LastX, LastY, BufPtr[dwSize]); Inc(dwSize); end; {$Else} WriteStrXY(LastX, LastY, BufPtr, BufPos); FillChar(BufPtr^, BufPos + 1, #0); {$EndIf} BufPos := 0; end; end; Result := 0; end; { } { This function handles the exchanging of Input or Output } { } function OpenText(var F: Text; Mode: Word): Integer; far; var OpenResult: integer; begin OpenResult := 102; { Text not assigned } if Assigned(PtrOpenText) then begin TTextRec(F).OpenFunc := PtrOpenText; OpenResult := PtrOpenText^(F, Mode); if OpenResult = 0 then begin if Mode = fmInput then hConsoleInput := TTextRec(F).Handle else begin hConsoleOutput := TTextRec(F).Handle; TTextRec(Output).InOutFunc := @TextOut; TTextRec(Output).FlushFunc := @TextOut; end; end; end; Result := OpenResult; end; { } { Fills the current window with special character } { } procedure FillerScreen(FillChar: Char); var Coord: TCoord; dwSize, dwCount: DWORD; Y: integer; begin Coord.X := ConsoleScreenRect.Left; dwSize := ConsoleScreenRect.Right - ConsoleScreenRect.Left + 1; for Y := ConsoleScreenRect.Top to ConsoleScreenRect.Bottom do begin Coord.Y := Y; FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount); FillConsoleOutputCharacter(hConsoleOutput, FillChar, dwSize, Coord, dwCount); end; GotoXY(1,1); end; { } { Write one character at the X,Y position } { } procedure WriteChrXY(X, Y: Byte; Chr: char); var Coord: TCoord; dwSize, dwCount: DWORD; begin LastX := X; LastY := Y; case Chr of #13: LastX := 1; #10: begin LastX := 1; Inc(LastY); end; else begin Coord.X := LastX - 1 + ConsoleScreenRect.Left; Coord.Y := LastY - 1 + ConsoleScreenRect.Top; dwSize := 1; FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount); FillConsoleOutputCharacter(hConsoleOutput, Chr, dwSize, Coord, dwCount); Inc(LastX); end; end; if (LastX + ConsoleScreenRect.Left) > (ConsoleScreenRect.Right + 1) then begin LastX := 1; Inc(LastY); end; if (LastY + ConsoleScreenRect.Top) > (ConsoleScreenRect.Bottom + 1) then begin Dec(LastY); GotoXY(1,1); DelLine; end; GotoXY(LastX, LastY); end; { } { Write string into the X,Y position } { } (* !!! The WriteConsoleOutput does not write into the last line !!! Procedure WriteStrXY(X,Y: byte; Str: PChar; dwSize: integer ); {$IfDef OneByOne} Var dwCount: integer; {$Else} Type PBuffer= ^TBuffer; TBUffer= packed array [0..16384] of TCharInfo; Var I: integer; dwCount: DWORD; WidthHeight,Coord: TCoord; hTempConsoleOutput: THandle; SecurityAttributes: TSecurityAttributes; Buffer: PBuffer; DestinationScreenRect,SourceScreenRect: TSmallRect; {$EndIf} Begin If dwSize>0 Then Begin {$IfDef OneByOne} LastX:=X; LastY:=Y; dwCount:=0; While dwCount < dwSize Do Begin WriteChrXY(LastX,LastY,Str[dwCount]); Inc(dwCount); End; {$Else} SecurityAttributes.nLength:=SizeOf(SecurityAttributes)-SizeOf(DWORD); SecurityAttributes.lpSecurityDescriptor:=NIL; SecurityAttributes.bInheritHandle:=TRUE; hTempConsoleOutput:=CreateConsoleScreenBuffer( GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, @SecurityAttributes, CONSOLE_TEXTMODE_BUFFER, NIL ); If dwSize<=(ConsoleScreenRect.Right-ConsoleScreenRect.Left+1) Then Begin WidthHeight.X:=dwSize; WidthHeight.Y:=1; End Else Begin WidthHeight.X:=ConsoleScreenRect.Right-ConsoleScreenRect.Left+1; WidthHeight.Y:=dwSize DIV WidthHeight.X; If (dwSize MOD WidthHeight.X) > 0 Then Inc(WidthHeight.Y); End; SetConsoleScreenBufferSize(hTempConsoleOutput,WidthHeight); DestinationScreenRect.Left:=0; DestinationScreenRect.Top:=0; DestinationScreenRect.Right:=WidthHeight.X-1; DestinationScreenRect.Bottom:=WidthHeight.Y-1; SetConsoleWindowInfo(hTempConsoleOutput,FALSE,DestinationScreenRect); Coord.X:=0; For I:=1 To WidthHeight.Y Do Begin Coord.Y:=I-0; FillConsoleOutputAttribute(hTempConsoleOutput,TextAttr,WidthHeight.X,Coord,dwCount); FillConsoleOutputCharacter(hTempConsoleOutput,' ' ,WidthHeight.X,Coord,dwCount); End; WriteConsole(hTempConsoleOutput,Str,dwSize,dwCount,NIL); { } New(Buffer); Coord.X:= 0; Coord.Y:= 0; SourceScreenRect.Left:=0; SourceScreenRect.Top:=0; SourceScreenRect.Right:=WidthHeight.X-1; SourceScreenRect.Bottom:=WidthHeight.Y-1; ReadConsoleOutputA(hTempConsoleOutput,Buffer,WidthHeight,Coord,SourceScreenRect); Coord.X:=X-1; Coord.Y:=Y-1; DestinationScreenRect:=ConsoleScreenRect; WriteConsoleOutputA(hConsoleOutput,Buffer,WidthHeight,Coord,DestinationScreenRect); GotoXY((dwSize MOD WidthHeight.X)-1,WidthHeight.Y+1); Dispose(Buffer); { } CloseHandle(hTempConsoleOutput); {$EndIf} End; End; *) procedure WriteStrXY(X, Y: Byte; Str: PChar; dwSize: Integer); {$IfDef OneByOne} var dwCount: integer; {$Else} var I: integer; LineSize, dwCharCount, dwCount, dwWait: DWORD; WidthHeight: TCoord; OneLine: packed array [0..131] of char; Line, TempStr: PChar; procedure NewLine; begin LastX := 1; Inc(LastY); if (LastY + ConsoleScreenRect.Top) > (ConsoleScreenRect.Bottom + 1) then begin Dec(LastY); GotoXY(1,1); DelLine; end; GotoXY(LastX, LastY); end; {$EndIf} begin if dwSize > 0 then begin {$IfDef OneByOne} LastX := X; LastY := Y; dwCount := 0; while dwCount < dwSize do begin WriteChrXY(LastX, LastY, Str[dwCount]); Inc(dwCount); end; {$Else} LastX := X; LastY := Y; GotoXY(LastX, LastY); dwWait := dwSize; TempStr := Str; while (dwWait > 0) and (Pos(#13#10, StrPas(TempStr)) = 1) do begin Dec(dwWait, 2); Inc(TempStr, 2); NewLine; end; while (dwWait > 0) and (Pos(#10, StrPas(TempStr)) = 1) do begin Dec(dwWait); Inc(TempStr); NewLine; end; if dwWait > 0 then begin if dwSize <= (ConsoleScreenRect.Right - ConsoleScreenRect.Left - LastX + 1) then begin WidthHeight.X := dwSize + LastX - 1; WidthHeight.Y := 1; end else begin WidthHeight.X := ConsoleScreenRect.Right - ConsoleScreenRect.Left + 1; WidthHeight.Y := dwSize div WidthHeight.X; if (dwSize mod WidthHeight.X) > 0 then Inc(WidthHeight.Y); end; for I := 1 to WidthHeight.Y do begin FillChar(OneLine, SizeOf(OneLine), #0); Line := @OneLine; LineSize := WidthHeight.X - LastX + 1; if LineSize > dwWait then LineSize := dwWait; Dec(dwWait, LineSize); StrLCopy(Line, TempStr, LineSize); Inc(TempStr, LineSize); dwCharCount := Pos(#13#10, StrPas(Line)); if dwCharCount > 0 then begin OneLine[dwCharCount - 1] := #0; OneLine[dwCharCount] := #0; WriteConsole(hConsoleOutput, Line, dwCharCount - 1,dwCount, nil); Inc(Line, dwCharCount + 1); NewLine; LineSize := LineSize - (dwCharCount + 1); end else begin dwCharCount := Pos(#10, StrPas(Line)); if dwCharCount > 0 then begin OneLine[dwCharCount - 1] := #0; WriteConsole(hConsoleOutput, Line, dwCharCount - 1,dwCount, nil); Inc(Line, dwCharCount); NewLine; LineSize := LineSize - dwCharCount; end; end; if LineSize <> 0 then begin WriteConsole(hConsoleOutput, Line, LineSize, dwCount, nil); end; if dwWait > 0 then begin NewLine; end; end; end; {$EndIf} end; end; { } { Empty the buffer } { } procedure FlushInputBuffer; begin FlushConsoleInputBuffer(hConsoleInput); end; { } { Get size of current cursor } { } function GetCursor: Word; var CCI: TConsoleCursorInfo; begin GetConsoleCursorInfo(hConsoleOutput, CCI); GetCursor := CCI.dwSize; end; { } { Set size of current cursor } { } procedure SetCursor(NewCursor: Word); var CCI: TConsoleCursorInfo; begin if NewCursor = $0000 then begin CCI.dwSize := GetCursor; CCI.bVisible := False; end else begin CCI.dwSize := NewCursor; CCI.bVisible := True; end; SetConsoleCursorInfo(hConsoleOutput, CCI); end; { } { --- Begin of Interface functions & procedures of original CRT unit --- } procedure AssignCrt(var F: Text); begin Assign(F, ''); TTextRec(F).OpenFunc := @OpenText; end; function KeyPressed: Boolean; var NumberOfEvents: DWORD; NumRead: DWORD; InputRec: TInputRecord; Pressed: boolean; begin Pressed := False; GetNumberOfConsoleInputEvents(hConsoleInput, NumberOfEvents); if NumberOfEvents > 0 then begin if PeekConsoleInput(hConsoleInput, InputRec, 1,NumRead) then begin if (InputRec.EventType = KEY_EVENT) and (InputRec{$IfDef NEW_STYLES}.Event{$EndIf}.KeyEvent.bKeyDown) then begin Pressed := True; {$IfDef MOUSE_IS_USED} MouseButtonPressed := False; {$EndIf} end else begin {$IfDef MOUSE_IS_USED} if (InputRec.EventType = _MOUSE_EVENT) then begin with InputRec{$IfDef NEW_STYLES}.Event{$EndIf}.MouseEvent do begin MousePosX := dwMousePosition.X; MousePosY := dwMousePosition.Y; if dwButtonState = FROM_LEFT_1ST_BUTTON_PRESSED then begin MouseEventTime := Now; MouseButtonPressed := True; {If (dwEventFlags AND DOUBLE_CLICK)<>0 Then Begin} {End;} end; end; end; ReadConsoleInput(hConsoleInput, InputRec, 1,NumRead); {$Else} ReadConsoleInput(hConsoleInput, InputRec, 1,NumRead); {$EndIf} end; end; end; Result := Pressed; end; function ReadKey: char; var NumRead: DWORD; InputRec: TInputRecord; begin repeat repeat until KeyPressed; ReadConsoleInput(hConsoleInput, InputRec, 1,NumRead); until InputRec{$IfDef NEW_STYLES}.Event{$EndIf}.KeyEvent.AsciiChar > #0; Result := InputRec{$IfDef NEW_STYLES}.Event{$EndIf}.KeyEvent.AsciiChar; end; procedure TextMode(Mode: Integer); begin end; procedure Window(X1, Y1, X2, Y2: Byte); begin ConsoleScreenRect.Left := X1 - 1; ConsoleScreenRect.Top := Y1 - 1; ConsoleScreenRect.Right := X2 - 1; ConsoleScreenRect.Bottom := Y2 - 1; WindMin := (ConsoleScreenRect.Top shl 8) or ConsoleScreenRect.Left; WindMax := (ConsoleScreenRect.Bottom shl 8) or ConsoleScreenRect.Right; {$IfDef WindowFrameToo} SetConsoleWindowInfo(hConsoleOutput, True, ConsoleScreenRect); {$EndIf} GotoXY(1,1); end; procedure GotoXY(X, Y: Byte); var Coord: TCoord; begin Coord.X := X - 1 + ConsoleScreenRect.Left; Coord.Y := Y - 1 + ConsoleScreenRect.Top; if not SetConsoleCursorPosition(hConsoleOutput, Coord) then begin GotoXY(1, 1); DelLine; end; end; function WhereX: Byte; var CBI: TConsoleScreenBufferInfo; begin GetConsoleScreenBufferInfo(hConsoleOutput, CBI); Result := TCoord(CBI.dwCursorPosition).X + 1 - ConsoleScreenRect.Left; end; function WhereY: Byte; var CBI: TConsoleScreenBufferInfo; begin GetConsoleScreenBufferInfo(hConsoleOutput, CBI); Result := TCoord(CBI.dwCursorPosition).Y + 1 - ConsoleScreenRect.Top; end; procedure ClrScr; begin FillerScreen(' '); end; procedure ClrEol; var Coord: TCoord; dwSize, dwCount: DWORD; begin Coord.X := WhereX - 1 + ConsoleScreenRect.Left; Coord.Y := WhereY - 1 + ConsoleScreenRect.Top; dwSize := ConsoleScreenRect.Right - Coord.X + 1; FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount); FillConsoleOutputCharacter(hConsoleOutput, ' ', dwSize, Coord, dwCount); end; procedure InsLine; var SourceScreenRect: TSmallRect; Coord: TCoord; CI: TCharInfo; dwSize, dwCount: DWORD; begin SourceScreenRect := ConsoleScreenRect; SourceScreenRect.Top := WhereY - 1 + ConsoleScreenRect.Top; SourceScreenRect.Bottom := ConsoleScreenRect.Bottom - 1; CI.AsciiChar := ' '; CI.Attributes := TextAttr; Coord.X := SourceScreenRect.Left; Coord.Y := SourceScreenRect.Top + 1; dwSize := SourceScreenRect.Right - SourceScreenRect.Left + 1; ScrollConsoleScreenBuffer(hConsoleOutput, SourceScreenRect, nil, Coord, CI); Dec(Coord.Y); FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount); end; procedure DelLine; var SourceScreenRect: TSmallRect; Coord: TCoord; CI: TCharinfo; dwSize, dwCount: DWORD; begin SourceScreenRect := ConsoleScreenRect; SourceScreenRect.Top := WhereY + ConsoleScreenRect.Top; CI.AsciiChar := ' '; CI.Attributes := TextAttr; Coord.X := SourceScreenRect.Left; Coord.Y := SourceScreenRect.Top - 1; dwSize := SourceScreenRect.Right - SourceScreenRect.Left + 1; ScrollConsoleScreenBuffer(hConsoleOutput, SourceScreenRect, nil, Coord, CI); FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount); end; procedure TextColor(Color: Byte); begin LastMode := TextAttr; TextAttr := (Color and $0F) or (TextAttr and $F0); SetConsoleTextAttribute(hConsoleOutput, TextAttr); end; procedure TextBackground(Color: Byte); begin LastMode := TextAttr; TextAttr := (Color shl 4) or (TextAttr and $0F); SetConsoleTextAttribute(hConsoleOutput, TextAttr); end; procedure LowVideo; begin LastMode := TextAttr; TextAttr := TextAttr and $F7; SetConsoleTextAttribute(hConsoleOutput, TextAttr); end; procedure HighVideo; begin LastMode := TextAttr; TextAttr := TextAttr or $08; SetConsoleTextAttribute(hConsoleOutput, TextAttr); end; procedure NormVideo; begin LastMode := TextAttr; TextAttr := StartAttr; SetConsoleTextAttribute(hConsoleOutput, TextAttr); end; procedure Delay(MS: Word); { Const Magic= $80000000; var StartMS,CurMS,DeltaMS: DWORD; } begin Windows.SleepEx(MS, False); // Windows.Sleep(MS); { StartMS:= GetTickCount; Repeat CurMS:= GetTickCount; If CurMS >= StartMS Then DeltaMS:= CurMS - StartMS Else DeltaMS := (CurMS + Magic) - (StartMS - Magic); Until MS ShowMouseConsoleMode then begin cMode := cMode or ShowMouseConsoleMode; SetConsoleMode(hConsoleInput, cMode); end; end; procedure MouseHideCursor; const ShowMouseConsoleMode = ENABLE_MOUSE_INPUT; var cMode: DWORD; begin GetConsoleMode(hConsoleInput, cMode); if (cMode and ShowMouseConsoleMode) = ShowMouseConsoleMode then begin cMode := cMode and ($FFFFFFFF xor ShowMouseConsoleMode); SetConsoleMode(hConsoleInput, cMode); end; end; function MouseKeyPressed: Boolean; {$IfDef MOUSE_IS_USED} const MouseDeltaTime = 200; var ActualTime: TDateTime; HourA, HourM, MinA, MinM, SecA, SecM, MSecA, MSecM: word; MSecTimeA, MSecTimeM: longInt; MSecDelta: longInt; {$EndIf} begin MousePressedButtons := 0; {$IfDef MOUSE_IS_USED} Result := False; if MouseButtonPressed then begin ActualTime := NOW; DecodeTime(ActualTime, HourA, MinA, SecA, MSecA); DecodeTime(MouseEventTime, HourM, MinM, SecM, MSecM); MSecTimeA := (3600 * HourA + 60 * MinA + SecA) * 100 + MSecA; MSecTimeM := (3600 * HourM + 60 * MinM + SecM) * 100 + MSecM; MSecDelta := Abs(MSecTimeM - MSecTimeA); if (MSecDelta < MouseDeltaTime) or (MSecDelta > (8784000 - MouseDeltaTime)) then begin MousePressedButtons := MouseLeftButton; MouseButtonPressed := False; Result := True; end; end; {$Else} Result := False; {$EndIf} end; procedure MouseGotoXY(X, Y: Integer); begin {$IfDef MOUSE_IS_USED} mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, X - 1,Y - 1,WHEEL_DELTA, GetMessageExtraInfo()); MousePosY := (Y - 1) * MouseRowWidth; MousePosX := (X - 1) * MouseColWidth; {$EndIf} end; function MouseWhereY: Integer; {$IfDef MOUSE_IS_USED} {Var lppt, lpptBuf: TMouseMovePoint;} {$EndIf} begin {$IfDef MOUSE_IS_USED} {GetMouseMovePoints( SizeOf(TMouseMovePoint), lppt, lpptBuf, 7,GMMP_USE_DRIVER_POINTS ); Result:=lpptBuf.Y DIV MouseRowWidth;} Result := (MousePosY div MouseRowWidth) + 1; {$Else} Result := -1; {$EndIf} end; function MouseWhereX: Integer; {$IfDef MOUSE_IS_USED} {Var lppt, lpptBuf: TMouseMovePoint;} {$EndIf} begin {$IfDef MOUSE_IS_USED} {GetMouseMovePoints( SizeOf(TMouseMovePoint), lppt, lpptBuf, 7,GMMP_USE_DRIVER_POINTS ); Result:=lpptBuf.X DIV MouseColWidth;} Result := (MousePosX div MouseColWidth) + 1; {$Else} Result := -1; {$EndIf} end; { } procedure Init; const ExtInpConsoleMode = ENABLE_WINDOW_INPUT or ENABLE_PROCESSED_INPUT or ENABLE_MOUSE_INPUT; ExtOutConsoleMode = ENABLE_PROCESSED_OUTPUT or ENABLE_WRAP_AT_EOL_OUTPUT; var cMode: DWORD; Coord: TCoord; OSVersion: TOSVersionInfo; CBI: TConsoleScreenBufferInfo; begin OSVersion.dwOSVersionInfoSize := SizeOf(TOSVersionInfo); GetVersionEx(OSVersion); if OSVersion.dwPlatformId = VER_PLATFORM_WIN32_NT then IsWinNT := True else IsWinNT := False; PtrOpenText := TTextRec(Output).OpenFunc; {$IfDef HARD_CRT} AllocConsole; Reset(Input); hConsoleInput := GetStdHandle(STD_INPUT_HANDLE); TTextRec(Input).Handle := hConsoleInput; ReWrite(Output); hConsoleOutput := GetStdHandle(STD_OUTPUT_HANDLE); TTextRec(Output).Handle := hConsoleOutput; {$Else} Reset(Input); hConsoleInput := TTextRec(Input).Handle; ReWrite(Output); hConsoleOutput := TTextRec(Output).Handle; {$EndIf} GetConsoleMode(hConsoleInput, cMode); if (cMode and ExtInpConsoleMode) <> ExtInpConsoleMode then begin cMode := cMode or ExtInpConsoleMode; SetConsoleMode(hConsoleInput, cMode); end; TTextRec(Output).InOutFunc := @TextOut; TTextRec(Output).FlushFunc := @TextOut; GetConsoleScreenBufferInfo(hConsoleOutput, CBI); GetConsoleMode(hConsoleOutput, cMode); if (cMode and ExtOutConsoleMode) <> ExtOutConsoleMode then begin cMode := cMode or ExtOutConsoleMode; SetConsoleMode(hConsoleOutput, cMode); end; TextAttr := CBI.wAttributes; StartAttr := CBI.wAttributes; LastMode := CBI.wAttributes; Coord.X := CBI.srWindow.Left; Coord.Y := CBI.srWindow.Top; WindMin := (Coord.Y shl 8) or Coord.X; Coord.X := CBI.srWindow.Right; Coord.Y := CBI.srWindow.Bottom; WindMax := (Coord.Y shl 8) or Coord.X; ConsoleScreenRect := CBI.srWindow; SoundDuration := -1; OldCp := GetConsoleOutputCP; SetConsoleOutputCP(1250); {$IfDef CRT_EVENT} SetConsoleCtrlHandler(@ConsoleEventProc, True); {$EndIf} {$IfDef MOUSE_IS_USED} SetCapture(hConsoleInput); KeyPressed; {$EndIf} MouseInstalled := MouseReset; Window(1,1,80,25); ClrScr; end; { } procedure Done; begin {$IfDef CRT_EVENT} SetConsoleCtrlHandler(@ConsoleEventProc, False); {$EndIf} SetConsoleOutputCP(OldCP); TextAttr := StartAttr; SetConsoleTextAttribute(hConsoleOutput, TextAttr); ClrScr; FlushInputBuffer; {$IfDef HARD_CRT} TTextRec(Input).Mode := fmClosed; TTextRec(Output).Mode := fmClosed; FreeConsole; {$Else} Close(Input); Close(Output); {$EndIf} end; initialization Init; finalization Done; {$Endif win32} end.