Model和modeless对话框的创建
我的开发环境:Visual Studio 2008.NET。
Model类型的对话框很容易,只要在想创建的时候给一个对象调用一个DoModal()函数便可以了,如下:
CAboutDlg my;
my.DoModal();
但是modeless对话框就没有这么容易了,创建的过程有点复杂,如下:
首先,使用wizzard创建一个对话框,一定要记得带上visible为ture,一般的创建的新对话框都是不可见的,所以记得带上。
之后,add class为新建的对话框添加类定义。
然后才是真正的modeless对话框的创建了:
1、添加一个private: CView *pView;在这里有一个问题了,为什么是CView对象?其实这里只是一个创建modeless对话框的parent对象,这里是创建一个从CView 对象触发的对象,如果以后从别的对象,那么就从相应的对象里面触发,比如private: CDialog *pDlg;而且这里的定义是用在构造函数里的。
2、我们必须了解到model和modeless对话框的特性:
|
Model |
Modeless |
使用构造函数 |
带有资源ID参数的构造函数 |
默认的构造函数(无参数) |
使用创建窗口的函数 |
DoModal() |
带有资源ID参数的 Create(……)函数 |
注:这里我觉得有点异议,就是默认构造函数应该是使用一个接受parent即触发对象的类成员。
3、第一点我们为构造函数准备了参数对象,第二步了解到了要调用create函数,那么接下来的的动作就是很简单了,准备构造函数,准备create函数。
4、添加:
CmyDlg(CView *view);
BOOL create();
5、第一步添加了一个对象,那么就要在系统默认提供的构造函数里面添加pView对象的初始化,而且要知道这个函数是为model对话框设计的:
CmyDlg::CmyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CmyDlg::IDD, pParent)
{
pView = NULL;//这里就添加上去的
}
6、为我们的modeless对话框添加一个对话框构造函数,这里的这个函数就是带一个触发对象的参数的构造函数,如下:
CmyDlg::CmyDlg(CView *view) {
pView = view;
}
用CView *view对象来初始化pView对象。
7、准备create函数:
BOOL CmyDlg::create() {
return CDialog::Create(CmyDlg::IDD);
}
这里这个函数为什么这么创建呢?很简单,上面的那个表已经说的很清楚了,而且第五步的那个model的构造函数也已经提示了,model的使用了IDD但是我们给出的modeless对话框的构造函数却没有使用IDD,因此,用带IDD参数的的对话框类成员函数create(……)来创建可视的对话框。
到这里为止我们已经知道了如何初始化一个modeless对话框对象,也晓得怎么创建了,那么接下来的事情就是在要调用的地方触发这个创建事件:
9、开始已经说过,第一步的添加的成员对象是为了指定触发对象的,那么我们的这个modeless对话框就应该由一个CView对象来触发。来到相应的……view头文件和.cpp文件里面添加我们想要的相关的内容:
#include "myDlg.h"
这个是modeless对话框的实现的类的头文件,首先加入……view头文件,然后在头文件里,添加一个对话框对象指针,而不是对象,因为我们的初始化要在类的构造函数里面来给定:
CmyDlg *pmyDlg;
来到……view.cpp头文件在构造函数里面改写成这么一段:
Cmodeless1View::Cmodeless1View()
{
// TODO: add construction code here
pmyDlg = new CmyDlg(this);
}
Cmodeless1View::~Cmodeless1View()
{
delete pmyDlg;
}
在构造函数里new,当然要在析构函数里delete,这个不是MFC里面的东西。
10、给……view类添加两个鼠标点击的事件,一个左键点击产生,右键点击销毁的消息,得到两个消息处理函数,我们改写一下:
// Cmodeless1View message handlers
void Cmodeless1View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
pmyDlg->create();
CView::OnLButtonDown(nFlags, point);
}
void Cmodeless1View::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
pmyDlg->DestroyWindow();
CView::OnRButtonDown(nFlags, point);
}
这就很简单了。
如图:
我们再看看从别的对象触发一个modeless对话框:就从一个对话框触发,效果如下:
同时触发model和modeless:
其实很简单,这个也是我琢磨了一下弄出来的,只要处理一下触发源即可。如下步骤,其实也可以很简单:
先创建这么2个对话框,有一个是AboutDlg对话框,自动生成的,我们创建工程的时候这样,选择给予对话框的工程:
1、 Cmymodeless.h中添加:
private:
CDialog *pDlg;
public:
Cmymodeless(CDialog *Dlg);
BOOL create();
2、 修改Cmymodeless.cpp:
Cmymodeless::Cmymodeless(CWnd* pParent /*=NULL*/)
: CDialog(Cmymodeless::IDD, pParent)
{
pDlg = NULL;
}
Cmymodeless::Cmymodeless(CDialog *Dlg) {
pDlg = Dlg;
}
BOOL Cmymodeless::create() {
return CDialog::Create(Cmymodeless::IDD);
}
3、 修改Cmodeless_to_dialogDlg.h,添加如下两项:
#include "mymodeless.h"
在Cmodeless_to_dialogDlg里面添加:
public:
Cmymodeless *pMymodelessDlg;
4、 修改Cmodeless_to_dialogDlg.cpp:
Cmodeless_to_dialogDlg::Cmodeless_to_dialogDlg(CWnd* pParent /*=NULL*/)
: CDialog(Cmodeless_to_dialogDlg::IDD, pParent)
{
pMymodelessDlg = new Cmymodeless(this);
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
pMymodelessDlg = new Cmymodeless(this);这句是添加的,其实就是让对话框成为其构造源。
7、添加消息函数:
void Cmodeless_to_dialogDlg::OnBnClickedButton2()
{
// TODO: Add your control notification handler code here
pMymodelessDlg->create();
}
void Cmodeless_to_dialogDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CAboutDlg my;
my.DoModal();
}
便一切OK了哈哈。