Отправляет email-рассылки с помощью сервиса Sendsay

Советы по Delphi

  Все выпуски  

Советы по Delphi


Служба Рассылок Subscribe.Ru

Здравствуйте, уважаемые подписчики! Сегодня поговорим о том, как запустить из Вашей программы еще какую-нибудь программу и дождаться ее закрытия. Для удобства сразу оговорюсь: Ваша программа - это программа, код которой здесь приведен. Другая программа - программа, которая была запущена из Вашей. Для запуска другой программы мы будем использовать функцию CreateProcess, поскольку она возвращает handle созданного процесса. Для ожидания завершения процесса (программы) нужно вызвать WaitForSingleObject. Эта функция будет "выполняться", пока процесс не завершиться. Но с этим связана одна проблема. Ваша программа остановится и перестанет что-либо делать, даже окно не сможет перерисоваться. Чтобы решить эту проблему, Вашу программу можно убирать с экрана. А можно заставить функцию WaitForSingleObject периодически прекращать выполняться. Для этого в качестве второго параметра нужно указать время в миллисекундах, которое будет выполняться функция. Если по истечению этого срока процесс не будет завершен, функция возвратит WAIT_TIMEOUT.

В этом примере функция ExecuteAndWait запускает другую программу (имя запускаемого файла - FileName). Если HideApplication установлен в true, то Ваша программа исчезает на время выполнения другой программы. В противном случае Ваша программа остается на экране и каждые 0.1 сек. будут выполняться все задачи, которые накопились в очереди (Application.ProcessMessages). А если пользователь решит закрыть Вашу программу - закроется и другая программа. Процедура SetEnabled устанавливает Enabled всех компонентов на форме в false. Может быть здесь это и не очень уместно - так когда-нибудь пригодится.

function ExecuteAndWait(FileName: string; HideApplication: boolean): boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  exitc: cardinal;
begin
  FillChar(StartupInfo, sizeof(StartupInfo), 0);
  with StartupInfo do begin
    cb := Sizeof(StartupInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := SW_SHOW;
  end;
  if not CreateProcess(nil, PChar(FileName), nil, nil, false,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,
    StartupInfo, ProcessInfo) then result := false
  else begin
    if HideApplication then begin
      Application.Minimize;
      ShowWindow(Application.Handle, SW_HIDE);
      WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
    end else
      while WaitforSingleObject(ProcessInfo.hProcess, 100) =
        WAIT_TIMEOUT do begin
        Application.ProcessMessages;
        if Application.Terminated
          then TerminateProcess(ProcessInfo.hProcess, 0);
      end;
    GetExitCodeProcess(ProcessInfo.hProcess, exitc);
    result := (exitc = 0);
    if HideApplication then begin
      ShowWindow(Application.Handle, SW_SHOW);
      Application.Restore;
      Application.BringToFront;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
  procedure SetEnabled(en: boolean);
  var
    i: integer;
  begin
    for i := 0 to Form1.ComponentCount - 1 do
      if Form1.Components[i] is TControl then
        (Form1.Components[i] as TControl).Enabled := en;
  end;
begin
  SetEnabled(false);
  if not ExecuteAndWait(Edit1.Text, CheckBox1.Checked)
    then ShowMessage('Возникли какие-то проблемы');
  SetEnabled(true);
end;


Полезные мелочи
Функции Delphi ParamCount и ParamStr работают неверно, поскольку пробел они считают разделителем параметров, а пробел может содержаться, например, в названии файла. Этой ошибки не происходит, если в начале и в конце параметра стоят кавычки. А еще можно воспользоваться переменной CmdLine. В ней хранится командная строка со всеми параметрами без каких-либо изменений. Пример:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.Caption := CmdLine;
end;


Все советы и замечания, пожалуйста, присылайте на delphi4all@narod.ru

Всего доброго,
Даниил Карапетян.






http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу
Рейтингуется SpyLog

В избранное