网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读

源代码在线查看: 07.2.2 非模态对话框的创建.txt

软件大小: 956 K
上传用户: kzdai22
关键词: TXT VC 目录
下载地址: 免注册下载 普通下载 VIP

相关代码

				7.2.2 非模态对话框的创建
				如果要创建非模态对话框,则需要利用 CDialog类的 Create成员函数。该函数具有以下两种形式的声明: 
				BOOL Create( LPCTSTR lpsZTemplateName, CWnd* pParentWnd = NULL ); 
				BOOL Create( UINT n工 DTemplate, CWnd* pParentWnd = NULL ); 
				也就是说, Create函数的第一个参数可以是对话框资源的 ID ( nIDTemplate参数 ),或者也可以是对话框模板的名称 ( lpszTemplateName参数)。这个函数的第二个参数指定了对话框的父窗口,如果其值是 NULL,对话框的父窗口就是主应用程序窗口。对本例来说,如果这个父窗口参数值是 NULL,对话框的父窗口就是框架窗口。这里,我们仍在 CMyboleView类 OnDialog函数中实现创建非模态对话框的功能,则首先需要将上面例 7-4所示代码中创建模态对话框的代码注释起来,然后在其后面添加创建非模态对话框的代
				码,结果如例 7-6所示。 
				void CMyboleView: :OnDialog() 
				// TODO : Add your command handler code here /1 CTestDlg dlg; // dlg.DoModal(); 
				CTestDlg dlg; 				
				dlg.Create(IDD_DIALOG1,this) ; 				
				Build井运行Mybole程序,单击程序菜单栏上的【对话框】菜单,发现并未出现测试对话框窗口。这里,读者一定要注意,当利用 Create画数创建非模态对话框时,还需要调用ShowWindow函数将这个对话框显示出来。那为什么上面利用DoModal函数创建对话框时不需要呢?这是因为DoModal函数本身就有显示模态对话框的作用,所以对模态对话框来说,不需要再调用ShowWindow函数来显示对话框了,但非模态对话框需要调用此函数。因此,我们在上述例7-6所示OnDialog函数的最后再加上下面这行代码: 
				dlg.ShowWindow(SW_SHOW); 
				Build井运行Mybole程序,单击程序菜单栏上的【对话框】菜单,发现仍没有出现测试对话框。问题出在哪里呢?我们回头看看上面的代码,发现这里创建的非模态对话框对象 (dlg)是一个局部对象,当程序执行时,会依次执行各条代码,当OnDialog函数的右大括号执行结束时, dlg这个对象的生命周期也就结束了,它就会销毁与之相关联的对话框资源。那为什么上面创建模态对话框时就可以使用局部对象呢?上面已经讲过,在创建模态对话框时,当执行到调用DoModal函数以显示这个对话框时,程序就会暂停执行,直到模态对话框关闭之后,程序才继续向下执行。也就是说,当模态对话框显示时,程序中创建的dlg这个对象的生命周期并未结束。因此,在创建非模态对话框时,不能把对话框对象定义为局部对象。对于这个问题,有两种解决办法:一种就是把这个对话框对象定义为视类的成员变量:另一种方式是将它定义为指针,在堆上分配内存。我们知道,在堆上分配的内存,与程序的整个生命周期是一致的,当然这里是指程序中不主动销毁的情况。这里,我们采用后一种方式,修改己有代码,结果如例7-7所示。 
				例7-7 				
				void CMyboleView : :OnDialog() 
				. 
				// TODO: Add your command handler code here 11 CTestDlg dlg ; // dlg . DoModal(); 
				CTestDlg *pDlg = new CTestDlg; 
				pDlg->Create(IDD_DIALOG1, this); 
				pDlg->ShowWindow(SW_SHOW) ; 
				因为这里定义的对话时象是指针类型,所有调用其成员函数时应该
				用->操作符。 
				Build并运行Mybole程序,单击程序菜单栏上的【对话框】菜单,测试对话框出现了,这时可以试着单击程序的菜单项,将会发现可以进行这项操作,如图7.11所示。这就是非模态对话框的特点。因为程序显示非模态对话框时,并不会停留在某条语句处,所以 CMyboleView类的 OnDialog函数内部的代码就会顺序地被执行,直到该函数执行结束,. 这时,程序就可以执行其他任务了,例如响应菜单项的单击操作。 
				图 7.11非模态对话框的显示				
				可是,上述例7-7所示的这段程序仍有问题,首先,我们定义的pDlg这个指针变量是一个局部对象,这样当它的生命周期结束时,它所保存的内存地址就丢失了,那么在程序中也就无法再引用到它所指向的那块内存了。这个问题的解决办法有两种:一是将这个指针变量定义为视类 C CMyboleView )的成员变量,然后在CMyboleView类的析构函数中调用 delete函数来释放这个指针变量所指向的那块内存:二是在 CTestDlg类中重载 PostNcDestroy虚函数,释放this指针所指向的内存,代码如例7-8所示,其中加灰显示的代码是我们添加的代码。 
				~~ 7-8 				
				void CTestDlg :: PostNcDestroy() 
				// TODO: Add your specialized code here and/ or call the base class delete this; CDialog : :PostNcDestroy(); 
				另外,读者会发现上述示例中无论创建的是模态对话框,还是非模态对话框,当单击对话框上的【OK】按钮时,对话框都会消失。但有一点需要提醒读者注意,对模态对话框而言,此时对话框窗口对象被销毁了。而对非模态对话框来说,对话框窗口对象并未被销毁,只是隐藏起来了。我们来分析一下在非模态对话框中单击OK按钮后,程序所发生的事情。这时,程序会调用基类 CCDialog)的 OnOK函数,这是一个虚函数。后者又会
				调用EndDialog函数,这个函数用于终止模态对话框,而对于非模态对话框,这个函数只是使对话框窗口不可见,并不销毁它。因此,对非模态对话框来说,如果有一个 E值为 IDOK的按钮,就必须重写基类的 OnOK这个虚函数,并在重写的函数中调用 DestroyWindow函数,以完成销毁对话框的工作,同时注意不要再调用基类的OnOK函数。同样地,如果非模态对话框中有一个 ID值为 IDCANCEL的按钮,也必须重写基类的 OnCancel虚函数,并在重写的函数中调用Des位oyWindow函数,销毁对话框,同时注意不要再调用基类的OnCancel函数。 
							

相关资源