Добрый день. Вот и я с вопросом решил обратиться.
Что нужно:
1. Из программы запустить презентацию.
2. Дождаться её завершения.
3. Информировать пользователь я ходе презентации (об ожидании закрытия презентации).
С запуском и ожиданием проблем нет. Проблема с продолжением работы программы после закрытия презентации.
Код:
function LectureThreadProc(p: Pointer): DWORD; stdcall;
var
sei: TShellExecuteInfo;
Buffer: array[0..1023] of Char;
tmp_str: string;
stream: TResourceStream;
lpHandles: array[0..1] of THandle;
begin
SetString(tmp_str, Buffer, GetTempPath(Sizeof(Buffer) - 1, Buffer));
tmp_str := Format(LECTURE_FORMAT_FILE, [tmp_str, PThreadParams(p)^.Num]);
stream := TResourceStream.Create(HInstance, Format(LECTURE_FORMAT_RESOURCE, [PThreadParams(p)^.Num]), RT_RCDATA);
stream.SaveToFile(tmp_str);
stream.Free;
ZeroMemory(@sei, SizeOf(sei));
sei.cbSize := SizeOf(sei);
sei.lpFile := PChar(tmp_str);
sei.nShow := SW_SHOWNORMAL;
sei.fMask := SEE_MASK_NOCLOSEPROCESS;
if ShellExecuteEx(@sei) then
begin
lpHandles[1] := sei.hProcess;
lpHandles[0] := LectureThreadCloseEvent;
case WaitForMultipleObjects(2, @lpHandles, False, INFINITE) of
WAIT_OBJECT_0:
begin
TerminateProcess(sei.hProcess, 0);
CloseHandle(sei.hProcess);
end;
WAIT_OBJECT_0 + 1:
begin
CloseHandle(sei.hProcess);
EnterCriticalSection(LectureThreadCS);
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_CLOSE, 0, 0);
LeaveCriticalSection(LectureThreadCS);
end;
end;
end;
Windows.DeleteFile(PChar(tmp_str));
Result := 0;
ExitThread(Result);
end;
procedure TMainForm._StartLecture(Number: TChapterNumber);
var
id: DWORD;
begin
LectureThreadParams.Wnd := Self.Handle;
LectureThreadParams.Num := Number;
LectureThreadhandle := CreateThread(nil, 0, @LectureThreadProc, @LectureThreadParams, 0, id);
Application.Minimize;
end;
procedure TMainForm.WMLectureClose(var Message: TMessage);
begin
WaitForSingleObject(LectureThreadHandle, INFINITE);
CloseHandle(LectureThreadHandle);
LectureThreadHandle := INVALID_HANDLE_VALUE;
Application.Restore;
end;
все отрабатывает на отлично. Но программа встает колом (не всегда, иногда с 10 запуска потока, иногда со второго). Зависание происходит на строчке:
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_CLOSE, 0, 0);
Причем программа не реанимируется, только жесткое завершение процесса. Если запуска из под ID, то только перезапуск IDE.
Уже и секцию критическую добавил и SendMessage заменил на PostMessage. И Тырнет перерыл.
Сталкивался кто? Какие еще есть варианты отправить сообщение форме по завершению потока?
P.S. Погонял еще. Часто зависает еще до запуска презентации. IDE выдает "External exception EEFFACE". Ну а потом среда отваливается от программы и требует перезапуска.
P.P.S. Без PostMessage работает как часы.