我正在处理一个简单的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;
我已经被困在这里 - 任何帮助将不胜感激。
答案 0 :(得分:3)
我基本上按原样测试了你的代码,它运行正常。尝试在GetMessage返回-1后添加对GetLastError的调用,以查看问题所在。
代码中是否在控制器线程中创建窗口并不完全清楚,但如果没有,我建议将-1而不是0作为HWND传递给GetMessage,并删除TranslateMessage / DispatchMessage调用,因为在它们之后的case语句应该处理你收到的任何消息。
此外,您不需要对错误执行“同步(终止)”。 Terminate只是将“Terminated”布尔值设置为true,因此您不需要同步它,您也可以轻松地使用“Break”来打破循环,效果相同。
答案 1 :(得分:0)
while循环的“结束”在哪里?
我想你会失踪并结束。所以也许(取决于实际的代码),你在一个声明中无休止地陷入while not Terminated do
循环。