首页 > 代码库 > MFC控件数据交换:DDX
MFC控件数据交换:DDX
MFC中操纵控件
操作控件的两种方式:
方式1 通过调用CWnd::GetDlgItem()函数,根据控件ID获取控件对象指针,操作控件即可。
对话框的初始化函数:OnInitDialog()
方式2 对话框的数据交换技术(DDX)
将控件和一个成员变量绑定,可以通过操作成员变量达到操作控件的目的。
1 定义与控件绑定的成员变量
2 在对话框中添加DoDataExchange()函数,在函数中完成控件
与变量的绑定。
DDX_Control()//控件类型的绑定
DDX_Text()//值类型的绑定
3 通过成员变量完成对控件的操作
4 值类型的绑定,还需要调用UpdateData(BOOL)函数
UpdateData(TRUE)- 控件中的值传赋值变量(接收)
跟进:
跟进:
Ok到这里就清晰了
跟进:
操作控件的两种方式:
方式1 通过调用CWnd::GetDlgItem()函数,根据控件ID获取控件对象指针,操作控件即可。
对话框的初始化函数:OnInitDialog()
方式2 对话框的数据交换技术(DDX)
将控件和一个成员变量绑定,可以通过操作成员变量达到操作控件的目的。
1 定义与控件绑定的成员变量
2 在对话框中添加DoDataExchange()函数,在函数中完成控件
与变量的绑定。
DDX_Control()//控件类型的绑定
DDX_Text()//值类型的绑定
3 通过成员变量完成对控件的操作
4 值类型的绑定,还需要调用UpdateData(BOOL)函数
UpdateData(TRUE)- 控件中的值传赋值变量(接收)
UpdateData(FALSE)-将变量的值显示到控件上
新建一个Win32 Application,选择A Simple Win32 Application,修改stdafx.h 中的windwos.h为afxwin.h,工程属性设置使用MFC静态库
编写如下测试代码
// DDX.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" class CMyDlg : public CDialog { public: CMyDlg ():CDialog(IDD_DIALOG1){} virtual void DoDataExchange (CDataExchange* pDX); virtual BOOL OnInitDialog (); virtual void OnOK(); protected: CButton m_wndOK; CString m_strEdit; }; void CMyDlg::DoDataExchange (CDataExchange* pDX) { //完成控件与变量的绑定 DDX_Control (pDX, IDOK, m_wndOK); DDX_Text (pDX, IDC_EDIT1, m_strEdit); } BOOL CMyDlg::OnInitDialog () { if (!CDialog::OnInitDialog()) return FALSE; // 初始化控件 // 方式一:通过GetDlgItem操作控件 CWnd *pWnd = GetDlgItem (IDCANCEL); pWnd->EnableWindow (FALSE); m_wndOK.MoveWindow (0, 0, 100, 100); m_wndOK.SetWindowText ("DDXOK"); // 方式二:通过DDX操作控件 m_strEdit = "Hello you"; UpdateData (FALSE); return TRUE; } void CMyDlg::OnOK () { // 接收控件的值到关联的变量 UpdateData (TRUE); AfxMessageBox (m_strEdit); CDialog::OnOK(); } class CMyWinApp : public CWinApp { public: virtual BOOL InitInstance (); }; CMyWinApp theApp; BOOL CMyWinApp::InitInstance () { CMyDlg dlg; m_pMainWnd = &dlg; dlg.DoModal (); return TRUE; }
DDX的实现原理
1 控件类型的绑定
DDX_Control (pDX, IDOK, m_wndOK);跟进:
void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl) {// nIDC: IDCOK , rControl: m_wndOK ................................... // 通过控件ID得到控件句柄 HWND hWndCtrl = pDX->PrepareCtrl(nIDC); if (!rControl.SubclassWindow(hWndCtrl)) { .......................................... } }
DDX_Control-->SubclassWindow
跟进:
BOOL CWnd::SubclassWindow(HWND hWnd) {// this == m_wndOK, hWnd == 控件句柄 // 将m_wndOK控件变量与OK按钮句柄绑定 if (!Attach(hWnd)) return FALSE; ............................................... }
DDX_Control-->SubclassWindow-->Attach跟进:
BOOL CWnd::Attach(HWND hWndNew) {//this == m_wndOK, hWndNew == 控件句柄 ...................................... CHandleMap* pMap = afxMapHWND(TRUE); // create map if not exist ASSERT(pMap != NULL); // 建立映射关系 pMap->SetPermanent(m_hWnd = hWndNew, this); ........................................ }
DDX_Control-->SubclassWindow-->Attach-->SetPermanent
跟进:
void CHandleMap::SetPermanent(HANDLE h, CObject* permOb) { ....................................... // 以控件句柄为键,以变量句柄为值建立映射关系 m_permanentMap[(LPVOID)h] = permOb; ......................................... }
Ok到这里就清晰了
总结流程如下:
DDX_Control(pDX,IDOK,m_wndOK); { //通过控件ID得到控件句柄 HWND hWndCtrl = pDX->PrepareCtrl(nIDC); //将控件句柄与变量绑定 rControl.SubclassWindow(hWndCtrl); { Attach(hWnd); { pMap->SetPermanent(m_hWnd = hWndNew, this); { //以句柄为健,以变量地址为值建立映射关系 m_permanentMap[(LPVOID)h] = permOb; } } } }
2 值类型的绑定
UpdateData (FALSE);跟进:
BOOL CWnd::UpdateData(BOOL bSaveAndValidate) {// this == &dlg, bSaveAndValidate == FALSE ............................................. CDataExchange dx(this, bSaveAndValidate); .......................................... // 虚函数,会调用我们重写的函数 DoDataExchange(&dx); ........................................ }
UpdateData-->DoDataExchange-->CMyDlg::DoDataExchange-->DDX_Text
跟进:
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CString& value) {// pDX中保存了&dlg和FALSE, nIDC == IDOK, value =http://www.mamicode.com/= m_strEdit>
总结上面的流程如下:UpdateData(FALSE); { CDataExchange dx(this, bSaveAndValidate); DoDataExchange(&dx); { DDX_Text(pDX,IDC_EDIT1,m_strEdit); { //通过控件ID得到控件句柄 HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC); if (pDX->m_bSaveAndValidate) { ::GetWindowText(hWndCtrl,...); value.ReleaseBuffer(); } else { //将变量的值设置到控件的窗口上 AfxSetWindowText(hWndCtrl, value); } } } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。