Показать сообщение отдельно
  #3  
Старый 05.05.2020, 10:42
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

С одного старого проекта вырезка:

Код:
  PThreadParams = ^TThreadParams;

  TThreadParams = record // параметры, передаваемые в поток
    Wnd: HWND;  // окно, получающее сообщения из потока
    Num: TChapterNumber; // номер запускаемой лекции
  end;

function LectureThreadProc(p: Pointer): DWORD; stdcall; // функция потока
var
  Buffer: array[0..1023] of Char;
  tmp_filename, app_filename: string;
  stream: TResourceStream;
  lpHandles: array[0..1] of THandle;
  fe_res: Integer;
  SInfo: TStartupInfo;
  PInfo: TProcessInformation;
begin
  PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_RUN, 0); // отправляем окну сообщение о старте потока

  tmp_filename := Format(LECTURE_FORMAT_FILE, [TMPpath, PThreadParams(p)^.Num]);  // формируем имя временного файла

  stream := TResourceStream.Create(HInstance, Format(LECTURE_FORMAT_RESOURCE, [PThreadParams(p)^.Num]), RT_RCDATA);  // из ресурсов загружаем нужную лекцию
  stream.SaveToFile(tmp_filename); // сохраняем в папу Temp
  stream.Free;

  fe_res := FindExecutable(PChar(tmp_filename), nil, Buffer);  // ищем приложение отображения презентаций
  if fe_res > 32 then  // если нашли, то...
  begin
    app_filename := PChar(@Buffer);
    FillChar(SInfo, SizeOf(SInfo), 0);
    SInfo.wShowWindow := SW_SHOWNORMAL;
    SInfo.cb := SizeOf(SInfo);
    if CreateProcess(nil, PChar(Format('"%s" "%s"', [app_filename, tmp_filename])), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, SInfo, PInfo) then // создаем процесс с параметрами
    begin
      lpHandles[1] := PInfo.hProcess;
      lpHandles[0] := LectureThreadCloseEvent;
// ожидаем завершение процесса или сигнала о принудительном завершении
      if WaitForMultipleObjects(2, @lpHandles, False, INFINITE) = WAIT_OBJECT_0 then  // принудительно завершаем процесс
        TerminateProcess(PInfo.hProcess, 0);
  //  подчищаем за собой
      CloseHandle(PInfo.hThread);
      CloseHandle(PInfo.hProcess);
    end
    else  // уведомляем окно об ошибке запуска процесса
      PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_ERROR, lPROC_ERROR);
  end
  else
    PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_ERROR, lAPP_ERROR);  // окно об ошибке (не найдено приложение для отображения презентации)

  Windows.DeleteFile(PChar(tmp_filename)); // удаляем временный файл
  PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_CLOSE, 0);  // уведомляем окно о завершении потока
  Result := 0;
  ExitThread(Result);
end;

Запуск потока:
Код:
procedure TMainForm._StartLecture(Number: TChapterNumber);
var
  id: DWORD;
begin
  LectureThreadParams.Wnd := Self.Handle;  // задаем параметры потока
  LectureThreadParams.Num := Number;
  ResetEvent(LectureThreadCloseEvent); // сбрасываем событие принудительного завершения потока
  LectureThreadhandle := CreateThread(nil, 0, @LectureThreadProc, @LectureThreadParams, 0, id);  // запускаем поток
end;

Программа запускала презентацию из ресурсов и ожидала завершения, отображая анимацию.
Не забывайте подчищать за собой.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием