游戏的界面
主要的功能实现
1 键盘消息
复制代码
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
windows,
uConsoleClass in 'uConsoleClass.pas',
uSnake in 'uSnake.pas';
// 参考
/// http://blog.csdn.net/haiou327/article/details/5695237
var
MyMsg : TMsg;
begin
while windows.GetMessage(MyMsg, 0, 0, 0) do
begin
DispatchMessage(MyMsg);
end;
end.
复制代码
2 定时器
这里用的是API
procedure TimerProc(window : Hwnd ; message,idEvent :UInt; dwTime: dword);stdcall;
begin
if Snake.StartSnake then
Snake.MoveSnake();
end;
FTimer := SetTimer(0, 0, TIMERINTERVAL, @TimerProc);
3 蛇控制单元
复制代码
unit uSnake;
interface
uses
Windows, classes, uConsoleClass, ExtCtrls;
const
GAMEROW = 16;
GAMECOL = 54;
TIMERINTERVAL = 300;
type
TMoveDir = (MD_Right, MD_Left, MD_Up, MD_Down);
TPointType = (PT_Head, PT_Body, PT_Tail, PT_Food);
TGamePoint = record
Row : byte;
Col : byte;
PointType : TPointType;
end;
PGamePoint = ^TGamePoint;
TReadKeyThread = Class(TThread)
private
FMoveDir : TMoveDir;
FStartRead : boolean;
FPause : boolean;
procedure SetStartRead(const Value: boolean);
public
property Pause : boolean read FPause write FPause;
property StartRead : boolean read FStartRead write SetStartRead;
property MoveDir : TMoveDir read FMoveDir write FMoveDir;
protected
procedure Execute; override;
end;
TSnake = class
private
//FGameMap : array[0..GAMEROW - 1, 0..GAMECOL - 1] of byte;
FFoodPoint : PGamePoint;
FSnakePointList : TList;
FLastPoint : PGamePoint;
FMyConsole : TConsoleControl;
FStartSnake : boolean;
FReadKeyThread : TReadKeyThread;
FEatFoodCount : integer;
// FScores : integer;
procedure InitGameMap();
procedure FreeSnakeList();
function CheckInSnake(Row, Col: integer): boolean;
procedure PrintSnake();
function GetSnakeBodyType(bodyType: TPointType): PGamePoint;
procedure GetFood();
procedure ShowScores(add: boolean = false);
procedure Start();
function CheckGameOver(): boolean;
procedure GameOver();
function EatFood(): boolean;
function GetMoveDir(): TMoveDir;
property Dir: TMoveDir read GetMoveDir;
property StartSnake: boolean read FStartSnake write FStartSnake;
public
constructor Create();
destructor Destroy;override;
procedure StartGame();
procedure MoveSnake();
function ThreadPause(): boolean;
end;
implementation
uses SysUtils;
var
Snake : TSnake;
FTimer : Integer;
procedure TimerProc(window : Hwnd ; message,idEvent :UInt; dwTime: dword);stdcall;
begin
if Snake.StartSnake then
Snake.MoveSnake();
end;
{ TSnake }
function TSnake.CheckGameOver: boolean;
var
Head: PGamePoint;
I: integer;
P: PGamePoint;
begin
Result := false;
Head := GetSnakeBodyType(PT_Head);
// FMyConsole.SetCursorTo(0, 16);
// FMyConsole.WriteText('Row: ' + inttostr(Head^.Row) + ' Col: ' + inttostr(Head^.Col));
if Dir = MD_Up then
begin
if Head^.Row = 1 then
Result := true;
end;
// 判断撞到上下的墙
if (Head^.Row < 1) or (Head^.Row > GAMEROW - 3) then
Result := true;
// 判断撞到左右的墙
if (Head^.Col < 3) or (Head^.Col > GAMECOL - 6) then
Result := true;
// 判断是否撞到自己
for I := 2 to FSnakePointList.Count - 1 do
begin
P := FSnakePointList.Items[I];
case Dir of
MD_Right:
begin
if (Head^.Col + 1 = P^.Col) and (Head^.Row = P^.Row) then
Result := true;
end;
MD_Left:
begin
if (Head^.Col - 1 = P^.Col) and (Head^.Row = P^.Row) then
Result := true;
end;
MD_Up:
begin
if (Head^.Row - 1 = P^.Row) and (Head^.Col = P^.Col) then
Result := true;
end;
MD_Down:
begin
if (Head^.Row + 1 = P^.Row) and (Head^.Col = P^.Col) then
Result := true;
end;
end;
end;
end;
function TSnake.CheckInSnake(Row, Col: integer): boolean;
var
P: PGamePoint;
I: integer;
begin
Result := false;
for I := 0 to FSnakePointList.Count - 1 do
begin
P := FSnakePointList.Items[I];
if (P^.Row = Row) and (P^.Col= Col) then
begin
Result := true;
break;
end;
end;
end;
constructor TSnake.Create();
begin
FReadKeyThread := TReadKeyThread.Create(true);
FSnakePointList := TList.Create();
New(FFoodPoint);
New(FLastPoint);
FMyConsole:= TConsoleControl.Create;
FMyConsole.SetWindowTitle('【贪吃蛇】 V1.0');
InitGameMap();
end;
destructor TSnake.Destroy;
begin
Dispose(FFoodPoint);
Dispose(FLastPoint);
FreeAndNil(FSnakePointList);
FMyConsole.Free;
FReadKeyThread.Free();
inherited;
end;
function TSnake.EatFood: boolean;
var
Head : PGamePoint;
begin
Result := false;
Head := GetSnakeBodyType(PT_Head);
if (Head^.Row = FFoodPoint^.Row) and (Head^.Col = FFoodPoint^.Col) then
begin
ShowScores(true);
Result := true;
end;
ShowScores();
end;
procedure TSnake.FreeSnakeList;
var
P: PGamePoint;
Index: integer;
begin
if FSnakePointList.Count > 0 then
begin
repeat
Index := FSnakePointList.Count - 1;
P := FSnakePointList.Items[Index];
FSnakePointList.Delete(Index);
Dispose(P);
until FSnakePointList.Count = 0;
end;
end;
procedure TSnake.GameOver;
var
S: string;
begin
StartSnake := false;
FReadKeyThread.StartRead := false;
//
FMyConsole.SetCursorTo(0, 16);
FMyConsole.WriteText(' ');
FMyConsole.SetCursorTo(0, 16);
FMyConsole.WriteText('游戏结束重新开始吗? (y/n):');
Readln(S);
if LowerCase(S) = 'y' then
begin
//FMyConsole.SetCursorTo(0, 16);
//FMyConsole.WriteText('游戏开始 ');
InitGameMap();
Start();
end;
end;
procedure TSnake.GetFood;
begin
Randomize;
repeat
FFoodPoint^.Row := Random(GAMEROW - 7) + 5;
FFoodPoint^.Col := Random(GAMECOL - 10) + 5;
until not CheckInSnake(FFoodPoint^.Row, FFoodPoint^.Col);
FMyConsole.SetForegroundColor(true, false, true, false);
FMyConsole.SetCursorTo(FFoodPoint^.Col, FFoodPoint^.Row);
FMyConsole.WriteText('O');
end;
function TSnake.GetMoveDir: TMoveDir;
begin
Result := FReadKeyThread.MoveDir;
end;
function TSnake.GetSnakeBodyType(bodyType: TPointType): PGamePoint;
var
I: integer;
begin
Result := nil;
for I := 0 to FSnakePointList.Count - 1 do
begin
Result := FSnakePointList.Items[I];
if Result.PointType = bodyType then break;
end;
end;
procedure TSnake.InitGameMap;
var
// I, J: integer;
P: PGamePoint;
begin
FMyConsole.ClearScreen;
// for I := 0 to GAMEROW - 1 do
// begin
// for J := 0 to GAMECOL - 1 do
// begin
// if (I = 0) or (I = GAMEROW - 1) then
// FGameMap[I][J] := 1
// else
// FGameMap[I][J] := 0;
//
// if (J = 0) or (J = 1) or (J = GAMECOL - 1 ) or (J = GAMECOL - 2 ) then
// FGameMap[I][J] := 1
// else
// FGameMap[I][J] := 0;
// end;
// end;
FreeSnakeList();
// 头 先添加
New(P);
P^.Row := 2;
P^.Col := 7;
P^.PointType := PT_Head;
FSnakePointList.Add(P);
// 身体
New(P);
P^.Row := 2;
P^.Col := 6;
P^.PointType := PT_Body;
FSnakePointList.Add(P);
New(P);
P^.Row := 2;
P^.Col := 5;
P^.PointType := PT_Body;
FSnakePointList.Add(P);
New(P);
P^.Row := 2;
P^.Col := 4;
P^.PointType := PT_Body;
FSnakePointList.Add(P);
New(P);
P^.Row := 2;
P^.Col := 3;
P^.PointType := PT_Tail;
FSnakePointList.Add(P);
// // 蛇的初始位置
// for J := 1 to 5 do
// FGameMap[1][J] := 1;
// 食物初始位置
// FFoodPoint^.Row := 10;
// FFoodPoint^.Col := 30;
// FFoodPoint^.PointType := PT_Food;
// FGameMap[10][30] := 1;
FMyConsole.SetCursorTo(0, 0);
FMyConsole.SetForegroundColor(true, false, false, false);
FMyConsole.WriteTextLine('┏━━━━━━━━━━━━━━━━━━━━━━━━┓');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┃ ┃');
FMyConsole.WriteTextLine('┗━━━━━━━━━━━━━━━━━━━━━━━━┛');
GetFood();
end;
procedure TSnake.MoveSnake;
var
Head : PGamePoint;
Tail : PGamePoint;
P1, P2: PGamePoint;
I : integer;
NewBody: PGamePoint;
eat: boolean;
begin
if ThreadPause then
begin
FMyConsole.SetCursorTo(0, 16);
FMyConsole.WriteText('游戏已暂停请按空格键继续... ');
end
else
begin
if CheckGameOver() then
begin
GameOver();
end
else
begin
eat := EatFood();
//保存最后一个要擦除的点
Tail := GetSnakeBodyType(PT_Tail);
FLastPoint^.Row := Tail^.Row;
FLastPoint^.Col := Tail^.Col;
if eat then
begin
New(NewBody);
NewBody^.Row := Tail^.Row;
NewBody^.Col := Tail^.Col;
NewBody^.PointType := PT_Tail;
FSnakePointList.add(NewBody);
Tail^.PointType := PT_Body;
GetFood();
end;
// 移动蛇的位置
for I := FSnakePointList.Count - 1 downto 1 do
begin
P1 := FSnakePointList.Items[I];
P2 := FSnakePointList.Items[I - 1];
P1^.Row := P2^.Row;
P1^.Col := P2^.Col;
end;
Head := GetSnakeBodyType(PT_Head);
case Dir of
MD_Right: Inc(Head^.Col);
MD_Left : Dec(Head^.Col);
MD_Up : Dec(Head^.Row);
MD_Down : Inc(Head^.Row);
end;
PrintSnake();
// 清空蛇尾
if FStartSnake and not eat then
begin
FMyConsole.SetCursorTo(FLastPoint^.Col, FLastPoint^.Row);
FMyConsole.WriteText(' ');
end;
end;
end;
end;
procedure TSnake.PrintSnake;
var
P: PGamePoint;
I: integer;
begin
FMyConsole.SetForegroundColor(false, true, false, false);
for I := 0 to FSnakePointList.Count - 1 do
begin
P := FSnakePointList.Items[I];
FMyConsole.SetCursorTo(P^.Col, P^.Row);
case P^.PointType of
PT_Head: FMyConsole.WriteText('#');
PT_Body: FMyConsole.WriteText('*');
PT_Tail: FMyConsole.WriteText('*');
end;
end;
// FMyConsole.WriteTextLine('┏━━━━━━━━━━━━━━━━━━━━━━━━┓');
// FMyConsole.WriteTextLine('┃****# ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ O ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┃ ┃');
// FMyConsole.WriteTextLine('┗━━━━━━━━━━━━━━━━━━━━━━━━┛');
// 14 行 48 列
end;
procedure TSnake.ShowScores(add: boolean = false);
var
S: string;
begin
// FEatFoodCount : integer;
// FScores : integer;
if add then
begin
Inc(FEatFoodCount);
end;
S := Format('完成食物个数: %d 得分数: %d ', [FEatFoodCount, 10 * FEatFoodCount]);
FMyConsole.SetCursorTo(0, 16);
FMyConsole.WriteText(S);
end;
procedure TSnake.Start;
begin
FEatFoodCount := 0;
//FScores := 0;
StartSnake := true;
FReadKeyThread.StartRead := true;
end;
procedure TSnake.StartGame;
var
S: string;
begin
PrintSnake();
FMyConsole.SetCursorTo(0, 16);
FMyConsole.WriteText('现在开始游戏吗? (y/n):');
Readln(S);
if LowerCase(S) = 'y' then
begin
// FMyConsole.SetCursorTo(0, 16);
// FMyConsole.WriteText('开始游戏 ');
Start();
end;
end;
function TSnake.ThreadPause: boolean;
begin
Result := FReadKeyThread.Pause;
end;
{ TReadKeyThread }
procedure TReadKeyThread.Execute;
var
arrInputRecs : array[0..9] of TInputRecord;
dwCur, dwCount : DWORD;
hInput : THandle;
begin
hInput := GetStdHandle(STD_INPUT_HANDLE);
while TRUE do
begin
ReadConsoleInput(hInput, arrInputRecs[0], 10, dwCount);
for dwCur := 0 to 10 - 1 do
begin
if self.Terminated then break;
case arrInputRecs[dwCur].EventType of
KEY_EVENT:
begin
with arrInputRecs[dwCur].Event.KeyEvent do
begin
if bKeyDown = true then
begin
case wVirtualKeyCode of
VK_Space:
begin
Pause := not Pause;
end;
VK_Left:
begin
if (MoveDir <> MD_Left) and (MoveDir <> MD_Right) then
begin
if not FPause then
MoveDir := MD_Left;
end;
end;
VK_Right:
begin
if (MoveDir <> MD_Right) and (MoveDir <> MD_Left) then
begin
if not FPause then
MoveDir := MD_Right;
end;
end;
VK_Up:
begin
if (MoveDir <> MD_Up) and (MoveDir <> MD_Down) then
begin
if not FPause then
MoveDir := MD_Up;
end;
end;
VK_Down:
begin
if (MoveDir <> MD_Up) and (MoveDir <> MD_Down) then
begin
if not FPause then
MoveDir := MD_Down;
end;
end;
end;
end;
end;
end;
end;
end;
end;
end;
procedure TReadKeyThread.SetStartRead(const Value: boolean);
begin
FStartRead := Value;
if FStartRead then
begin
MoveDir := MD_Right;
FPause := false;
Resume;
end
else
Suspend;
end;
initialization
Snake := TSnake.Create;
Snake.StartGame();
FTimer := SetTimer(0, 0, TIMERINTERVAL, @TimerProc);
finalization
KillTimer(0, FTimer);
Snake.Free();
end.
复制代码
4 控制台单元 这个单元是网上的
复制代码
unit uConsoleClass;
interface
uses Windows;
type
TConsoleControl = Class
private
FhStdIn : THandle; // Handle to the standard input
FhStdOut : THandle; // Handle to the standard output
FhStdErr : THandle; // Handle to the standard error (Output)
FbConsoleAllocated : Boolean; // Creation Flag
FBgAttrib : Cardinal; // Currently set BackGround Attribs.
FFgAttrib : Cardinal; // Currently set ForeGround Attribs.
public
(* Creates a new consolewindow, or connects the current window *)
constructor Create;
destructor Destroy;override;
(* Cleanup of the class structures *)
(* Color properties:
The console window does not handle the colors like known form delphi
components. Each color will be created from a red,green,blue and a
intensity part. In fact the resulting colors are the same as the well
known 16 base colors (clwhite .. clBlack).
Black ist if all flags are false, white if all flag are true.
The following two functions will change the color for followingwrites *)
procedure SetForegroundColor(bRed,bGreen,bBlue,bIntensity : Boolean);
procedure SetBackgroundColor(bRed,bGreen,bBlue,bIntensity : Boolean);
(* Writing functions : simple wrapper around WriteConsole*)
procedure WriteText (const s : string);
procedure WriteTextLine( const s : string);
(* Change the Windowtitle of the command window. If the program has been
executed from a CMD-box the title change is only active while the
programs execution time *)
procedure SetWindowTitle (const sTitle : string);
(* some Cursor manipulation functions *)
procedure ShowCursor (iSize : Integer);
procedure HideCursor;
procedure GetCursorPos(var x, y : integer);
procedure SetCursorTo(x, y : integer);
(* screen operations:
the screen ist the visible part of a cmd window. Behind the windowthere
is a screenbuffer. The screenbuffer may be larger than the visible window *)
procedure ClearScreen;
function GetScreenLeft : integer;
function GetScreenTop : Integer;
function GetScreenHeight : integer;
function GetScreenWidth : integer;
(* screenbuffer operations *)
procedure ClearBuffer;
function GetBufferHeight : integer;
function GetBufferWidth : integer;
(* sample to read characters from then screenbuffer *)
procedure GetCharAtPos(x, y : Integer; var rCharInfo : Char);
end;
implementation
{ TConsoleControl }
procedure TConsoleControl.ClearBuffer;
var
SBInfo : TConsoleScreenBufferInfo;
ulWrittenChars : Cardinal;
TopLeft : TCoord;
begin
TopLeft.X := 0;
TopLeft.Y := 0;
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
FillConsoleOutputCharacter(FhStdOut,' ', SBInfo.dwSize.X * SBInfo.dwSize.Y, TopLeft, ulWrittenChars);
FillConsoleOutputAttribute(FhStdOut, FOREGROUND_RED or FOREGROUND_BLUE or FOREGROUND_GREEN,
(SBInfo.srWindow.Right - SBInfo.srWindow.Left) *
(SBInfo.srWindow.Bottom - SBInfo.srWindow.Top),
TopLeft, ulWrittenChars);
end;
procedure TConsoleControl.ClearScreen;
var
SBInfo : TConsoleScreenBufferInfo;
ulWrittenChars : Cardinal;
TopLeft : TCoord;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
TopLeft.X := SBInfo.srWindow.Left;
TopLeft.Y := SBInfo.srWindow.Top;
FillConsoleOutputCharacter(FhStdOut,' ',
(SBInfo.srWindow.Right - SBInfo.srWindow.Left)*
(SBInfo.srWindow.Bottom - SBInfo.srWindow.Top),
TopLeft,
ulWrittenChars);
FillConsoleOutputAttribute(FhStdOut,FOREGROUND_RED or FOREGROUND_BLUE or FOREGROUND_GREEN,
(SBInfo.srWindow.Right - SBInfo.srWindow.Left)*
(SBInfo.srWindow.Bottom - SBInfo.srWindow.Top),
TopLeft,
ulWrittenChars);
end;
constructor TConsoleControl.Create;
begin
inherited Create;
// A process can be associated with only one console, so the AllocConsole
// function fails if the calling process already has a console.
FbConsoleAllocated := AllocConsole;
// initializing the needed handles
FhStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
FhStdErr := GetStdHandle(STD_ERROR_HANDLE);
FhStdIn := GetStdHandle(STD_INPUT_HANDLE);
end;
destructor TConsoleControl.Destroy;
begin
if FbConsoleAllocated then FreeConsole;
inherited;
end;
function TConsoleControl.GetBufferHeight: integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.dwSize.Y;
end;
function TConsoleControl.GetBufferWidth: integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.dwSize.X;
end;
procedure TConsoleControl.GetCharAtPos(x, y: Integer; var rCharInfo : Char);
var
CharInfo : array [0..10] of Char;
TopLeft : TCoord;
CharsRead : Cardinal;
begin
TopLeft.x := X;
TopLeft.Y := Y;
ReadConsoleOutputCharacter(FhStdOut,CharInfo,10,TopLeft,CharsRead);
rCharInfo := CharInfo[0];
end;
procedure TConsoleControl.GetCursorPos(var x, y: integer);
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
x := SBInfo.dwCursorPosition.X;
y := SBInfo.dwCursorPosition.Y;
end;
function TConsoleControl.GetScreenHeight: integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Bottom -SBInfo.srWindow.Top;
end;
function TConsoleControl.GetScreenLeft: integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Left;
end;
function TConsoleControl.GetScreenTop: Integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Top;
end;
function TConsoleControl.GetScreenWidth: integer;
var
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Right - SBInfo.srWindow.Left;
end;
procedure TConsoleControl.HideCursor;
var
ConsoleCursorInfo : TConsoleCursorInfo;
begin
GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
if ConsoleCursorInfo.bVisible then begin
ConsoleCursorInfo.bVisible := False;
SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
end;
end;
procedure TConsoleControl.SetBackgroundColor(bRed, bGreen, bBlue,
bIntensity: Boolean);
begin
FBgAttrib := 0;
if bRed then FBgAttrib := FBgAttrib or BACKGROUND_RED;
if bGreen then FBgAttrib := FBgAttrib or BACKGROUND_GREEN;
if bBlue then FBgAttrib := FBgAttrib or BACKGROUND_BLUE;
if bIntensity then FBgAttrib := FBgAttrib or BACKGROUND_INTENSITY;
SetConsoleTextAttribute(FhStdOut, FBgAttrib or FFgAttrib);
end;
procedure TConsoleControl.SetCursorTo(x, y: integer);
var
Coords : TCoord;
SBInfo : TConsoleScreenBufferInfo;
begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
if x < 0 then Exit;
if y < 0 then Exit;
if x > SbInfo.dwSize.X then Exit;
if y > SbInfo.dwSize.Y then Exit;
Coords.X := x;
Coords.Y := y;
SetConsoleCursorPosition(FhStdOut,Coords);
end;
procedure TConsoleControl.SetForegroundColor(bRed, bGreen, bBlue,
bIntensity: Boolean);
begin
FFgAttrib := 0;
if bRed then FFgAttrib := FFgAttrib or FOREGROUND_RED;
if bGreen then FFgAttrib := FFgAttrib or FOREGROUND_GREEN;
if bBlue then FFgAttrib := FFgAttrib or FOREGROUND_BLUE;
if bIntensity then FFgAttrib := FFgAttrib or FOREGROUND_INTENSITY;
SetConsoleTextAttribute(FhStdOut,FBgAttrib or FFgAttrib);
end;
procedure TConsoleControl.SetWindowTitle(const sTitle: string);
begin
SetConsoleTitle(PChar(sTitle));
end;
procedure TConsoleControl.ShowCursor(iSize: Integer);
var
ConsoleCursorInfo : TConsoleCursorInfo;
begin
GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
if (not ConsoleCursorInfo.bVisible) or (ConsoleCursorInfo.dwSize <> iSize) then
begin
ConsoleCursorInfo.bVisible := True;
ConsoleCursorInfo.dwSize := iSize;
SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
end;
end;
procedure TConsoleControl.WriteText(const s: string);
var
ulLength : Cardinal;
begin
WriteConsole(FhStdOut, PChar(s), Length(s), ulLength, NIL);
end;
procedure TConsoleControl.WriteTextLine(const s: string);
begin
WriteText(s +#13#10);
end;
end.
来源:https://www.cnblogs.com/qkhhxkj/archive/2013/01/05/2846380.html