- 编程环境:VS2008
- 练习目的:记住模式和非模式对话框区别
- 关键函数:CDialog::DoModal(),CDialog::Create(),CWnd::ShowWindow(),CWnd::DestroyWindow()
- 两者区别
区别分类 modal对话框 非modal对话框 使用中的区别 不关闭此对话框无法操作其他对话框 随意切换操作对话框 构建方式 局部变量或以new的方式从堆中构建都可以 不能以局部变量构建 创建函数 调用CDialg::DoModal()方法创建 调用CDialg::Create()和CWnd::ShowWindow(SW_SHOW)方法创建并显示 阻塞情况 当前线程阻塞直到关闭modal对话框 CDialg::Create()创建后立即返回继续执行下面代码 - 创建过程
首先我们在创建的MFC工程的主对话框新建两个Button控件,caption分别命名为“model“和”modeless“。
然后新建两个对话框caption分别命名为”设备信息“和”设备状态“,并且为对话框关联名为CDlgDeviceInfo和CDlgDeviceState对话框类。
再为两个Button分别创建单击事件,代码如下:
我们最终代码实现的功能是:void CModalDLGCreateDlg::OnBnClickedBtnModel() { // TODO: 在此添加控件通知处理程序代码 } void CModalDLGCreateDlg::OnBnClickedBtnModeless() { // TODO: 在此添加控件通知处理程序代码 }
一、单击"model" Button后关联了CDlgDeviceInfo类的对话框以模式对话框方式弹出显示。
二、单击"modeless" Button后关联了CDlgDeviceState类的对话框以非模式对话框方式弹出显示。
实现功能一,在OnBnClickedBtnModel()单击事件函数中添加如下代码:
void CModalDLGCreateDlg::OnBnClickedBtnModel() { CDlgDeviceInfo dlgDeviceInfo; int Ret; Ret = dlgDeviceInfo.DoModal(); switch(Ret){ case IDOK: MessageBoxA(NULL,"Model dialg ONOK is called","debug",MB_OK);break; case IDCANCEL: MessageBoxA(NULL,"Model dialg ONCANCEL is called","debug",MB_OK);break; default: MessageBoxA(NULL,"Model dialg sth else is happened","debug",MB_OK);break; } }
当然记得包含CDlgDeviceInfo类声明的头文件“#include DlgDeviceInfo.h”。顺便验证一下CDialog::DoModal()的返回值与创建的模式对话框中使用CDialog::OnOK()和CDialog::OnCancel()函数的关系。
实现功能二,在主窗口的头文件中包含CDlgDeviceState类的头文件“#include DlgDeviceState.h”,并在主对话框类中添加私有成员变量dlgDeviceState,最后在OnBnClickedBtnModeless()的单击事件函数中添加如下代码:
void CModalDLGCreateDlg::OnBnClickedBtnModeless() { if(!IsWindow(dlgDeviceState.m_hWnd)){ BOOL Ret = dlgDeviceState.Create(IDD_DLG_DEVICE_STATE,this); if(!Ret){ AfxMessageBox(_T("Error Creating Modeless Diaglog!"),MB_OK); }else{ AfxMessageBox(_T("Creating Modeless Diaglog Succeed"),MB_OK); dlgDeviceState.ShowWindow(SW_SHOW); } }else{ AfxMessageBox(_T("dlgDeviceState对象已关联对话框"),MB_OK); dlgDeviceState.ShowWindow(SW_SHOW); } }
为了防止重复创建对话框资源,需要用IsWindow(HWND hWnd)判断成员变量dlgDeviceState是否已经关联了对话框资源。如果没有则关联CDlgDeviceState类对话框,并完成对话框的显示。
为了能够销毁modeless对话框,在主对话框创建一个Button,caption修改为“关闭modeless”,添加了此button的单击事件函数后添加如下代码:
void CModalDLGCreateDlg::OnBnClickedBtnCloseModeless() { if(IsWindow(dlgDeviceState.m_hWnd)){ if(!dlgDeviceState.DestroyWindow()){ AfxMessageBox(_T("销毁Modeless对话框失败"),MB_OK); }else{ AfxMessageBox(_T("销毁Modeless对话框成功"),MB_OK); } } }
至此,modeless对话框的创建和销毁练习完毕!
注:已将测试代码工程传至资源中,资源名“VS2008创建model和modeless对话框测试”。
- 两者区别