【问题标题】:How do I get MDIMain form to get application close message before mdichild forms如何在 mdi 子表单之前获取 MDI 主表单以获取应用程序关闭消息
【发布时间】:2017-03-03 03:18:52
【问题描述】:

我们的应用程序使用“MDI”(大多数问题已在 TForm 后裔中得到解决)。在大多数表单中,如果数据已更改,则它拒绝关闭(使用 closequery)并告诉用户保存或取消。这工作得很好。

但与其他人不同,如果应用程序正在死去,我想跳过这个。这可能是因为用户单击了 MainForm 上的 X。我只是希望应用程序死掉 - 不保存数据等。

问题是 MainForm 的 CloseQuery 在所有 mdichild 表单之后触发。我在 MainForm 中尝试过 wm_close、wm_quit 甚至是 windproc。但他们没有及时开火。

当我在 mdichild 中获得 formclosequery 时,我无法知道该表单是被用户杀死还是被杀死的应用程序。

当然有一种简单的方法可以做到这一点。我错过了什么?

【问题讨论】:

  • 你能在主窗体中展示你如何处理 WM_CLOSE
  • @ken 它是 MS,后向兼容性为王,一如既往地工作,耳语它,但我的应用程序是 mdi.....
  • @David:是的,我知道。你最后没看到 ;-) 吗?
  • 点击MainForm的X会先通知MainForm,然后再通知它的子表单。如果您在处理WndProc() 中的初始通知时遇到问题,那么您可能没有正确处理它。请出示您的实际代码。
  • 这似乎是客户要求的一种奇怪行为。你确定你理解正确吗?

标签: delphi windows-10 mdi formclosing


【解决方案1】:

这种行为的解释可以在TCustomForm.CloseQuery的实现中找到,看起来是这样的:

function TCustomForm.CloseQuery: Boolean;
var
  I: Integer;
begin
  if FormStyle = fsMDIForm then
  begin
    Result := False;
    for I := 0 to MDIChildCount - 1 do
      if not MDIChildren[I].CloseQuery then Exit;
  end;
  Result := True;
  if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end;

代码对每个 MDI 子级调用 CloseQuery,这会触发附加到 MDI 子级的任何 OnCloseQuery 事件,然后为主 MDI 窗体触发 OnCloseQuery 事件。

因此,您只需在主 MDI 表单中覆盖 CloseQuery 并采取措施抢占此行为,即可自行处理。

例如,您可以在主窗体中执行此操作:

// in the form type declaration:
function CloseQuery: Boolean; override;

// in the implementation section:
function TMainForm.CloseQuery: Boolean;
begin
  Result := True;
  if Assigned(OnCloseQuery) then OnCloseQuery(Self, Result);
end;

或者可能是这样的:

function TMainForm.CloseQuery: Boolean;
begin
  while MDIChildCount > 0 do
    MDIChildren[0].Free;
  inherited;
end;

甚至:

function TMainForm.CloseQuery: Boolean;
begin
  Application.Halt;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多