微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Delphi中模拟TFrame上的OnDestroy事件?

如何在Delphi中为TFrame模拟OnDestroy事件?

我简单地在我的框架中添加一个构造函数和析构函数,认为这就是TForm的作用:

TframeEditCustomer = class(TFrame)
...
public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   ...
end;

constructor TframeEditCustomer.Create(AOwner: TComponent)
begin
    inherited Create(AOwner);

    //allocate stuff
end;

destructor TframeEditCustomer.Destroy;
begin
   //cleanup stuff

   inherited Destroy;
end;

这个问题是,当我的析构函数运行时,框架上的控件已经被破坏并且不再有效.

原因在于包含表单的析构函数,它用于触发OnDestroy事件:

destructor TCustomForm.Destroy;
begin
   ...
   if OldCreateOrder then DoDestroy; //-->fires Form's OnDestroy event; while controls are still valid
   ...
   if HandleAllocated then DestroyWindowHandle; //-->destroys all controls on the form,and child frames
   ...
   inherited Destroy; //--> calls destructor of my frame
   ...
end;

当表单的析构函数运行时,我的框架对象的析构函数调用.问题是,为时已晚.该表单调用DestroyWindowHandle,它要求Windows销毁表单的窗口句柄.这会递归地破坏所有子窗口 – 包括我框架上的窗口.

因此,当我的框架的析构函数运行时,我尝试访问不再处于有效状态的控件.

如何在Delphi中为TFrame模拟OnDestroy事件?

也可以看看

> Simulating OnCreate and OnDestroy for a Frame?
> How to Implement the OnCreate event for a Delphi TFrame object
> Embargadero QC#1767: TFrame misses OnCreate,OnDestroy,OnShow

解决方法

您需要添加WM_DESTROY处理程序并检查ComponentState中的csDestroying,以便它仅在实际销毁时捕获,而不是在重新创建句柄时捕获.
type
  TCpFrame = class(TFrame)
  private
    FOnDestroy: TNotifyEvent;
    procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
  published
    property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy;
  end;

procedure TCpFrame.WMDestroy(var Msg: TWMDestroy);
begin
  if (csDestroying in ComponentState) and Assigned(FOnDestroy) then
    FOnDestroy(Self);
  inherited; 
end;

这只有在实际创建了框架的窗口句柄时才有效.没有其他好的挂钩点,所以如果你想确保它总是被调用,你需要在WMDestroy中设置一个标志,如果没有被击中则回退到在析构函数调用它.

窗口句柄本身都在WM_NCDESTROY中被清除,WM_NCDESTROY在所有后代WM_DESTROY消息返回后被调用,因此表单及其所有childens的句柄在此时仍然有效(忽略在表单的OnDestroy中释放的任何内容) .

原文地址:https://www.jb51.cc/delphi/239399.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