转自:http://hi.baidu.com/chinamis/blog/item/b52b242440c9d23ac995596b.html
在form 关闭后 ,窗口变量的指针变没有指向NIL,而是指向一个无效的地址,对于SDI 窗口来说,这不存在问题,但是对于 MDIChild ,则问题多多。
一般来说,我们应该只需要在 close 事件中写上
Action := CaFree;
就可以解决问题,但是在mdichild 中,写上这行代码等于没有写。
如果有一个窗口为form 2 ,哪么关闭的时候要这样写才能让from2 指向NIL
方法一、
from2.free;
form2:=nil;
方法二、
freeandnil(form2);
上面的代码不存在问题,哪什么地方来的问题?
如果我们想把代码通用化,哪么,FREE 操作完成以后,你就无法让变量再指向nil
相关的通用化变量的使用,都是用指针来完成了,问题就出在这儿,指针只能操作他所指向的变量,而不能改变另一个指向同一地址的变量的指向,所以也就无法完成 更改变量为nil的操作
哪常规的主窗口中的代码:
if not assigned(form2) then form2:=tform2.create(Self);
//if form2=nil then form2:=tform2.create(Self);
form2.show;
就会无用,因为现在form2 不是空指针。
Delphi(Pascal) code
属性设置:
form1.formstyle:=fsMDIform;
form2.formstyle:=fsMDIChild;
代码:
procedure TForm1.act_Frm2Execute(Sender: TObject);
begin
if form2=nil then form2:=tform2.Create(self);
form2.Show ;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//freeandnil(tform(sender));
tform(sender).Free ;
tform(sender):=nil;
end;
如果FORM2中不用类型转换,直接把代码改成:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
form2.free;
form2:=nil;
end;
则不会出现问题。
哪么,这个问题是DELPHI 的一个BUG 吗,相关官方人员没有给一个确切的回答,只是给了一个解决方案:
这个解决方案,这个对于小型软件来说,意义不大,但是对于大型的商业项目,确实是个不错的选择:
原贴请见:
http://bbs.codegear-cn.com/viewthread.php?tid=1013&extra=page%3D1
相关代码:
问题就在于你写的 if not assigned(child2) then了。我的意思是,不要写这一句,而是将其替换为
if IsInclude(TChild2) then 。
然后在主窗体中写一个函数:
function TForm1.isInclude(formclass: TFormClass): boolean;
var
i: Integer;
form: TObject;
begin
result := false;
for i := 0 to MDIChildCount do
begin
form := MDIChildren[i];
if form is formclass then
result := true;
end;
end;
这样就不需要再复制childn := nil 了。
也就是说,现在我们不用管这个指针是否指向NIL,而是在主窗口中查找引用次数,哪现在也就解决了子窗体中的代码不能通用化的问题.
最终的调用代码为:
procedure TForm1.form21Click(Sender: TObject);
begin
if not isInclude(tform2)then form2:=tform2.create(self);
form2.show;
end;
再修改下,就可以实现通用化了!
(最近如果能休改成功,则会把所有代码贴出来,思路有了,但是细节还是要慢慢的去实现)
分享到:
相关推荐
在这个特定的案例中,提供的压缩包可能包含了一个已经预设好背景图的PB8 MDI窗口对象,以及相关的源代码和资源文件。开发者可以下载并研究这些文件,理解如何在自己的项目中应用类似的设计。如果想要自定义背景图,...
每个子窗口都可以独立打开、关闭、最大化、最小化,且可以在MDI父窗口内自由移动。它们可能具有各自的特性和功能,例如,`frmDoc.frm`可能是基本的文档视图,而`frmDoc2.frm`可能包含额外的功能或界面改进。 3. `...
用户可以在MDIFrame中自由切换和管理这些子窗口,而无需频繁地打开和关闭新窗口,提高了工作效率。 二、菜单系统 菜单是用户与应用程序交互的重要途径,用于执行各种操作。在MDI应用程序中,菜单通常包括文件、编辑...
这里我们将深入探讨如何在Dialog模式下创建一个MFC OpenGL子窗口,而不是使用SDI (Single Document Interface) 或 MDI (Multiple Document Interface)。 首先,我们需要理解MFC中的对话框。对话框是Windows应用程序...
MDI应用程序通常包含多个子窗口(子框架),这些子窗口可以在主窗口内自由移动和排列。关键组件和技术包括: 1. **JDesktopPane**:它是MDI应用程序的主要容器,用于显示和管理MDI子窗口(JInternalFrame)。 2. *...
通过这种方式,父窗口可以在子窗口实例化后或在任何时间传递值,而子窗口可以通过订阅事件来响应这些值的变化。这种模式特别适用于用户交互,例如点击按钮或更改控件状态时。 在实际应用中,你可能还会发现DEMO包含...
在“工程”菜单中选择“工程属性”,在“通用”选项卡下将“MDI应用程序”设置为“是”。 2. **添加引用**:为了使用MapInfo OLE,需要在VB项目中添加对MapInfo的引用。在“工具”菜单中选择“引用”,然后在弹出的...
MDI的应用程序框架通常包括菜单、工具栏以及可以创建、排列和关闭子窗口的机制。 2. **源代码**:源代码是程序员用编程语言编写的原始指令集合,它是软件开发的基础。在这个例子中,源代码可能包含创建MDI应用程序...
在本示例中,应用程序名为MDITest,使用AppWizard创建的类包括CMDITestApp(应用程序类)、CMainFrame(MDI框架窗口类)、CMDITestDoc(文档类)、CChildFrame(MDI子窗口类)和CMDITestView(文档显示类)。...
它可以管理子窗口的排列、最大最小化、平铺和层叠等行为。 6. **事件处理**:Qt使用信号和槽机制处理用户交互,例如点击按钮、关闭窗口等事件。开发者需要为这些事件编写相应的槽函数来响应。 7. **资源文件**:Qt...
14. 改变工程表头栏,通常是自定义一个资源并且在窗口的初始化代码中进行设置。 15. 如何打开一个Dialog的窗口,需要使用CDialog类或其派生类来创建和显示一个对话框。 16. 得到系统中设置的窗口颜色,可以使用API...
3. 窗口类的层次结构:包括CFrameWnd(框架窗口),CMDIFrameWnd(MDI框架窗口),CMDIChildWnd(MDI子窗口),CView(视图类),CDialog(对话框类),CButton(按钮控件)。 4. 窗口属性获取与设置:如GetStyle...
在Windows应用程序中,停靠窗口是一种可以被用户自由定位或固定在主窗口边缘的子窗口。它们通常用于提供额外的工具栏、属性面板或视图,提高用户交互性。在MFC中,我们可以利用CWnd类的派生类来创建停靠窗口,并使用...
"frmView"可能用于查看样品的详细信息,而"MDIForm1"则可能是一个多文档界面(MDI)的主窗口,允许同时打开和操作多个子窗口。 通过这些文件,我们可以看出这个通用样品管理系统采用了BASIC语言进行开发,并且有...
mdiPnt1B.frm和mdiPnt2B.frm可能是两个子窗体(MDI Child Forms),用于展示不同的背景绘图效果;MDIPNT1B.FRX和mdiPnt2B.frx是资源文件,存储了窗体的布局和控件信息;MDIPNTB.VBP是项目文件,记录了整个工程的配置...
10. 最大化MDI子窗口:调用CMDIChildWnd::ShowWindow(SW_MAXIMIZE)实现最大化。 11. 移除主窗口标题中的"Untitled":修改CFrameWnd或CMDIFrameWnd的OnCreate()方法。 12. 递归树搜索:对于树控件,你可以编写递归...
《Delphi7编程100例》代码目录:---------------------------------------------ToolBar工具栏控件的使用动态建立主菜单选项窗口界面的动态分隔条动态设置选项卡页面在标题栏中自定义按钮窗体开合窗帘效果Windows XP...
在Delphi中,实现MDI需要使用TApplication和TMDIMainForm等组件,以及适当的事件处理来管理子窗口的创建、关闭和布局。 "DLL对象传参数"是指在DLL中创建的对象可以通过函数参数传递给调用者。这种方式常用于在DLL...
当关闭MDI父窗体时,所有打开的子窗体也会随之关闭。 在C#中创建MDI应用程序,关键在于设置窗体的`IsMdiContainer`属性为`True`,使其成为MDI容器,然后可以在其中添加和管理MDI子窗体。MDI父窗体有一些特定的属性...
12. 如何让窗口和 MDI窗口一启动就最大化和最小化? 41 13. 如何使程序保持极小状态? 41 14. 如何限制窗口的 大小? 41 15. 如何使窗口不可见? 41 16. 如何使窗口始终在最前方? 41 17、如何创建一个字回绕的CEditView...