如何在Delphi中的TFrame上模拟OnDestroy事件? [英] How to simulate an OnDestroy event on a TFrame in Delphi?
问题描述
如何在Delphi中为TFrame
模拟OnDestroy
事件?
How can i simulate an OnDestroy
event for a TFrame
in Delphi?
我认真地在框架中添加了constructor
和destructor
,以为TForm
会这样做:
i nievely added a constructor
and destructor
to my frame, thinking that is what TForm
does:
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;
问题是当我的析构函数运行时,框架上的控件已被破坏并且不再有效.
The problem with this is that by the time my destructor runs, controls on the frame have been destroyed and are no longer valid.
其原因在于包含窗体的析构函数,该析构函数用于引发OnDestroy
事件:
The reason for this is in the containing form's destructor, which it uses to fire an OnDestroy
event:
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销毁表单的窗口句柄.这会递归地破坏所有子窗口-包括我框架中的子窗口.
The destructor of my frame object is being called when the form's destructor runs. Problem with this is that it's too late. The form calls DestroyWindowHandle
, which asks Windows to destroy the form's window handle. This recursively destroys all child windows - including those on my frame.
因此,当我的框架的destructor
运行时,我尝试访问不再处于有效状态的控件.
So when my frame's destructor
runs, i attempt to access controls that are no longer in a valid state.
如何在Delphi中为TFrame
模拟OnDestroy
事件?
How can i simulate an OnDestroy
event for a TFrame
in Delphi?
- 为框架模拟OnCreate和OnDestroy吗?
- 如何为Delphi TFrame对象实现OnCreate事件
- Embargadero QC#1767:TFrame缺少OnCreate,OnDestroy,OnShow
- 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,以便仅在实际销毁时才捕获它,而在重新创建句柄时才捕获它.
You need to add a WM_DESTROY handler and check for csDestroying in the ComponentState so it's only caught when actually destroying, and not when recreating the handle.
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中设置一个标志,如果未命中,则应在析构函数中调用它.
That will only work if the frame's window handle has actually been created. There isn't another good hook point, so if you want to ensure it's always called you'll need to set a flag in WMDestroy and fall back to calling it in the destructor if that isn't hit.
窗口句柄本身全部在WM_NCDESTROY中清除,在所有后代WM_DESTROY消息返回之后调用该窗口句柄,因此该窗体及其所有子句柄在这一点上仍然有效(忽略任何在WM_DESTROY消息中释放的句柄).表单的OnDestroy).
The window handles themselves are all cleared in WM_NCDESTROY, which is called after all of the descendant WM_DESTROY messages return, so the form and all of its childens' handles should still be valid at this point (ignoring any that were freed in the form's OnDestroy).
这篇关于如何在Delphi中的TFrame上模拟OnDestroy事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!