5

我正在开发一个简单的 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;

我被困在这里 - 任何帮助将不胜感激。

4

2 回答 2

3

我基本上按原样测试了您的代码,并且运行良好。尝试在 GetMessage 返回 -1 后添加对 GetLastError 的调用以查看问题所在。

从代码中不能完全清楚您是否在控制器线程中创建窗口,但如果不是,我建议将 -1 而不是 0 作为 HWND 传递给 GetMessage,并删除 TranslateMessage/DispatchMessage 调用,因为 case 语句紧随其后的应该处理您收到的任何消息。

此外,您不需要对错误执行“同步(终止)”。Terminate 只是将“Terminated”布尔值设置为 true,因此您不需要同步它,您可以轻松地使用“Break”以相同的效果跳出循环。

于 2010-03-22T21:37:19.620 回答
0

while 循环的“结束”在哪里?我想你失踪了,结束了。因此,也许(取决于实际代码),您在while not Terminated do单个语句上无休止地陷入循环。

于 2010-03-22T21:00:31.943 回答