С одного старого проекта вырезка:
Код:
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% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
|