MDI问题:简直不能相信NULL指针也能SHOW出窗体来!

kissfire 2003-07-30 08:41:07
我有一个MDIchild窗体,是我的MDI窗体的成员窗体,我不想每次都NEW一个窗体,所以就想判断一下,为NULL才NEW一个,所以MDI初始化时,使fmSysModuleSet= NULL, 但是,下面的语句居然能SHOW出来,经调试此时fmSysModuleSet的确为NULL,关掉子窗体再SHOW,fmSysModuleSet不为NULL,但SHOW不出来,真是奇怪!
try{

fmSysModuleSet->Show();
}catch(...)
{
fmSysModuleSet = new TfmSysModuleSet(Application);
fmSysModuleSet->Show();
}
...全文
58 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
jishiping 2003-08-02
  • 打赏
  • 举报
回复
“我忘了写,不初始化,第一次创建时,自动为NULL”

对于没有初始化的变量,它的值是随机的(由编译器编译时决定的)。也许编译10次看到的
都是NULL,但是第11次就不是NULL了。但是你千万不要认为没有初始化的变量的初始值就是
NULL(或者是0)。

对于你的做法,我真的是已经失去了耐心。我说了,拷贝你的代码到CSDN上,而不是自己写。
你上面的代码,主窗口没有包含 unit1.hpp,编译时怎么可能通得过???我指出一处问题,
你马上说你忘了,或者是其它什么的,可是事实上的错误,可能就是这些你认为忘了还是什
么其它的原因造成的。也许你原来程序里的错误,被你放到CSDN上时,又被你改对了也说不
定!!!我已经多次强调,使用复制功能将你已经编译通过但是运行时有问题的代码贴出来。
但是我每次看到的,都是不同的代码。比如,最初你说的是fmSysModuleSet,可是在你最后
一次贴的代码里,又变成了Form1了!!!你这样变来变去的,有谁知道你程序中真正的代码
错在哪里???鉴于楼主的做法,我不会再来看这个帖子了,我觉得真的是在浪费时间。
kissfire 2003-08-02
  • 打赏
  • 举报
回复
谢谢各位热心的朋友,改日结帖!
kissfire 2003-08-02
  • 打赏
  • 举报
回复
找到一个简单的办法,在主窗体的FormPaint事件中使 ChildForm = NULL 这样问题就解决了! 很遗憾没人告诉这样做,有点失望!
kissfire 2003-08-02
  • 打赏
  • 举报
回复
抱歉,我是新建了一个工程,你应该看得出来吧

你上面的代码,主窗口没有包含 unit1.hpp,编译时怎么可能通得过???

我的头文件没有贴出来,只是声明了Form1的指针。

我的意思你应该很清楚了吧,你自己建一个工程,一试便知。

感谢你的解答,但你一样固执。如果说浪费了你的时间,我表示道歉!

我想再次清楚的重申一下这个问题:(对不起各位,我前面说的不是很清楚!)

其实就是MDI应用程序如何避免多次NEW 同一个动态子窗体? 好多朋友说,1。将子窗体指针初始化为NULL,2.要显示的时候,判断 if (ChildForm == NULL), 3.关闭子窗体时,释放子窗体,并将ChildForm = NULL,
但是问题出在 if (ChildForm == NULL) 并非绝对有效,我测试过多次,重新打开子窗体时,ChildForm并非每次都为NULL,所以就SHOW不出窗体来。

kissfire 2003-08-01
  • 打赏
  • 举报
回复
Form1的ONCLOSE中指定自已是空,这样肯定是不行的...

我试过,可以的!

在 Form1 里,Form1 初始化为NULL了么?

我忘了写,不初始化,第一次创建时,自动为NULL,关掉后,再次弹出窗体时,Form1就不为NULL了,不过,我另建一个工程,没有用MDI向导生成,Form1可以每次都为NULL,真是很奇怪。


he_Fly 2003-08-01
  • 打赏
  • 举报
回复
Form1的ONCLOSE中指定自已是空,这样肯定是不行的...
勉励前行 2003-08-01
  • 打赏
  • 举报
回复
//MDI父窗口:

TfmSysModuleSet *pfmSysModuleSet = new TfmSysModuleSet(this);
pfmSysModuleSet

//子窗口:
void __fastcall TfmSysModuleSet::FormClose(TObject *Sender,TCloseAction &Action)
{
Action=caFree;
this = NULL ; //加上這句就會出錯。
delete this; //這樣用還是要出錯,
//因為後面的VCL代碼還是要用到this指針來析構對象。在FormClose事件中,試圖將this設為NULL,會出錯的。在構造函數或析構函數中,試圖執行這種代碼都將失敗。
}

類似這種代碼,關閉後其指針確實不為NULL,這是你自己要想辦法呀,別老抱怨。
我好久好久不用MDI窗口,不知道有什麼好方法。
MDIChildCount , MDIChildren ,WindowMenu 這些有關MDI的屬性應該能處理這問題吧。
實在不行,可以查詢:Screen->Forms,或者在FormClose事件中發送消息給自定義的窗口管理者吧。

jishiping 2003-08-01
  • 打赏
  • 举报
回复
在 Form1 里,Form1 初始化为NULL了么?上面你不是说已经初始化为NULL了,怎么我没有看见啊。
he_Fly 2003-08-01
  • 打赏
  • 举报
回复
调用:

