模式窗体无法关闭



我有一个显示长操作进度的模态表单。当表单的OnActivate事件被触发时,该操作被触发。

procedure TMyForm.FormActivate(Sender:TObject);
begin
  Start;
end;

表单有一个取消按钮,ModalResult属性设置为mrCancel,OnClick处理程序设置一个导致操作结束的标志。

procedure TMyForm.CancelButtonClick(Sender: TObject);
begin
  FCancel := True;
end;

当我单击取消按钮时,它会按预期停止操作,但无法关闭表单。我怀疑这是因为OnActivate处理程序阻止了表单关闭。第二次点击按钮确实关闭了表单。我试着调用close并发送了一条wm_close消息,但似乎什么都不起作用。有人有什么建议可以让表格在第一次点击时做出回应吗?也许我可以使用另一个事件来代替OnActivate?

我知道会建议将操作转移到线程。由于大量的遗留代码写得不好,这在目前是不可能的。

在下文中,我将假设消息可能是通过在任务中调用Application.ProcessMessages来处理的。

让我们来看看相关的代码ShowModal

SendMessage(Handle, CM_ACTIVATE, 0, 0);
ModalResult := 0;
repeat
  Application.HandleMessage;
  if Application.Terminated then ModalResult := mrCancel else
    if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;

SendMessage调用导致OnActivate事件触发。在您的代码中,然后启动任务,直到任务完成才返回。您已指定给ModalResult的时间点。但是等一下,上面摘录的下一行将ModalResult设置回0,因此您的设置将丢失。因此,进入了模式消息循环,您需要再次分配给ModalResult以关闭表单。

这里的底线是,在进入模式消息循环之前不能执行任务。一种解决方案是将长时间运行的任务放在一个单独的线程中。如果您无法做到这一点,可以在OnActivate事件处理程序中向表单发布消息。通过启动任务来响应事件。此时,模式消息循环将运行,设置ModalResult将关闭表单。

相关内容

  • 没有找到相关文章

最新更新