Delphi中MDI子窗口关闭或应用程序退出时,'OnCloseQuery'触发,如何追踪其触发原因?

2026-04-10 01:561阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计517个文字,预计阅读时间需要3分钟。

Delphi中MDI子窗口关闭或应用程序退出时,'OnCloseQuery'触发,如何追踪其触发原因?

我目前正在开发一个MDI应用程序。每次创建新的MDI子窗口时,其基础数据都会动态保存在SQLite数据库中。同时,打开的序列设置默认为1,这样如果用户关闭程序并重新打开,则窗口会自动恢复(以防止重复)。

我目前正在开发一个MDI应用程序.
每次创建新的MDI子窗口时,它的基础数据都会动态保存到SQLite数据库,并且打开的列设置为1,因此如果用户关闭程序并重新打开它,则会恢复窗口(以防万一) of Anything BadTM).
因此,每个文档始终存在于数据库中 – 如果用户单击“保存”,则唯一发生的事情是将持久性列设置为1.
现在,如果关闭MDI子窗口,则将open设置为0 – 并且持久性= 0 AND open = 0的每一行都将注定失败并将被删除.

由于这种行为,我不需要问“保存文件?”在ApplicationClose上.
但每次MDI子窗口关闭时我都需要询问.
如果在MDIChild.OnCloseQuery之前调用Mainform.OnCloseQuery,那将很容易做到,但遗憾的是情况并非如此.

把它们加起来:
我需要一种方法来了解是否调用了MDIChild.OnCloseQuery

>应用程序正在关闭,或
> MDI子窗口正在关闭.

有没有办法做到这一点?

您需要在主窗体中覆盖受保护的虚方法CloseQuery.当它触发时你知道应用程序正在关闭.但是,在主窗体上触发OnCloseQuery事件之前,继承的实现会在MDI子节点上调用CloseQuery.

这是CloseQuery的TCustomForm实现:

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子项在Self之前获得了CloseQuery通知,即主表单.

因此,在您的主要表单中,您需要:

type TMainForm = class(TForm); private FCloseQueryExecuting: Boolean; protected function CloseQuery: Boolean; override; public property CloseQueryExecuting: Boolean read FCloseQueryExecuting; end;

然后是一个看起来像这样的实现:

Delphi中MDI子窗口关闭或应用程序退出时,'OnCloseQuery'触发,如何追踪其触发原因?

function TMainForm.CloseQuery: Boolean; begin FCloseQueryExecuting := True; try Result := inherited CloseQuery; finally FCloseQueryExecuting := False; end; end;

然后,MDI子项可以在其OnCloseQuery事件中检查主窗体的FCloseQueryExecuting属性的状态.

本文共计517个文字,预计阅读时间需要3分钟。

Delphi中MDI子窗口关闭或应用程序退出时,'OnCloseQuery'触发,如何追踪其触发原因?

我目前正在开发一个MDI应用程序。每次创建新的MDI子窗口时,其基础数据都会动态保存在SQLite数据库中。同时,打开的序列设置默认为1,这样如果用户关闭程序并重新打开,则窗口会自动恢复(以防止重复)。

我目前正在开发一个MDI应用程序.
每次创建新的MDI子窗口时,它的基础数据都会动态保存到SQLite数据库,并且打开的列设置为1,因此如果用户关闭程序并重新打开它,则会恢复窗口(以防万一) of Anything BadTM).
因此,每个文档始终存在于数据库中 – 如果用户单击“保存”,则唯一发生的事情是将持久性列设置为1.
现在,如果关闭MDI子窗口,则将open设置为0 – 并且持久性= 0 AND open = 0的每一行都将注定失败并将被删除.

由于这种行为,我不需要问“保存文件?”在ApplicationClose上.
但每次MDI子窗口关闭时我都需要询问.
如果在MDIChild.OnCloseQuery之前调用Mainform.OnCloseQuery,那将很容易做到,但遗憾的是情况并非如此.

把它们加起来:
我需要一种方法来了解是否调用了MDIChild.OnCloseQuery

>应用程序正在关闭,或
> MDI子窗口正在关闭.

有没有办法做到这一点?

您需要在主窗体中覆盖受保护的虚方法CloseQuery.当它触发时你知道应用程序正在关闭.但是,在主窗体上触发OnCloseQuery事件之前,继承的实现会在MDI子节点上调用CloseQuery.

这是CloseQuery的TCustomForm实现:

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子项在Self之前获得了CloseQuery通知,即主表单.

因此,在您的主要表单中,您需要:

type TMainForm = class(TForm); private FCloseQueryExecuting: Boolean; protected function CloseQuery: Boolean; override; public property CloseQueryExecuting: Boolean read FCloseQueryExecuting; end;

然后是一个看起来像这样的实现:

Delphi中MDI子窗口关闭或应用程序退出时,'OnCloseQuery'触发,如何追踪其触发原因?

function TMainForm.CloseQuery: Boolean; begin FCloseQueryExecuting := True; try Result := inherited CloseQuery; finally FCloseQueryExecuting := False; end; end;

然后,MDI子项可以在其OnCloseQuery事件中检查主窗体的FCloseQueryExecuting属性的状态.