这已经在这里讨论过了,但没有详细讨论.
我试图让非模态子表单自身关闭时遇到麻烦.我让它通知父母,但我得到了抽象错误和其他异常.我究竟做错了什么?父母是否必须释放非模态形式,或者永远不再尝试通过该变量访问它?
主要形式:
NonModal := NonModalTForm.Create(Self);
NonModal.Callback := Callback;
NonModal.Show;
Procedure TForm.Callback; // called by non-modal form when closing
begin
FreeAndNil(NonModal); // or should this just be NonModal := nil so I don't try to access a dangling pointer?
end;
Run Code Online (Sandbox Code Playgroud)
在NonModal.pas
procedure NonModalTForm.FormClose;
begin
Callback; // calls parent
end;
Run Code Online (Sandbox Code Playgroud)
ska*_*adt 11
您调用close从FormClose事件以外的其他位置关闭您的表单.在FormClose事件中,只需将Action设置为等于以下之一:
caFree - 完全处理表格caMinimize - 最小化表格caHide - 隐藏表格caNone - 忽略关闭例如:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
Run Code Online (Sandbox Code Playgroud)
如果要稍后显示窗口,请使用"隐藏".
如果要关闭它,请使用关闭.(关闭主窗口,关闭应用程序).Close的确切操作取决于表单参数.
查看关闭源:
procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then begin
if FormStyle = fsMDIChild then
if biMinimize in BorderIcons then
CloseAction := caMinimize
else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then
Application.Terminate
else if CloseAction = caHide then
Hide
else if CloseAction = caMinimize then
WindowState := wsMinimized
else
Release;
end;
end;
Run Code Online (Sandbox Code Playgroud)
但要小心免费.Windows窗口队列中可能会有一些消息可能导致崩溃.更好地使用Release来清理窗口.因为这会在释放之前等待消息.
VCL已经有一种机制,可以在释放其他组件时通知组件.你可以这样使用它;
type
TfrmParent = class(TForm)
btnShowChild: TButton;
procedure btnShowChildClick(Sender: TObject);
private
FChild: TfrmChild;
public
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
end;
procedure TfrmParent.btnShowChildClick(Sender: TObject);
begin
// Check status of child
if FChild = nil then
begin
// Child does not exist, create it
FChild:= TfrmChild.Create(Application);
FChild.Show;
// Ask Child to notify us when it is destroyed
FChild.FreeNotification(Self);
end
else
begin
// Child already exists
FChild.Show;
end;
end;
procedure TfrmParent.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
if (AComponent = FChild) and (Operation = opRemove) then
begin
// FChild is about to be freed, so set reference to Child to nil
FChild:= nil;
end;
end;
Run Code Online (Sandbox Code Playgroud)
创建子表单后,使用创建的表单的FreeNotification方法注册自己,以便在销毁子表单时收到通知.
要对通知做出反应,请覆盖通知方法.在那里,您可以找出销毁的组件,并将其与记住的子表单引用进行比较.收到通知后,只需将子表单的引用设置为nil即可.
在孩子TfrmChild本身你不需要做任何其他事情,除了skamradt编写的内容:只需在OnClose事件中将参数Actionb设置为caFree.
| 归档时间: |
|
| 查看次数: |
14507 次 |
| 最近记录: |