FAQ VCL
Консоль

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как включить/выключить стандартный вывод в консоль?

// Включить
procedure EnableStdOutput;
begin
  Assign(Output, '');
end;

// Выключить
procedure DisableStdOutput;
begin
  {$IFDEF MSWINDOWS}
  Assign(Output, 'NUL');
  {$ELSE IFDEF LINUX}
  Assign(Output, '/dev/null');
  {$ENDIF}
end;


Как получить Handle консольного приложения?

// Способ первый
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

function GetConsoleHandle: HWND;
var
  OldT: string;
  NewT: string;
begin
  SetLength(OldT, 1024);
  GetConsoleTitle(PChar(OldT), 1024);
  NewT := IntToStr(GetTickCount) + IntToStr(GetCurrentProcessId);
  SetConsoleTitle(PChar(NewT));
  Sleep(10);
  Result := FindWindow(nil, PChar(NewT));
  SetConsoleTitle(PChar(OldT));
end;

var
  Handle: HWND;

begin
  Handle := GetConsoleHandle;
  if Handle <> 0 then
    ShowWindow(Handle, SW_MINIMIZE);

  Readln;
end.

// Способ второй
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

function GetConsoleWindow: IntPtr; stdcall;
  external kernel32 name 'GetConsoleWindow';

var
  Handle: HWND;

begin
  Handle := GetConsoleWindow;
  if Handle <> 0 then
    ShowWindow(Handle, SW_MINIMIZE);

  Readln;
end.


Как заставить консоль поддерживать русский язык?

program Project1;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

type
  TCONSOLE_FONT_INFOEX = record
    cbSize: Cardinal;
    nFont: LongWord;
    dwFontSize: COORD;
    FontFamily: Cardinal;
    FontWeight: Cardinal;
    FaceName: array [0..LF_FACESIZE-1] of WideChar;
  end;
  PCONSOLE_FONT_INFOEX = ^TCONSOLE_FONT_INFOEX;

function SetCurrentConsoleFontEx(ConsoleOutput: THandle; MaximumWindow: BOOL;
  ConsoleInfo: PCONSOLE_FONT_INFOEX): BOOL; stdcall;
  external kernel32 name 'SetCurrentConsoleFontEx';
function GetCurrentConsoleFontEx(ConsoleOutput: THandle; MaximumWindow: BOOL;
  ConsoleInfo: PCONSOLE_FONT_INFOEX): BOOL; stdcall;
  external kernel32 name 'GetCurrentConsoleFontEx';

procedure SetConsoleFont(const AFontName: string; const AFontSize: Word);
var
  ci: TCONSOLE_FONT_INFOEX;
  ch: THandle;
begin
  if not CheckWin32Version(6, 0) then
    Exit;

  FillChar(ci, SizeOf(TCONSOLE_FONT_INFOEX), 0);
  ci.cbSize := SizeOf(TCONSOLE_FONT_INFOEX);

  ch := GetStdHandle(STD_OUTPUT_HANDLE);
  GetCurrentConsoleFontEx(ch, False, @ci);
  ci.FontFamily := FF_DONTCARE;
  FillChar(ci.FaceName, LF_FACESIZE, #0);
  StrPCopy(@ci.FaceName[0], AFontName); // или немного иначе
  // CopyMemory(@ci.FaceName[0], @AFontName[1], Length(AFontName) * 2);
  ci.dwFontSize.X := 0;
  ci.dwFontSize.Y := AFontSize;
  ci.FontWeight := FW_NORMAL;
  SetCurrentConsoleFontEx(ch, False, @ci);
end;

var
  s: string;
begin
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);

  // Нужно установить шрифт, поддерживающий русский язык
  SetConsoleFont('Lucida Console', 14);
  // SetConsoleFont('Consolas', 16);

  Writeln('Привет');
  Readln(s);
  Writeln(s);
  Readln(Input);
end.


Как отследить нажатие клавиши в консольной приложении?

program Project1;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows, System.SysUtils;

function ShiftDown: Boolean;
begin
  Result := (GetAsyncKeyState(VK_SHIFT) shr 16) and 1 = 1;
end;

var
  NumRead: DWORD;
  InputRec: TInputRecord;
  ci: THandle;
begin
  ci := GetStdHandle(STD_INPUT_HANDLE);

  while ReadConsoleInput(ci, InputRec, 1, NumRead) do
  begin
    if InputRec.EventType <> KEY_EVENT then
      Continue;

    if InputRec.Event.KeyEvent.bKeyDown and (LowerCase(InputRec.Event.KeyEvent.AsciiChar) = 'q') then
      WriteLn('Press key "q"')
    else if InputRec.Event.KeyEvent.bKeyDown and (InputRec.Event.KeyEvent.AsciiChar = ^Q) and not ShiftDown then
      WriteLn('Press key "Ctrl + Q"')
    else
    begin
      // Остальной код
    end;
  end;
end.


Как отследить нажатие клавиши в консольной приложении не прерывая работу основного цикла?

program Project1;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

var
  NumRead: DWORD;
  NumEvents: DWORD;
  InputRec: TInputRecord;
  ci: THandle;
begin
  ci := GetStdHandle(STD_INPUT_HANDLE);

  repeat
    // Остальной код
    WriteLn('Working...');
    Sleep(100);

    GetNumberOfConsoleInputEvents(ci, NumEvents);
    if NumEvents > 0 then
      if ReadConsoleInput(ci, InputRec, 1, NumRead) then
        case InputRec.Event.KeyEvent.wVirtualKeyCode of
          ord('Q'): WriteLn('Press key "Q"');
          VK_ESCAPE: Break;
        end;
  until False;
end.


Как обработать команду Ctrl+C в консольной приложении?

program Project1;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

function console_handler(dwCtrlType: DWORD): BOOL; stdcall;
begin
  // Отменяем завершение приложения по Ctrl+C
  if dwCtrlType = CTRL_C_EVENT then
    Result := True
  else
    Result := False;
end;

begin
  SetConsoleCtrlHandler(@console_handler, True);

  repeat
    Sleep(100);
  until False;
end.

При использовании материала - ссылка на сайт обязательна