读书人

delphi MDI 子窗体关闭后再打开报错

发布时间: 2012-02-10 21:27:42 作者: rapoo

delphi MDI 子窗体关闭后再打开报错,请大家看看什么原因

Delphi(Pascal) code
//父unit sybz_main;interfaceuses  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;interfaceuses  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.


[解决办法]
我觉得你的程序有几个问题:
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;implementationvar   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; 

读书人网 >.NET

热点推荐