Form_MBillSet = dynamic_cast <TForm_MBillSet *> (FindShowForm (__classid(TForm_MBillSet), ""));
he_Fly 2003-08-01
  • 打赏
  • 举报
回复
没试过你的程序,但你的目的我知道,给你一个通用的函数,不管是MDI还SDI。
//---------------------------------------------------------------------------
TForm * __fastcall FindShowForm(TFormClass FormClass,String vCaption)
{
TForm *vResultForm;
vResultForm=NULL;
for(int i=0;i<Screen->FormCount;i++){
if(Screen->Forms[i]->ClassType()==FormClass){
if (vCaption ==""||vCaption == Screen->Forms[i]->Caption){
vResultForm=Screen->Forms[i];
break;
}
}
}
if(vResultForm==NULL){
Application->CreateForm(FormClass, &vResultForm);
// vResultForm=new TForm(NULL);
if(vCaption != "")
vResultForm->Caption = vCaption;
vResultForm->FormStyle = fsStayOnTop;
}
if(vResultForm->WindowState == wsMinimized)
vResultForm->WindowState = wsNormal;
vResultForm->Show();
return vResultForm;
}
//---------------------------------------------------------------------------
kissfire 2003-08-01
  • 打赏
  • 举报
回复
主窗体:

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
#include "About.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------

__fastcall TMainForm::TMainForm(TComponent *Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CreateMDIChild(String Name)
{
TMDIChild *Child;

//--- create a new MDI child window ----
Child = new TMDIChild(Application);
Child->Caption = Name;
if (FileExists (Name))
Child->Memo1->Lines->LoadFromFile(Name);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileNew1Execute(TObject *Sender)
{
CreateMDIChild("NONAME" + IntToStr(MDIChildCount + 1));
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileOpen1Execute(TObject *Sender)
{
if (OpenDialog->Execute())
CreateMDIChild(OpenDialog->FileName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::HelpAbout1Execute(TObject *Sender)
{
AboutBox->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileExit1Execute(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Button1Click(TObject *Sender)
{
if (Form1 == NULL)
Form1 = new TForm1(this);
else
Form1->Show();
}
//---------------------------------------------------------------------------

子窗体:
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
Form1 = NULL;
}
//---------------------------------------------------------------------------
kissfire 2003-08-01
  • 打赏
  • 举报
回复
子窗体的FFocusedcontrol 不为NULL,不知道是什么东西?

抱歉,可能是我比较固执。


jishiping 2003-07-31
  • 打赏
  • 举报
回复
不用说的,肯定是你自己弄错了(就象你前面说的不会进入异常处理一样)。如果你不相信
的话,贴出你的所有相关代码。如果贴出的不是你的全部代码,请新建一个Project,自己
先测试一下,然后再贴出这个测试的Project的全部代码。
jishiping 2003-07-31
  • 打赏
  • 举报
回复
不用说的,肯定是你自己弄错了(就象你前面说的不会进入异常处理一样)。如果你不相信
的话,贴出你的所有相关代码。如果贴出的不是你的全部代码,请新建一个Project,自己
先测试一下,然后再贴出这个测试的Project的全部代码。
kissfire 2003-07-31
  • 打赏
  • 举报
回复
不好意思,是我弄错了,进入错误处理了,不过,子窗体关闭后,我释放它,并把fmSysModuleSet =NULL,但在主窗体中fmSysModuleSet 并不为NULL,所以
if(!fmSysModuleSet )就判断不了。
jiangchun_xn 2003-07-31
  • 打赏
  • 举报
回复
为什么不用MDIChildCount
kissfire 2003-07-31
  • 打赏
  • 举报
回复
if(form!=NULL)

这句根本无效,关闭子窗体后,即使释放了,子窗体指针依然不为NULL;
jishiping 2003-07-31
  • 打赏
  • 举报
回复
“我用了错误处理,也不算错吧。” 一开始就已经说了,明知 mSysModuleSet 是NULL,还
故意使用fmSysModuleSet->Show();这就是严重的错误(尽管你使用了异常处理)。你要知道
这样的异常,不是普通的异常,这是发生严重错误时的异常。也许在Windows NT/2000/XP下,
程序还能硬挺好多次,但是在Win98下,可能几次一搞,程序就完蛋了。

“现在关键问题是 if(form!=NULL)根本无效!” 如果你仍然觉得无效的话,请你将你的
完整的代码贴出来,而不是只是摘录其中的一两个函数贴出来(前面我已经这样说了)。我
可以100%的肯定,一定是你自己写错了!!!如果你坚持说Form不为NULL,根本无效,而又
不肯贴完整的代码的话,谁也无法帮你,只有你自己在那儿固执己见了。
kissfire 2003-07-31
  • 打赏
  • 举报
回复
哪里将 fmSysModuleSet 设为 NULL 了?

因为没用,我已经删了。

怎么到
现在还对NULL指针做fmSysModuleSet->Show();

我用了错误处理,也不算错吧。现在关键问题是 if(form!=NULL)根本无效!


jishiping 2003-07-31
  • 打赏
  • 举报
回复
你上面的FormClose中,Action=caFree;这个语句也用try catch!!!请不要乱用try catch
好不好!还有,具体怎么使用,无论是 Libran 还是 warton,都已经教给你方法了,怎么到
现在还对NULL指针做fmSysModuleSet->Show();
加载更多回复(16)

13,874

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