首页 > 代码库 > C++MFC编程笔记day08 MFC对话框的使用
C++MFC编程笔记day08 MFC对话框的使用
一 MFC对话框
1 分类
模式和非模式
2 相关类
CDialog类-父类是CWnd,本质上是一个窗口,对话框类的父类。
CCommonDialog类以及子类-通用对话框,颜色对话框、文件对话框、
查找替换对话框、字体设置对话框、打印设置对话框和
打印对话框。
CPropertyPage类-属性页对话框。
3 在Win32向导中,使用MFC的类创建对话框程序
3.1 模式对话框
3.1.1 创建和显示对话框
CDialog::DoModal()
3.1.2 对话框的关闭(无需用户处理)
CDialog::OnOK/OnCancel
3.2 非模式对话框
3.2.1 创建和显示对话框
类似于一般窗口的创建过程
3.2.2 对话框的关闭
1 重写CDialog::OnOK/OnCancel函数,在函数中:
DestroyWindow()
2 重写CWnd::PostNcDestroy函数,在函数中:
delete this;
3.3 创建单文档程序,使用菜单分别打开模式/非模式对话框
对比运行时的效果
3.4 跟踪DoModal()函数的执行过程
3.4.1 查找和加载对话框资源
3.4.2 将父窗口设置为不可用状态
3.4.3 创建对话框
3.4.4 进入对话框的消息循环
3.4.5 当点击OK或则Cancel按钮后,退出循环
3.4.6 隐藏了对话框窗口,将父窗口设置为可用状态
3.4.7 销毁对话框
3.4.8 释放对话框资源
3.4.9 返回DoModal()函数的返回值
示例:
新建win32 应用程序 ,然后改为支持MFC,并手动创建代码:
// DlgApp.cpp : Defines the entry point for the application.
//
#include "stdafx.h"//#include <afxwin.h>
#include "resource.h"
class CMyDlg:public CDialog
{
public:
CMyDlg():CDialog(IDD_DIALOG1){}//关联对话框资源ID
//以下3函数,使用非模式对话框时要重写实现
virtual void PostNcDestroy( );
virtual void OnOK( );
virtual void OnCancel();
};
void CMyDlg::OnOK()
{
CDialog::OnOK();
DestroyWindow();
}
void CMyDlg::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
void CMyDlg::PostNcDestroy()
{
CWnd::PostNcDestroy();
delete this;
}
class CDlgApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CDlgApp theApp;
BOOL CDlgApp::InitInstance()
{
/* 模式对话框
CMyDlg dlg;
m_pMainWnd=&dlg;
dlg.DoModal();//创建和显示模式对话框
*/
//非模式对话框
CMyDlg *pDlg=new CMyDlg;
pDlg->Create(IDD_DIALOG1);//对话框资源ID
m_pMainWnd=pDlg;
pDlg->ShowWindow(SW_SHOW);
return TRUE;
}
二 对话框的数据交换技术(DDX)
引入它的目的是方便操作控件和获取/设置控件的值
可以将控件与对话框的成员变量绑定,通过操作对话框的成员变量来
达到操作控件的目的。
1 相关函数
1.1 一系列的绑定函数
DDX_Control ,绑定控件类型的变量
DDX_Text ,绑定值类型的变量
例如,对话框中有一个编辑框控件,ID,ID_EDIT1
对话框类中的变量,CString m_strText;//值类型的变量
int m_nText;//值类型的变量
CEdit m_wndText;//控件类型的变量
1.2 对话框数据交换函数,包含1.1绑定函数
CWnd::DoDataExchange
1.3 当值类型(CString)成员变量与控件之间有数据交换时,调用以下函数:
UpdateData()
UpdateData(TRUE)-控件的值传递给成员变量
UpdateData(FALSE)-成员变量的值放到控件上显示
2 使用
3 原理
3.1 DDX_Control-控件类型的绑定函数
DDX_Control(CDataExchange* pDX, ...)
{
//1根据控件的ID,得到控件的句柄
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
//2 将控件类型的变量与控件的句柄建立映射关系
rControl.SubclassWindow(hWndCtrl)
{
Attach(hWndCtrl);
}
}
3.2 DDX_Text-值类型的绑定函数
DDX_Text(CDataExchange* pDX, int nIDC,...)
{
//1根据控件的ID,得到控件的句柄
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
//2 变量与控件相互赋值
if (pDX->m_bSaveAndValidate)
{
int nLen = ::GetWindowTextLength(hWndCtrl);
::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen), nLen+1);
value.ReleaseBuffer();
}
else
{
AfxSetWindowText(hWndCtrl, value);
}
}
4 函数的调用关系,为什么我们会在CMyDlg::OnInitDialog(),首先
调用它的父类CDialog::OnInitDialog()?
只有调用CDialog::OnInitDialog(),对话框显示前,才能将
控件与变量绑定。具体的调用关系:
CDialog::OnInitDialog()
{
UpdateData(FALSE);
{
DoDataExchange(pDx);
{
DDX_Control();
DDX_Text();
}
}
}
示例,建立win32 应用程序,然后手动改为支持MFC,再写代码:
// DlgDDX.cpp : Defines the entry point for the application.
//
#include "stdafx.h"//#include <afxwin.h>
#include "resource.h"
class CMyDlg:public CDialog
{
public:
CMyDlg():CDialog(IDD_DIALOG1){}//关联对话框资源ID
//以下3函数,非模式对话框时要重写实现
virtual void PostNcDestroy( );
virtual void OnOK( );
virtual void OnCancel();
virtual BOOL OnInitDialog();
virtual void DoDataExchange(CDataExchange* pDX);
CButton m_wndOK;//与ok按钮绑定的控件
CString m_wndEdit1;
};
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX,IDOK,m_wndOK);//界面上控件与成员变量绑定
DDX_Text(pDX,IDC_EDIT1,m_wndEdit1);
}
void CMyDlg::OnOK()
{
UpdateData(TRUE);
AfxMessageBox(m_wndEdit1);
//CDialog::OnOK();
//DestroyWindow();
}
void CMyDlg::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
void CMyDlg::PostNcDestroy()
{
CWnd::PostNcDestroy();
delete this;
}
//对话框初始化
BOOL CMyDlg::OnInitDialog()
{
if(!CDialog::OnInitDialog())
{
return FALSE;
}
CWnd* pbtn = GetDlgItem(IDCANCEL);//获取控件
pbtn->EnableWindow(FALSE);//设置为不可用
m_wndOK.MoveWindow(0,0,100,100,TRUE);//操作绑定的成员变量等于操作控件
m_wndOK.SetWindowText("DDX_OK");
m_wndEdit1="123";
UpdateData(FALSE);
return TRUE;
}
class CDlgApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CDlgApp theApp;
BOOL CDlgApp::InitInstance()
{
///* 模式对话框
CMyDlg dlg;
m_pMainWnd=&dlg;
dlg.DoModal();//创建和显示模式对话框
//*/
return TRUE;
}
三 实现登录功能
在主窗口显示前,设置登陆对话框,登陆通过了,才显示主窗口:
CDialogLogin dlglogin;
if(IDOK!=dlglogin.DoModal()) return false;
添加控件与值绑定:
Ctrl+w ,选择 member variables 选项卡,添加与控件对应的变量。
登陆对话框处理:
void CDialogLogin::OnOK()
{
UpdateData(TRUE);//更新控件值到变量中
if(m_UserName=="123" && m_UserPwd=="123")//模拟登陆
{
CDialog::OnOK();
}
else
{
AfxMessageBox("用户名或密码错误!");
}
}
示例:
1、创建MFC对话框应用程序
4、ctrl+w添加成员绑定:
5、在app的IninInstance函数中,加入代码:
CDialogLogin dlglogin;
if(IDOK!=dlglogin.DoModal()) return false;
意思是,如果登陆框没有返回IDOK就不显示主框架窗口。
添加点击确定按钮时的消息映射:
//CDialogLogin中实现点击登陆的代码:
void CDialogLogin::OnOK()
{
UpdateData(TRUE);
if(m_UserName=="123" && m_UserPwd=="123")//模拟登陆
{
CDialog::OnOK();//默认关闭对话框,返回IDOK
}
else
{
AfxMessageBox("用户名或密码错误!");
}
1 分类
模式和非模式
2 相关类
CDialog类-父类是CWnd,本质上是一个窗口,对话框类的父类。
CCommonDialog类以及子类-通用对话框,颜色对话框、文件对话框、
查找替换对话框、字体设置对话框、打印设置对话框和
打印对话框。
CPropertyPage类-属性页对话框。
3 在Win32向导中,使用MFC的类创建对话框程序
3.1 模式对话框
3.1.1 创建和显示对话框
CDialog::DoModal()
3.1.2 对话框的关闭(无需用户处理)
CDialog::OnOK/OnCancel
3.2 非模式对话框
3.2.1 创建和显示对话框
类似于一般窗口的创建过程
3.2.2 对话框的关闭
1 重写CDialog::OnOK/OnCancel函数,在函数中:
DestroyWindow()
2 重写CWnd::PostNcDestroy函数,在函数中:
delete this;
3.3 创建单文档程序,使用菜单分别打开模式/非模式对话框
对比运行时的效果
3.4 跟踪DoModal()函数的执行过程
3.4.1 查找和加载对话框资源
3.4.2 将父窗口设置为不可用状态
3.4.3 创建对话框
3.4.4 进入对话框的消息循环
3.4.5 当点击OK或则Cancel按钮后,退出循环
3.4.6 隐藏了对话框窗口,将父窗口设置为可用状态
3.4.7 销毁对话框
3.4.8 释放对话框资源
3.4.9 返回DoModal()函数的返回值
示例:
新建win32 应用程序 ,然后改为支持MFC,并手动创建代码:
// DlgApp.cpp : Defines the entry point for the application.
//
#include "stdafx.h"//#include <afxwin.h>
#include "resource.h"
class CMyDlg:public CDialog
{
public:
CMyDlg():CDialog(IDD_DIALOG1){}//关联对话框资源ID
//以下3函数,使用非模式对话框时要重写实现
virtual void PostNcDestroy( );
virtual void OnOK( );
virtual void OnCancel();
};
void CMyDlg::OnOK()
{
CDialog::OnOK();
DestroyWindow();
}
void CMyDlg::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
void CMyDlg::PostNcDestroy()
{
CWnd::PostNcDestroy();
delete this;
}
class CDlgApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CDlgApp theApp;
BOOL CDlgApp::InitInstance()
{
/* 模式对话框
CMyDlg dlg;
m_pMainWnd=&dlg;
dlg.DoModal();//创建和显示模式对话框
*/
//非模式对话框
CMyDlg *pDlg=new CMyDlg;
pDlg->Create(IDD_DIALOG1);//对话框资源ID
m_pMainWnd=pDlg;
pDlg->ShowWindow(SW_SHOW);
return TRUE;
}
二 对话框的数据交换技术(DDX)
引入它的目的是方便操作控件和获取/设置控件的值
可以将控件与对话框的成员变量绑定,通过操作对话框的成员变量来
达到操作控件的目的。
1 相关函数
1.1 一系列的绑定函数
DDX_Control ,绑定控件类型的变量
DDX_Text ,绑定值类型的变量
例如,对话框中有一个编辑框控件,ID,ID_EDIT1
对话框类中的变量,CString m_strText;//值类型的变量
int m_nText;//值类型的变量
CEdit m_wndText;//控件类型的变量
1.2 对话框数据交换函数,包含1.1绑定函数
CWnd::DoDataExchange
1.3 当值类型(CString)成员变量与控件之间有数据交换时,调用以下函数:
UpdateData()
UpdateData(TRUE)-控件的值传递给成员变量
UpdateData(FALSE)-成员变量的值放到控件上显示
2 使用
3 原理
3.1 DDX_Control-控件类型的绑定函数
DDX_Control(CDataExchange* pDX, ...)
{
//1根据控件的ID,得到控件的句柄
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
//2 将控件类型的变量与控件的句柄建立映射关系
rControl.SubclassWindow(hWndCtrl)
{
Attach(hWndCtrl);
}
}
3.2 DDX_Text-值类型的绑定函数
DDX_Text(CDataExchange* pDX, int nIDC,...)
{
//1根据控件的ID,得到控件的句柄
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
//2 变量与控件相互赋值
if (pDX->m_bSaveAndValidate)
{
int nLen = ::GetWindowTextLength(hWndCtrl);
::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen), nLen+1);
value.ReleaseBuffer();
}
else
{
AfxSetWindowText(hWndCtrl, value);
}
}
4 函数的调用关系,为什么我们会在CMyDlg::OnInitDialog(),首先
调用它的父类CDialog::OnInitDialog()?
只有调用CDialog::OnInitDialog(),对话框显示前,才能将
控件与变量绑定。具体的调用关系:
CDialog::OnInitDialog()
{
UpdateData(FALSE);
{
DoDataExchange(pDx);
{
DDX_Control();
DDX_Text();
}
}
}
示例,建立win32 应用程序,然后手动改为支持MFC,再写代码:
// DlgDDX.cpp : Defines the entry point for the application.
//
#include "stdafx.h"//#include <afxwin.h>
#include "resource.h"
class CMyDlg:public CDialog
{
public:
CMyDlg():CDialog(IDD_DIALOG1){}//关联对话框资源ID
//以下3函数,非模式对话框时要重写实现
virtual void PostNcDestroy( );
virtual void OnOK( );
virtual void OnCancel();
virtual BOOL OnInitDialog();
virtual void DoDataExchange(CDataExchange* pDX);
CButton m_wndOK;//与ok按钮绑定的控件
CString m_wndEdit1;
};
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX,IDOK,m_wndOK);//界面上控件与成员变量绑定
DDX_Text(pDX,IDC_EDIT1,m_wndEdit1);
}
void CMyDlg::OnOK()
{
UpdateData(TRUE);
AfxMessageBox(m_wndEdit1);
//CDialog::OnOK();
//DestroyWindow();
}
void CMyDlg::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
void CMyDlg::PostNcDestroy()
{
CWnd::PostNcDestroy();
delete this;
}
//对话框初始化
BOOL CMyDlg::OnInitDialog()
{
if(!CDialog::OnInitDialog())
{
return FALSE;
}
CWnd* pbtn = GetDlgItem(IDCANCEL);//获取控件
pbtn->EnableWindow(FALSE);//设置为不可用
m_wndOK.MoveWindow(0,0,100,100,TRUE);//操作绑定的成员变量等于操作控件
m_wndOK.SetWindowText("DDX_OK");
m_wndEdit1="123";
UpdateData(FALSE);
return TRUE;
}
class CDlgApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CDlgApp theApp;
BOOL CDlgApp::InitInstance()
{
///* 模式对话框
CMyDlg dlg;
m_pMainWnd=&dlg;
dlg.DoModal();//创建和显示模式对话框
//*/
return TRUE;
}
三 实现登录功能
在主窗口显示前,设置登陆对话框,登陆通过了,才显示主窗口:
CDialogLogin dlglogin;
if(IDOK!=dlglogin.DoModal()) return false;
添加控件与值绑定:
Ctrl+w ,选择 member variables 选项卡,添加与控件对应的变量。
登陆对话框处理:
void CDialogLogin::OnOK()
{
UpdateData(TRUE);//更新控件值到变量中
if(m_UserName=="123" && m_UserPwd=="123")//模拟登陆
{
CDialog::OnOK();
}
else
{
AfxMessageBox("用户名或密码错误!");
}
}
示例:
1、创建MFC对话框应用程序
2、添加对话框,ID为IDD_DIALOG_LOGIN,并修改界面控件。
4、ctrl+w添加成员绑定:
5、在app的IninInstance函数中,加入代码:
CDialogLogin dlglogin;
if(IDOK!=dlglogin.DoModal()) return false;
意思是,如果登陆框没有返回IDOK就不显示主框架窗口。
添加点击确定按钮时的消息映射:
//CDialogLogin中实现点击登陆的代码:
void CDialogLogin::OnOK()
{
UpdateData(TRUE);
if(m_UserName=="123" && m_UserPwd=="123")//模拟登陆
{
CDialog::OnOK();//默认关闭对话框,返回IDOK
}
else
{
AfxMessageBox("用户名或密码错误!");
}
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。