delphi MDI 子窗体关闭后再打开报错,请大家看看什么原因
时间:2011-09-23
来源:互联网
Delphi(Pascal) code
//父 unit sybz_main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Mz_dl, ToolWin, ActnMan, ActnCtrls, ActnMenus, Menus, ImgList, ComCtrls, ExtCtrls,Unit_cx,Unit_dj, DB, DBTables, Grids, DBGrids, StdCtrls,Unit_dm1; type Tmain = class(TForm) MainMenu1: TMainMenu; N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; N4: TMenuItem; ImageList1: TImageList; stat1: TStatusBar; tmr1: TTimer; Panel1: TPanel; DBGrid1: TDBGrid; Button1: TButton; procedure FormShow(Sender: TObject); procedure FormActivate(Sender: TObject); procedure tmr1Timer(Sender: TObject); procedure N1Click(Sender: TObject); procedure N2Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public sybz_dj: Tsybz_dj; sybz_cx: Tsybz_cx; { Public declarations } end; var main: Tmain; implementation {$R *.dfm} procedure Tmain.FormShow(Sender: TObject); begin Dl_form.Showmodal; end; procedure Tmain.FormActivate(Sender: TObject); begin stat1.Panels[0].Text:='操作人姓名:' +dl_form.Edit1.Text; if Dl_Form.Edit1.Text='管理员' then begin main.Enabled:=False; MessageBox(0,'请勿使用公用管理员帐号登录本系统!','提示!',MB_ICONSTOP); Close; end; end; procedure Tmain.tmr1Timer(Sender: TObject); begin Stat1.Panels[1].Text:= FormatDateTime( 'yyyy "年 "mm "月 "dd "日 " hh:mm:ss ', Now()); end; procedure Tmain.N1Click(Sender: TObject); begin //保持窗口唯一 if sybz_dj = nil then begin sybz_dj := Tsybz_dj.Create(Self); end else begin sybz_dj.Show; end; sybz_dj.WindowState := wsMaximized; end; procedure Tmain.N2Click(Sender: TObject); begin if sybz_cx =nil then begin sybz_cx := Tsybz_cx.Create(nil); end else begin sybz_cx.Show; end; sybz_cx.WindowState := wsMaximized; end; procedure Tmain.Button1Click(Sender: TObject); begin dm1.qry_jrtj.Active:=True; end; procedure Tmain.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Caption := IntToStr(X) + chr(32) + IntToStr(Y); if (X < Panel1.Left+200) or (X > Panel1.Left + Panel1.Width) or (Y < Panel1.Top) or (Y > Panel1.Top + Panel1.Height) then Panel1.Hide else Panel1.Show; end; end. //子 unit Unit_dj; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type Tsybz_dj = class(TForm) Label1: TLabel; procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var sybz_dj: Tsybz_dj; implementation {$R *.dfm} uses sybz_main; procedure Tsybz_dj.FormActivate(Sender: TObject); begin main.stat1.Panels[2].Text:='登记状态'; end; procedure Tsybz_dj.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; sybz_dj := nil; end; procedure Tsybz_dj.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Caption := IntToStr(X) + chr(32) + IntToStr(Y); if (X < main.Panel1.Left+200) or (X > main.Panel1.Left + main.Panel1.Width) or (Y < main.Panel1.Top) or (Y > main.Panel1.Top + main.Panel1.Height) then main.Panel1.Hide else main.Panel1.Show; end; end.
作者: guxinren521 发布时间: 2011-09-23
sybz_dj := nil;
这个放到窗体的destroy事件下吧。
好像这样没有什么区别啊
这个放到窗体的destroy事件下吧。
好像这样没有什么区别啊
作者: moshao6 发布时间: 2011-09-23
你在主窗体设置了 sybz_dj:Tsybz_dj;定义了一个窗体
在子窗体中还有一个sybz_dj.
在主窗体中创建子窗体时其实用的是主窗体的 sybz_dj 变量
子窗体在close 时 sybz_dj:=nil;其实是 子窗体的变量。
在第二次打开时,主窗体中的 sybz_dj <> nil ;这里调用 sybz_dj.show 肯定会错了.
在子窗体中还有一个sybz_dj.
在主窗体中创建子窗体时其实用的是主窗体的 sybz_dj 变量
子窗体在close 时 sybz_dj:=nil;其实是 子窗体的变量。
在第二次打开时,主窗体中的 sybz_dj <> nil ;这里调用 sybz_dj.show 肯定会错了.
作者: ZyxIp 发布时间: 2011-09-23
我觉得你的程序有几个问题:
1.窗体命名不好, Tsybz_dj 让别人看根本就不知道是个窗体.最好命令是 Tfrm_sybzdj 所有的窗体都加上 tfrm前缀。
2.窗体单元命令不好。Unit_dj表现不出这是一个窗体单元最好加上 TWindj 使用 TWin前缀。
3.在窗体调用时不要在调用窗体中定义被调用窗体的变量。你在主窗体中:
public
sybz_dj: Tsybz_dj;
sybz_cx: Tsybz_cx; 这样不好。
4.窗体的创建的代码最好在窗体自己的单元文件中实现,而你的是在主窗体中调用的。可以参考以下的实现方式。
Delphi(Pascal) code
1.窗体命名不好, Tsybz_dj 让别人看根本就不知道是个窗体.最好命令是 Tfrm_sybzdj 所有的窗体都加上 tfrm前缀。
2.窗体单元命令不好。Unit_dj表现不出这是一个窗体单元最好加上 TWindj 使用 TWin前缀。
3.在窗体调用时不要在调用窗体中定义被调用窗体的变量。你在主窗体中:
public
sybz_dj: Tsybz_dj;
sybz_cx: Tsybz_cx; 这样不好。
4.窗体的创建的代码最好在窗体自己的单元文件中实现,而你的是在主窗体中调用的。可以参考以下的实现方式。
Delphi(Pascal) code
//主窗体 procedure TWinMain.btn_OpenDJ(Sender:Tobject); begin CreateWinsybzdj(参数); end; //子窗体 Winsybzdj Tfrm_sybzdj=class(tform) public class function CreateWinsybzdj(参数):Boolean; end; implementation var frm_sybzdj:Tfrm_sybzdj; //如果窗体只是 Show出来,则这样写 class function Tfrm_sybzdj.CreateWinsybzdj(参数):Boolean; begin Result:=False; if Not Assigned(frm_sybzdj) then frm_sybzdj:=Tfrm_sybzdj.Create(Application); frm_sybzdj.Show; Result:=True; //然后在窗体的 Close 事件中 action:=cafree; frm_sybzdj:=nil; end; //如果窗体是ShowModal 出来,则这样写 class function Tfrm_sybzdj.CreateWinsybzdj(参数):Boolean; var frm_sybzdj:Tfrm_sybzdj; //将上面的变量放在这里。 begin Result:=False; frm_sybzdj:=Tfrm_sybzdj.Create(Application); frm_sybzdj.ShowModal; Result:=frm_sybzdj.ModalResult=mrOK; frm_sybzdj.Free; end;
作者: ZyxIp 发布时间: 2011-09-23
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28