У меня есть простая программа Delphi, что я продолжаю работать, в котором я пытаюсь использовать поточную обработку, чтобы разделить функциональность программы от ее GUI и сохранить GUI быстро реагирующим во время более долгих задач, и т.д. В основном у меня есть 'контроллер' TThread и 'представление' TForm. Представление знает дескриптор контроллера, который оно использует для отправки сообщений контроллера через 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;
Я работал застрявший сюда - любая справка значительно ценилась бы.
Я тестировал ваш код как есть, и он работал нормально. Попробуйте добавить вызов GetLastError после того, как GetMessage вернет -1, чтобы узнать, в чем проблема.
Из кода не совсем понятно, создаете ли вы окна в потоке контроллера, но если нет, я бы предложил передать -1 вместо 0 в качестве HWND для GetMessage и удалить вызовы TranslateMessage / DispatchMessage, поскольку оператор case, который следует за ними, должен обрабатывать все получаемые вами сообщения.
Кроме того, вам не нужно выполнять команду «Синхронизировать (завершить)» в случае ошибки. Terminate просто устанавливает для логического «Terminated» значение true, поэтому вам не нужно его синхронизировать, и вы можете так же легко использовать «Break» для выхода из цикла с тем же эффектом.
Где "конец" для цикла while?
Я думаю, что вам не хватает конца. Так что, возможно (в зависимости от фактического кода), вы застряли в while not Terminated do
бесконечном цикле на одном операторе.