Нужно просто использовать GetConsoleScreenBufferInfo() для ввода нескольких пустых строк.

 

Code:

program Project1;

{$APPTYPE CONSOLE}

uses

Windows;

{$R *.RES}

var

sbi: TConsoleScreenBufferInfo;

i: integer;

begin

Writeln('A Console Applicaiton');

Writeln('Press Enter To Clear The Screen');

GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),

   sbi);

Readln;

GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),

   sbi);

for i := 0 to sbi.dwSize.y do

   writeln;

Writeln('Press Enter To End');

Readln;

end.

 

 

 

Я не профи в Win API, просто у меня возникла именно такая проблема. Я нашел решение устраивающее меня. И к тому же решил, поделился с вами. Если кому-то требуется что-то другое - дерзайте, я с удовольствием прочту на "Королевстве" что и как у вас получилось. Handle = Хэндл = Рукоятка :)

 Хочу предложить 2 способа:

 1) Простой, с использованием command.com /c имя_консольной_проги > имя_файла_куда_переназначить_StdOut

2) С использованием Win API (2 штуки)

Вы уж сами выберите, что вам подходит больше. Я использую способ № 2.2.

Рассмотрим их более подробно на примерах.

 

  

Вообще - я программист молодой, стаж - всего 2 года. И я никак не ожидал, что в век GDI мне придется возится с консолью... Ан нет, пришлось.

 Начал писать "движок" для собственного сайта. А именно - "Apache 1.x shared module" (dll - линкуется к Апачу и обрабатывает определенные адреса).

 Написал. Всего три сотни строк. НО умеет кучу всяких полезностей, типа вставлять на страницы данные из файлов (файл в файл), строки и, главное, данные из БД. Все это прекрасно. НО не умеет вставлять результаты работы других файлов (типа как CGI). Ну, думаю, надо сделать.

 Ага, а как? Вот тут то все и началось...

 Итак,

 ЗАДАЧА:

 запустить процесс (некий файл), передать ему команды и получить от него результаты работы. Вставить полученные результаты на страницу сайта. Причем в целях совместимости механизмы передачи данных ДОЛЖНЫ быть стандартными - StdIn, StdOut, StdErr.

 

Автор: Alex G. Fedorov 

Все настоящие программисты делятся на три категории: на тех, кто пишет программы, завершающиеся по нажатию F10, Alt-F4, Alt-X. Все остальные принципы деления надуманны. 

 Статья представляет собой изучение создания консольного приложения в Delphi. Прежде чем начать вникать в подробности, необходимо уточнить, что консольные приложения это особый вид Windows приложений - с одной стороны он имеет полный доступ к функциям Win API, с другой - не имеет графического интерфейса и выполняется в текстовом режиме.

 

 

Code:

unit consoleoutput;

 

interface

 

uses

Controls, Windows, SysUtils, Forms;

 

function GetDosOutput(const CommandLine:string): string;

 

implementation

 

function GetDosOutput(const CommandLine:string): string;

var

SA: TSecurityAttributes;

SI: TStartupInfo;

PI: TProcessInformation;

StdOutPipeRead, StdOutPipeWrite: THandle;

WasOK: Boolean;

Buffer: array[0..255] of Char;

BytesRead: Cardinal;

WorkDir, Line: String;

begin

Application.ProcessMessages;

with SA do

begin

   nLength := SizeOf(SA);

   bInheritHandle := True;

   lpSecurityDescriptor := nil;

end;

// создаём пайп для перенаправления стандартного вывода

CreatePipe(StdOutPipeRead,  // дескриптор чтения

            StdOutPipeWrite, // дескриптор записи

            @SA,              // аттрибуты безопасности

            0                // количество байт принятых для пайпа - 0 по умолчанию

            );

try

   // Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,

   // а так же проверяем, чтобы он не показывался на экране.

   with SI do

   begin

     FillChar(SI, SizeOf(SI), 0);

     cb := SizeOf(SI);

     dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

     wShowWindow := SW_HIDE;

     hStdInput := GetStdHandle(STD_INPUT_HANDLE); // стандартный ввод не перенаправляем

     hStdOutput := StdOutPipeWrite;

     hStdError := StdOutPipeWrite;

   end;

 

   // Запускаем компилятор из командной строки

   WorkDir := ExtractFilePath(CommandLine);

   WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);

 

   // Теперь, когда дескриптор получен, для безопасности закрываем запись.

   // Нам не нужно, чтобы произошло случайное чтение или запись.

   CloseHandle(StdOutPipeWrite);

   // если процесс может быть создан, то дескриптор, это его вывод

   if not WasOK then

     raise Exception.Create('Could not execute command line!')

   else

     try

       // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено

       Line := '';

       repeat

         // читаем блок символов (могут содержать возвраты каретки и переводы строки)

         WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

 

         // есть ли что-нибудь ещё для чтения?

         if BytesRead > 0 then

         begin

           // завершаем буфер PChar-ом

           Buffer[BytesRead] := #0;

           // добавляем буфер в общий вывод

           Line := Line + Buffer;

         end;

       until not WasOK or (BytesRead = 0);

       // ждём, пока завершится консольное приложение

       WaitForSingleObject(PI.hProcess, INFINITE);

     finally

       // Закрываем все оставшиеся дескрипторы

       CloseHandle(PI.hThread);

       CloseHandle(PI.hProcess);

     end;

