地球人都知道的方法
1.建立工程
2.分别建立两个窗体form1, form2;
3.设置form1的formstyle为fsMDIForm,加入工具栏及按钮和状态栏;
4.设置form2的formstyle为fsMIDChild;
在按钮中加入如下代码:
if not Assign(form2) then
begin
application.createform(Tform2, form2);
form2.show;
end;
运行程序,但是form2不能关闭。
在form2的onclos事件中加入如下代码
Action := caFree;
关于TCloseAction的类型说明参考delphi帮助,网上也有n多的解释,在此就不罗嗦了!
好了,这次可以关闭子form了。但是重新点击创建代码,则会出现错误!
接着在form2中的onclose中加入form2 := nil。OK,可以反复创建和释放form2了。
但是我的程序是采用bpl方式动态加载的,而且变量名都不知道。不过,最后还是找到了方法。
5.在form1中的代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin;
type
PMethod = ^TMethod;
TForm1 = class(TForm)
StatusBar1: TStatusBar;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
procedure ToolButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure FormClose(Sender: TObject; var Action: TCloseAction);
end;
var
Form1: TForm1;
FList: TStringList;
implementation
{$R *.dfm}
uses
unit2;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
vIndex: integer;
p: PMethod;
m: TMethod;
vName: string;
begin
Action := caFree;
if Sender is TForm then
begin
vName := TForm(Sender).Name;
vIndex := FList.IndexOf(vName);
if vIndex >= 0 then
begin
p := PMethod(FList.Objects[vIndex]);
m.Data := Sender;
m.Code := p^.Data;
// 重新悬挂原有close方法,并执行
if m.Code <> nil then
TCloseEvent(m)(Sender, Action);
//释放资源
p^.Code := nil;
p^.Data := nil;
Dispose(p);
FList.Delete(vIndex);
end;
end;
end;
procedure TForm1.ToolButton1Click(Sender: TObject);
var
vForm: TForm2;
i: integer;
p: PMethod;
begin
vForm := TForm2.Create(self);
vForm.Caption := vForm.Name;
New(p);
p^.Code := vForm;
p^.Data := @vForm.OnClose;
vForm.OnClose := FormClose;
FList.AddObject(vForm.Name, Pointer(p));
vForm.Show;
end;
initialization
FList := TStringList.Create;
finalization
FList.Free;
end.
//这仅仅是一个Demo,有些地方仍需改进。这种方法可以解决form资源创建后,不能完全释放的问题。
//记录在此,备忘!