MDI窗口几问???(50分)

  • 主题发起人 主题发起人 yun.li
  • 开始时间 开始时间
Y

yun.li

Unregistered / Unconfirmed
GUEST, unregistred user!
想实现的目标:
在MDI窗口中实现子窗体不重复打开,
procedure OpenForm(FormName:String); //在菜单事件中调用
Function ExistForm(FormName:String):Boolean; //判断是否已打开某一窗体
在调用ExistForm()时使用窗口名('sys_msjg')
问题是Application.CreateForm(TFormName, FormName);
FormMain.WindowState:=wsNormal ;
FormMain.Show ;
这要用到宏替换,我应该怎么使用这条语句??

Procedure TFormMain.OpenForm(FormName:String);
Begin
If FormMain.ExistForm(FormName) Then
begin
FormMain.MDIChildren[0].BringToFront; //以避免重复打开
FormMain.MDIChildren[0].WindowState:=wsNormal ;
FormMain.MDIChildren[0].Show ;
End
Else
begin
//Application.CreateForm(TFormName, FormName);
FormMain.MDIChildren[0].WindowState:=wsNormal ;
FormMain.MDIChildren[0].Show ;
End;
End;

Function TFormMain.ExistForm(FormName:String):Boolean;
{作为MDI父窗体(FormMain)的该方法,可在MDIchild子窗体调用}
var
I: Integer;
begin
Result:=false;
with FormMain do
for I := MDIChildCount-1 downto 0 do
If Pos(Uppercase(FormName),Uppercase(MDIChildren.Name))>0 Then
begin
Result:=True;
Break;
End;
End;

procedure TFormMain.Setup_1Click(Sender: TObject);//菜单事件
begin
OpenForm('Sys_msjg');
end;

 
那有这么复杂
procedure TFormMain.Setup_1Click(Sender: TObject);//菜单事件
begin
if not assigned(Sys_msjg) then Sys_msjg:=TSys_msjg.create(application);
Sys_msjg.show;
end;
在Sys_msjg窗口的ondestroy事件中要加上一句 Sys_msjg:=nil;
 
很对呀,有简单的为什么不用?
多写代码好完吗?是没有必要的代码!
 
楼上二位,言之有理。不过小愚仍然有点困惑,
1。像这样的语句中能不能使用宏替换???
if not assigned([red]Sys_msjg[/red]) then Sys_msjg:=TSys_msjg.create(application);
[black][/black]
2。MDI主窗口中为什么不能显示背景图片,但在设计时可以显示???
 
不打开重复的MDI窗口可以这样

if mdifrm <> nil then
midfrm := midfrm.create(application)
else
midfrm.show;

在MDI窗口的CLOSE处加上一句(就是action := cafree处)
mdifrm := nil;

简单吧!!
 
nathanlee:
你是这样写的:
if mdifrm <> nil then
midfrm := midfrm.create(application)
else
midfrm.show;
我试了一下,应该这样写:
if mdifrm = nil then
midfrm := midfrm.create(application)



 
谢谢几位,但是如果在主菜单重要打开许多个窗口,这么写仍然很麻烦。应该可以使用自定义函数
 
那就看你的爱好了

procedure OpenForm(FormName:Tform);
begin
if not assigned(Sys_msjg) then Sys_msjg:=TSys_msjg.create(application);
Sys_msjg.show;
end;

procedure TFormMain.Setup_1Click(Sender: TObject);//菜单事件
begin
OpenForm(Sys_msjg);
end;
 
我自己写了一个公共函数,就是调用子窗体的公共函数,很好用
所有菜单可以公用一个事件,省了我很多代码,你看一看,应该能符合
你的要求,调用前,即在主窗体的create事件中,要调用
RegisterClasses函数把你的所有子窗体的类注册,这样在后面的
getClass才能起作用!

procedure TfrmMain.ShowMdiChild(ClassName:String);
var
FormClass:TPersistentClass;
i:integer;
Child,CurrentForm:TForm;
ClassStr:String;
begin
{
我这里有个变通,即把菜单名字和窗体的类名保存在数据库中,
如果你的程序不用数据库,也可以用ini文件保存,这样所有的菜单就可以
公用这一个事件了,调用时只要传入菜单名字就行了,classStr是根据菜单名
得到的子窗体类名
}

if adomodul.Locate('name',ClassName,[]) then
ClassStr:=adomodul.fieldbyname('classname').asstring
else
begin
MessageBox(frmMain.handle,'找不到该窗体!','出错',MB_ICONERROR);
Exit;
end;
//已经是活动的,退出
if FrmMain.MDIChildCount<>0 then
if FrmMain.ActiveMDIChild.ClassName=ClassStr then
exit;
FormClass:=GetClass(ClassStr);
if FormClass=nil then
begin
MessageBox(frmMain.handle,'找不到该窗体!','出错',MB_ICONERROR);
exit;
end;
for i:=0 to FrmMain.MDIChildCount-1 do
begin
if frmMain.MDIChildren.ClassName=ClassStr then
begin
Child:=frmMain.MDIChildren;
{
如果窗体已存在,把它放到最前面,使他是活动的
SW_SHOWMAXIMIZED
可以自己设置!
}
ShowWindow(Child.handle,SW_SHOWMAXIMIZED);

if Child.WindowState=wsMinimized then
ShowWindow(Child.handle,SW_SHOWMAXIMIZED)
else
ShowWindow(Child.handle,SW_SHOWNA);
if (not Child.Visible) then Child.Visible:=True;
Child.BringToFront;
Child.Setfocus;
exit;
end;
end;
//窗体不存在,create
try
CurrentForm:= TFormClass(FormClass).Create(application);
CurrentForm.BorderIcons:=[];
// CurrentForm.Show;
except
Application.MessageBox('找不到该窗体!','出错',MB_ICONERROR);
end;

end;
 
多谢你们的热情答复,可惜我的分数太少了,只有请你们原谅!
余俊
2002。05。28

再一次衷心感谢
 
后退
顶部