Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CRT для консольного приложения 
:(
    Опции темы
Alex
Дата 26.9.2005, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Код

$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<DeltaMS; 
    } 
end; 

procedure Sound(Hz: Word); 
begin 
  {SetSoundIOPermissionMap(LocalIOPermission_ON);} 
  SoundFrequency := Hz; 
  if IsWinNT then 
  begin 
    Windows.Beep(SoundFrequency, SoundDuration) 
  end 
  else 
  begin 
    asm 
        mov  BX,Hz 
        cmp  BX,0 
        jz   @2 
        mov  AX,$34DD 
        mov  DX,$0012 
        cmp  DX,BX 
        jnb  @2 
        div  BX 
        mov  BX,AX 
        { Sound is On ? } 
        in   Al,$61 
        test Al,$03 
        jnz  @1 
        { Set Sound On } 
        or   Al,03 
        out  $61,Al 
        { Timer Command } 
        mov  Al,$B6 
        out  $43,Al 
        { Set Frequency } 
    @1: mov  Al,Bl 
        out  $42,Al 
        mov  Al,Bh 
        out  $42,Al 
    @2: 
    end; 
  end; 
end; 

procedure NoSound; 
begin 
  if IsWinNT then 
  begin 
    Windows.Beep(SoundFrequency, 0); 
  end 
  else 
  begin 
      asm 
        { Set Sound On } 
        in   Al,$61 
        and  Al,$FC 
        out  $61,Al 
      end; 
  end; 
  {SetSoundIOPermissionMap(LocalIOPermission_OFF);} 
end; 
{ --- End of Interface functions & procedures of original CRT unit --- } 
{  } 

procedure OverwriteChrXY(X, Y: Byte; Chr: char); 
var 
  Coord: TCoord; 
  dwSize, dwCount: DWORD; 
begin 
  LastX := X; 
  LastY := Y; 
  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); 
  GotoXY(LastX, LastY); 
end; 

{  --------------------------------------------------  } 
{  Console Event Handler } 
{  } 
{$IfDef CRT_EVENT} 
function ConsoleEventProc(CtrlType: DWORD): Bool; stdcall; far; 
var 
  S: {$IfDef Win32}ShortString{$Else}String{$EndIf}; 
  Message: PChar; 
begin 
  case CtrlType of 
    CTRL_C_EVENT: S        := 'CTRL_C_EVENT'; 
    CTRL_BREAK_EVENT: S    := 'CTRL_BREAK_EVENT'; 
    CTRL_CLOSE_EVENT: S    := 'CTRL_CLOSE_EVENT'; 
    CTRL_LOGOFF_EVENT: S   := 'CTRL_LOGOFF_EVENT'; 
    CTRL_SHUTDOWN_EVENT: S := 'CTRL_SHUTDOWN_EVENT'; 
    else 
      S := 'UNKNOWN_EVENT'; 
  end; 
  S := S + ' detected, but not handled.'; 
  Message := @S; 
  Inc(Message); 
  MessageBox(0, Message, 'Win32 Console', MB_OK); 
  Result := True; 
end; 
  {$EndIf} 

function MouseReset: Boolean; 
begin 
  MouseColWidth := 1; 
  MouseRowWidth := 1; 
  Result := True; 
end; 

procedure MouseShowCursor; 
const 
  ShowMouseConsoleMode = ENABLE_MOUSE_INPUT; 
var 
  cMode: DWORD; 
begin 
  GetConsoleMode(hConsoleInput, cMode); 
  if (cMode and ShowMouseConsoleMode) <> 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.



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0818 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.