在最近中兴捧月的竞赛和帮同学解决一个对话框中动态显示数据时都用到了非模式对话框。现在对非模式对话框做个小结。
非模式对话框,说简单点就是在一个主对话框中弹出一个新对话框时,仍然可以对原来的主对话框进行相关操作,不一定要把当前新生产的对话框叉掉。(模式对话框就必须把后来新生产的对话框叉掉,才能获得原对话框焦点,进行操作)
创建非模式对话框有两种情形:
情形一、在资源视图里手动添加了一个Dialog,同时赋以对应的ID.
情形二、不用在资源视图里手动添加Dialog.
(1)先说情形一:
情形一又可分为简单做法和复杂做法。(此处的复杂做法可以应用于情形二。)
创建一个基于对话框的project.:TestDlg,然后在资源视图里插入一个新的Dialog.点击类向导(Ctrl+W),生成一个新类CNonModalDlg,该对话框对应的ID是IDD_DIALOG2;
【简单做法】
在TestDlg对话框的界面上增加按钮,在对应的消息映射函数里写上如下语句
{
CNonModalDlg * pNonMdlg = new CNonModalDlg;//新对话框类对象指针
pNonMdlg->Create(IDD_DIALOG2); //调用默认的Create方法
pNonMdlg->ShowWindow(SW_SHOW); //显示对话框SW_SHOW,隐藏用SW_HIDE
}
此时可以生成多个非模式对话框
【复杂做法,参考http://topic.youkuaiyun.com/t/20041111/16/3544214.html,只生成一个非模式对话框】
(1)对话框添加后,在CNonModalDlg类里添加一个成员变量CDialog * m_pParent;
(2)为CNonModalDlg添加一个新的构造函数
CNonModalDlg::CNonModalDlg(CDialog *pParent)
{
m_pParent = pParent;
}
(3)在CNonModalDlg中重写Create方法
BOOL CNonModalDlg::Create()
{
return CDialog::Create(CNonModalDlg::IDD);
}
至于OK和Cancel按钮可以直接去掉,如果保留,则可以重写对应的消息映射,略
(4)在CTestDlg(主对话框)类中添加一个成员变量
CNonModalDlg * m_MDlg;//记得添加头文件
在CNonModalDlg的构造函数里为m_Mdlg赋值
即添加:m_Mdlg = new CNonModalDlg;
若没有析构函数,则要添加析构函数,并在里面释放内存。
CTestDlg::~CTestDlg
{
if (m_MDlg != NULL)
delete m_MDlg;
}
(5)在主对话框中添加一按钮,对应的消息映射为:
void CTestDlg::OnOpenDlg()
{
if (m_MDlg-> GetSafeHwnd() == NULL)
m_MDlg-> Create(); //句柄不空,才创建,保证只创建一个
else
m_MDlg-> SetWindowPos(&wndTopMost,300,400,NULL,NULL,SWP_NOSIZE);
}
情形二即在没有在资源视图中添加一个新的Dialog
具体做法也同情形一的复杂情况。
另外,如果要创建多个Dialog。(如中兴的竞赛中要生成多个窗口)。
当时的处理就是创建一个全局的CNonModalDlg对话框对象指针数组CNonModalDlg *DlgArr[100]。然后在对应的CTestDlg中就不添加 CNonModalDlg * m_MDlg;
当然也就不需要在构造函数中赋初值和析构中释放内存。并在具体创建时用DlgArr[i].Create();i++;(i是一个全局的维护对话框计数器)来代替。
因为全局变量不用初始化和销毁,所以省略了对应的构造函数和析构函数。
对于简单情况下应该也可以将生成的结果放到一个数据里。
总之,若能在资源视图里添加新对话框,则可用简单方法,反之,用复杂方法。
本文总结了在MFC中创建非模式对话框的方法,包括资源视图添加和不添加Dialog的情况。通过示例详细讲解了如何实现非模式对话框的显示、创建以及管理多个对话框实例。涉及CNonModalDlg类的构造、Create方法重写以及主对话框的交互处理。
618

被折叠的 条评论
为什么被折叠?



