Цикл сообщения темы висит в Delphi - PullRequest
5 голосов
/ 22 марта 2010

У меня есть простая программа на Delphi, над которой я работаю, в которой я пытаюсь использовать многопоточность, чтобы отделить функциональность программы от ее графического интерфейса, и чтобы графический интерфейс реагировал на более длительные задачи и т. Д. В основном,У меня есть TThread «контроллера» и TForm «view».Представление знает дескриптор контроллера, который он использует для отправки сообщений контроллера через PostThreadMessage.В прошлом у меня не было проблем с использованием такого рода модели для форм, которые не являются основной формой, но по какой-то причине, когда я пытаюсь использовать эту модель для основной формы, цикл сообщений потока просто завершается.

Вот мой код для цикла сообщений темы:

procedure TController.Execute;
var
  Msg : TMsg;
begin
  while not Terminated do begin
    if (Integer(GetMessage(Msg, hwnd(0), 0, 0)) = -1) then begin
      Synchronize(Terminate);
    end;

    TranslateMessage(Msg);
    DispatchMessage(Msg);

    case Msg.message of
      // ...call different methods based on message
    end;
  end;
end;

Чтобы настроить контроллер, я делаю это:

Controller := TController.Create(true); // Create suspended
Controller.FreeOnTerminate := True;
Controller.Resume;

Для обработки сообщений основной формы яЯ пытался использовать и Application.Run, и следующий цикл (сразу после Controller.Resume)

while not Application.Terminated do begin
  Application.ProcessMessages;
end;

Я тут застрял - любая помощь будет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 23 марта 2010

Я тестировал ваш код в основном как есть, и он работал нормально.Попробуйте добавить вызов GetLastError после того, как GetMessage вернет -1, чтобы увидеть, в чем проблема.

Из кода не совсем ясно, создаете ли вы окна в потоке контроллера, но если нет, я бы предложилПередавая -1 вместо 0 в качестве HWND в GetMessage, и удалите вызовы TranslateMessage / DispatchMessage, так как оператор case, который следует за ними, должен обрабатывать все полученные сообщения.Синхронизировать (завершить) "при ошибке.Terminate просто устанавливает для логического значения «Termination» значение true, поэтому вам не нужно синхронизировать его, и вы можете с легкостью использовать «Break» для выхода из цикла с тем же эффектом.

0 голосов
/ 23 марта 2010

Где находится «конец» цикла while? Я думаю, что ты пропал и конец. Так что, возможно (в зависимости от фактического кода), вы застряли в цикле while not Terminated do бесконечно за одним оператором.

...