新手学习中 发表于 2014-3-19 19:38:55

新手笔记-----对话框的创建---求指正

             创建模态对话框与非模态对话框

创建弹出模态对话框:

具体步骤:(先插入对话框资源)

1、新建mfc派生类的同时与其ID绑定。如图:

1.1 新建类向导----addnew class-----Base CDialog----ID


http://p.qlogo.cn/qqmail_head/cZVA8I2lXTGxPRVqQiby2Y4Qgcdd5rRxQvmmUKqLyjdGIsq4picI8icjHEbXBlet0jWMIwDUeCtzoqgIqdib5BanpY4CkfPzpWbHHEOJkicvgZtGpb2zB4TwWXaiawexiaMcYd82n9Yab779VfeFsdZic3Dv4iap4WBvM6kbe/0http://p.qlogo.cn/qqmail_head/cZVA8I2lXTGxPRVqQiby2Y4Qgcdd5rRxQvmmUKqLyjdGIsq4picI8icjHEbXBlet0jWMIwDUeCtzopBtibDCdb1kuxay1k5rUmx7TM0ofwf8SuTiba37wTd3XICdTBBsq89Y0bhicibltMfGc5uTqHH1eQRQCQn8LcPyjeW/0



2、在需要响应的函数中调用对象.DoModal();//弹出。之前要新建绑定的类对象。


说明:

1、add class 不需要特意选择某个cpp 直接add就行

2、绑定必须是对应mfc基类的派生类

3、注意是类与资源绑定。

4、DoModal();是阻塞函数,卡在那里,直到用户关闭对话框才返回函数

5、自动生成的绑定功能的相关代码所在位置:
http://p.qlogo.cn/qqmail_head/cZVA8I2lXTGxPRVqQiby2Y4Qgcdd5rRxQvmmUKqLyjdGIsq4picI8icjHEbXBlet0jWMIwDUeCtzoo29P0evvibkDSlKvQkKkhkjaJm0QUvicBemf0ksnLvVYFb6wjqJq85oj3nLebV1DKo2Rvw5Lt5DtUhLV3icwkCUwE/0

6、一个类只能绑定一个资源

7、不可绑定mfc默认的原始对话框,因为它已经被默认生成的类绑定了。


8、模态的概念:是指阻塞在那里,等待用户关闭才返回函数的对话框


9、模态的特征:不关闭子模态对话框,就不能对父窗口进行操作。



创建弹出非模态对话框:

具体步骤:

1、新建派生绑定资源类(同上)


2、在需要响应的函数里,调用绑定类对象成员函数(先要创建对象)

dlg.Create(弹出的ID,父窗口指针(可以传this));            //内存中创建
dlg.ShowWindow(SW_SHOW);                               //显示出来了,却一闪而过


说明:

1、显示出来的对话框会一闪而过。




2、原因是函数为非阻塞,立刻返回,大函数结束后对象被析构,对话框自动关闭


创建弹出非模态对话框非一闪而过:

1、在绑定类后,只需把新建的对象新建在全局或者作为父对话框类成员即可。

说明:

1、设置全局,或者成为类成员时,要注意添加头文件

2、非一闪而过的对话框,可关闭后要求再次弹出,会出错。

3、原因是,关闭后,对象的作用域使得对象没被析构。再次弹出creat时,对话框之前的还在,于是出错。



解决非一闪而过非模态对话框之无法多次弹出的问题:


方法一:设置全局或者成员变量bool 来判断,如:
void CFdsaDlg::OnOK()
{
if(t==false)
{
   dlg.Create(IDD_DIALOG1,this);
   dlg.ShowWindow(SW_SHOW);
   t = true;
}
    dlg.ShowWindow(SW_SHOW);
}

方法二:设置全局或成员指针,弹出时申请动态对象,关闭对话框时手动释放对象

说明:

1、如果指针定义为父窗口的指针成员变量。那么按钮函数里释放时,要释放this而不是释放成员指针



原因: 因为成员指针超出了作用域(至于为什么超出,似乎要了解消息回调机制等,暂时不太懂)

因为指针指向对象。this也是执行对象。所以 delete this 就可以释放。


2、对话框叉叉按钮无法编辑,但是它响应的是OnCancel()   同默认取消一样的响应

void Cmydialog::OnCancel()
{
delete this;

// CDialog::OnCancel();
}

3、注意因为释放了,窗口就消失了,CDialog::OnCancel();无法执行,必须去掉


方法三:调用DestroyWindow()销毁内存中的窗口

void Cmydialog::OnCancel()
{

DestroyWindow();
//delete this;
// CDialog::OnCancel();
}


说明:

1、必须把CDialog::OnCancel();去掉,因为窗口都没了。不然直接运行错误

2、根据情况,销毁后可继续delete this销毁整个对象(如果是全局则不用)

3、销毁对象也可在PostNcDestroy()中进行(这个函数的优势就是你不用为每个退出函数都重复写上释放代码)

说明:
3.1内存上销毁窗口时(非显示上关闭),会响应PostNcDestroy()函数,要重载虚函数
http://p.qlogo.cn/qqmail_head/cZVA8I2lXTGxPRVqQiby2Y4Qgcdd5rRxQvmmUKqLyjdGIsq4picI8icjHEbXBlet0jWMIwDUeCtzoqeDGAtuaM5q79NJr1MOqPtxfKeaFAXEJr96ibgLicHB80aLHspOhmbhjsVg1bakAIWfzPtWia7h1Wh6hBZ1LgGz9k/0

我们可以在OnCancel()里delete 也可在PostNcDestroy() 里delete


void Cmydialog::PostNcDestroy()
{
delete this;

CDialog::PostNcDestroy();
}

3.2 趣味实验:在PostNcDestroy() 里又显示窗口,这样窗口就关不掉了!

void Cmydialog::OnCancel()
{

DestroyWindow();

// CDialog::OnCancel();
}


void Cmydialog::PostNcDestroy()
{
this->Create(IDD_DIALOG1,this);
this->ShowWindow(SW_SHOW);
//delete this;

CDialog::PostNcDestroy();
}

3.3 内存里窗口被销毁时,不只发送PostNcDestroy消息,它是层层发送的,详见:

http://blog.csdn.net/liuy_yy/article/details/7095286

3.4、注意,销毁时发这个消息是发给子对话框自己,不是发给父对话框


**** Hidden Message *****







页: [1]
查看完整版本: 新手笔记-----对话框的创建---求指正