finally

     result:=Line;

     CloseHandle(StdOutPipeRead);

end;

end;

 

 

end.

 

В следуещем примере используется функция Windows API FindWindow(). Обратите внимание, что WndClass консольного окна отличаются для Windows 95 и Window NT и заголовок окна может содержать полный путь под Windows NT.

 

Каким образом организовать ожидание завершения DOS-задачи? Например, надо подождать, пока заархивируется файл, и далее обработать его.

 

Code:

uses Windows;

 

procedure RunRarAndWait;

var

si: TStartupInfo;

pi: TProcessInformation;

begin

//подготовливаем записи si и pi к использованию

FillChar(si, SizeOf(si));

si.cb := SizeOf(si);

FillChar(pi, SizeOf(pi));

//попытаемся запустить рар

if CreateProcess('rar.exe', 'parameters',

nil, nil, //безопасность по умолчанию

false,    //не наследовать хэндлов

0,        //флаги создания по умолчанию

nil,      //переменные среды по умолчанию

nil,      //текущая директория по умолчанию

si,       //стартовая информация

pi)       //а в эту запись получим информацию о созданом процессе

then

begin

   //удалось запустить рар

   //подождем пока рар работает

   WaitForSingleObject(pi.hProcess, INFINITE);

   //убираем мусор

   CloseHandle(pi.hProcess);

   CloseHandle(pi.hThread);

end

else

   //выдаем сообщение об ощибке

   MessageDlg(SysErrorMessage(GetLastError), mtError, [mbOK], 0);

end;

 

 

Code:

procedure TForm1.Button1Click(Sender: TObject);

var

h: HWND;

AIcon: TIcon;

begin

AllocConsole;

SetConsoleTitle(PChar('Console Title'));

Sleep(0);

h := FindWindow(nil, PChar('Console Title'));

AIcon := TIcon.Create;

ImageList1.GetIcon(0, AIcon);

SendMessage(h, WM_SETICON, 1, AIcon.Handle);

AIcon.Free;

end;

 

{----------------------------CreateDOSProcessRedirected---------------------------

Description    : executes a (DOS!) app defined in the CommandLine parameter redirected

                 to take input from InputFile and give output to OutputFile

Result         : True on success

Parameters     :

                 CommandLine : the command line for the app, including its full path

                 InputFile   : the ascii file where from the app takes input

                 OutputFile  : the ascii file to which the app's output is redirected

                 ErrMsg      : additional error message string. Can be empty

Error checking : YES

Target         : Delphi 2, 3, 4

Author         : Theodoros Bebekis, email Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

Notes          :

Example call   : CreateDOSProcessRedirected('C:\MyDOSApp.exe',

                                            'C:\InputPut.txt',

                                            'C:\OutPut.txt',

                                            'Please, record this message')

-----------------------------------------------------------------------------------}

 

Это не документированные возможности создания полноэкранных консольных приложений. 

В данном случае использованы недокументированные функции SetConsoleDisplayMode и    GetConsoleDisplayMode.

С периодичностью раз в месяц-полтора конференция RU.DELPHI оглашается стонами на тему “Консоль не поет по-русски”, за которыми стоит вывод текста в консольных приложениях в кодировке OEM (Delphi IDE, как и все GUI, работает в ANSI).

 

С точки зрения набора символов эти кодовых таблицы не совпадают: позиции символов кириллицы в них различны (отсюда и неприятные эффекты), кроме того, в ANSI присутствуют диакритические символы, которых нет в OEM, но в последней имеются символы псевдографики, незаменимые при изображении таблиц (интересно, это еще кем-то востребовано? На ум приходит только FAR). Впрочем, возможности для вывода текстовой информации у этих таблиц одинаковы, что в нашем случае позволяет говорить о взаимозаменяемости.