Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 18.05.2016, 15:00
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию CreateThread, SendMessage/PostMessage

Добрый день. Вот и я с вопросом решил обратиться.
Что нужно:
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 работает как часы.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.

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

Все-таки проблема не в отправке сообщений, а в ShellExecuteEx. Почему-то иногда вылетает ошибка "External exception EEFFACE" и все встает колом. Закономерности не нашел.

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

В общем-то проблема не нова. Интернет-сообщества "жалуются" на ShellExecute. А решение предложено одно - использовать CreateProcess.
С этим все получилось.

Сам с собой поговорил Тему можно закрыть.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #4  
Старый 19.05.2016, 16:53
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, у меня вчера вообще что-то форум не работал...
По поводу ShellExecute. Где-то на просторх MSDN это написано. ShellExecute(Ex) лучше всего использовать для того, что бы запустить процесс и "бросить" его. Собственно, ShellRxrcute это обертка над CreateProcess, которая, с одной стороны, добавляет возможности запуска "через реестр" (по типу файла), с другой стороны не имеет всех тех возможностей, что CreateProcess.

Кстати, вот еще один момент:
Цитата:
Сообщение от MSDN
Remarks

Because ShellExecuteEx can delegate execution to Shell extensions (data sources, context menu handlers, verb implementations) that are activated using Component Object Model (COM), COM should be initialized before ShellExecuteEx is called. Some Shell extensions require the COM single-threaded apartment (STA) type. In that case, COM should be initialized as shown here:
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:52.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter