《MFC那点事儿》の访问对话框控件的方式

获取和设置对话框控件标题或内容的相关方法介绍:

0)先来看一个获取窗口中指定控件或子窗口指针的函数CWnd::GetDlgItem

CWnd* GetDlgItem(

int nID //控件或子窗口的ID

) const;

void GetDlgItem(

int nID, //控件或子窗口的ID

HWND* phWnd //指向子窗口的指针

) const;

“返回值”是指向控件或子窗口的指针,如果指定nID控件不存在,返回值是NULL

要注意的是:返回的指针可能是临时的,因此不能存下来以待后面使用。我们通常会将返回的指针转换为nID指向控件的类型。例如:

// uses GetDlgItem to return a pointer to a user interface control

CEdit* pBoxOne;

pBoxOne = (CEdit*)GetDlgItem(IDC_ASCEEDIT);

GotoDlgCtrl(pBoxOne);

1CWnd::GetWindowText函数实现获取CWnd的标题内容,或者当CWnd对象是一个控件时,函数将获取控件中文本内容而不是标题内容;函数原型如下:

int GetWindowText(

LPTSTR lpszStringBuf, //接收返回的内容的缓冲区

int nMaxCount //复制到缓冲区的最大字符个数

) const;

void GetWindowText(

CString& rString //接收返回的内容的CString对象

) const;

第一个函数的返回值是复制的字符个数,不包括null结束符;当CWnd没有标题或标题为空时返回0

该成员函数使得WM_GETTEXT消息发送给CWnd对象。

CWnd::SetWindowText函数实现设置CWnd对象的标题内容,而当CWnd对象是一个控件时,函数将设置控件中文本内容,函数原型如下:

void SetWindowText(

LPCTSTR lpszString

);

实例代码如下:

// set the text in IDC_EDITNAME

CWnd* pWnd = GetDlgItem(IDC_EDITNAME);

pWnd->SetWindowText(_T("Gerald Samper"));

// Get the text back. CString is convenient, because MFC

// will automatically allocate enough memory to hold the

// text--no matter how large it is.

CString str;

pWnd->GetWindowText(str);

ASSERT(str == _T("Gerald Samper"));

// The LPTSTR override works, too, but it might be too short.

// If we supply a buffer that's too small, we'll only get those

// characters that fit.

TCHAR sz[10];

int nRet = pWnd->GetWindowText(sz, 10);

// Nine characters, plus terminating null

ASSERT(_tcscmp(sz, _T("Gerald Sa")) == 0);

ASSERT(nRet == 9);

// You can query the length of the text without the length of

// the string using CWnd::GetWindowTextLength()

nRet = pWnd->GetWindowTextLength();

ASSERT(nRet == 13);

2CWnd::GetDlgItemText函数用来返回对话框中指定ID的控件上的文本,也就是说,GetDlgItemText函数将GetDlgItemGetWindowText这两个函数的功能组合起来了:

int GetDlgItemText(

int nID, //控件的ID

LPTSTR lpStr, //指向接收控件标题或文本的缓冲区的指针

int nMaxCount //复制到缓冲区的最大字符个数

) const;

int GetDlgItemText(

int nID, //控件ID

CString& rString //接收控件标题或文本内容

) const;

函数返回值是实际复制到缓冲区的字符个数,不包括null结束符;当没有复制任何东西时,返回0

CWnd::SetDlgItemText函数用来设置对话框中指定控件的标题或文本:

void SetDlgItemText(

int nID, //控件ID

LPCTSTR lpszString //要设置的内容

);

该函数将发送一个WM_SETTEXT消息给指定的控件。

3CWnd::GetDlgItemInt函数用来获取指定控件的文本,并将其转换为一个整型数值:

UINT GetDlgItemInt(

int nID, //控件ID

BOOL* lpTrans = NULL, //指向一个布尔型变量,该变量接收转换成功与否标志

BOOL bSigned = TRUE //指定被检索的值是否有符号

) const;

返回值是转换后的整型值。该函数将向控件发送一个WM_GETTEXT消息。

CWnd::SetDlgItemInt函数用指定的数值来设置指定控件的文本:

void SetDlgItemInt(

int nID, //控件ID

UINT nValue, //指定用来产生控件上文本的整型数值

BOOL bSigned = TRUE //指定数值是否是有符号数字

);

该函数的调用将发送一个WM_SETTEXT消息给指定的控件。

4)为了将对话框控件与对话框类成员变量相关联,我们可以使ClassWizard来帮助我们完成(VC6.0VC10.0中有ClassWizard)。首先打开ClassWizard对话框,并单击Member Variable选项卡,在Class name下拉列表框中选择CASCEDlg,这时在Control IDs列表中将列出这个对话框中的所有控件的ID。接着就可以为指定的控件ID关联成员变量,这里选择变量的类别是:Value,变量的类型是int,关联了几个变量后,实例代码如下:

在类的头文件中,可以看到在两个AFX_DATA注释宏之间增加了三个成员变量:

//{{AFX_DATA(CASCEDlg)

enum { IDD = IDD_DIALOG_ASCE };

int m_num1;

int m_num2;

int m_total;

//}}AFX_DATA

而在CASCEDlg类的构造函数中,可以看到对这三个成员变量进行了初始化:

CASCEDlg::CASCEDlg(CWnd* pParent /*=NULL*/)

: CDialog(CASCEDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CASCEDlg)

m_num1 = 0;

m_num2 = 0;

m_total = 0;

//}}AFX_DATA_INIT

}

而接着在DoDataExchange函数中完成了对话框数据的交换和校验,在这个函数内部调用了三个DDX_TEXT函数,后者的功能就是将ID指定的控件与特定的类成员变量相关联。因此,在DoDataExchange函数内部实现了对话框控件与类成员变量的关联:

void CASCEDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CASCEDlg)

DDX_Text(pDX, IDC_EDIT1, m_num1);

DDX_Text(pDX, IDC_EDIT2, m_num2);

DDX_Text(pDX, IDC_EDIT_TOTAL, m_total);

//}}AFX_DATA_MAP

}

注:MFC提供了多种DDX_为前缀的函数,这些函数分别用于不同控件的数据交换。

这之后,就可以使用这些成员变量了,例如实现m_total是前面两个变量的和:

m_total = m_num1 + m_num2;

但是在代码中仅仅写这一句是实现不了编辑框的赋值的,因为对话框数据交换是由DoDataExchange函数完成的,但在程序代码中从来不能直接调用这个函数,而是通过CWnd::UpdateData来调用。通过后者来初始化对话框控件或从对话框获取数据。即为了是数据生效,需要在代码中调用UpdateData函数:

BOOL UpdateData(

BOOL bSaveAndValidate = TRUE

);

当参数bSaveAndValidateTRUE时,说明该函数正在获取对话框数据;当为FALSE时,说明该函数正在初始化对话框的控件。因此,实现相加并显示在编辑框中的完整代码是:

UpdateData();

m_total = m_num1 + m_num2;

UpdateData(FALSE);

5)同样使用ClassWizard,但这次我们将编辑框控件关联到一个控件变量,即代表控件本身。即在选择变量类型时选择Control,此时,变量类型会自动变为CEdit。同样添加三个成员变量,此时头文件代码片段我为:

//{{AFX_DATA(CASCEDlg)

enum { IDD = IDD_DIALOG_ASCE };

CEdit m_edit1;

CEdit m_edit2;

CEdit m_edit_total;

int m_num1;

int m_num2;

int m_total;

//}}AFX_DATA

而在CASCEDlg类的DoDataExchange函数中增加了三个DDX_Control函数,分别将一个对话框控件与一个变量相关联:

void CASCEDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CASCEDlg)

DDX_Control(pDX, IDC_EDIT1, m_edit1);

DDX_Control(pDX, IDC_EDIT2, m_edit2);

DDX_Control(pDX, IDC_EDIT_TOTAL, m_edit_total);

DDX_Text(pDX, IDC_EDIT1, m_num1);

DDX_Text(pDX, IDC_EDIT2, m_num2);

DDX_Text(pDX, IDC_EDIT_TOTAL, m_total);

//}}AFX_DATA_MAP

}

而这些控件变量代表的就是控件本身,并且CEdit类派生于CWnd类,因此,可以利用这些控件变量调用GetWindowTextSetWindowText这两个函数来获取和设置编辑框中的文本。

6Windows程序都是基于消息的系统,为了获取或设置窗口的文本,只要知道获取或设置窗口文本的消息,就可以通过SendMessage来发送这条消息,从而获取或设置窗口的文本。

Windows系统中,获取窗口文本的消息是WM_GETTEXT,发送该消息后,系统将把指定窗口的文本复制到调用者提供的一个缓存中。在这个消息的两个附加参数中,wParam指定将复制的字符数,lParam就是调用者提供的用来保存窗口文本的缓存地址。

而设置窗口文本的消息是WM_SETTEXT,这个消息的wParam参数没有用到,值为0;而lParam参数指定了用来设置窗口文本的字符串地址。

实例代码如下:

void CASCEDlg::OnBtnAdd()

{

int num1, num2, numTotal;

char ch1[10], ch2[10], ch3[10];

::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd, WM_GETTEXT, 10, (LPARAM)ch1);

::SendMessage(m_edit2.m_hWnd, WM_GETTEXT, 10, (LPARAM)ch2);

num1 = atoi(ch1);

num2 = atoi(ch2);

numTotal = num1 + num2;

itoa(numTotal, ch3, 10);

m_edit_total.SendMessage(WM_SETTEXT, 0, (LPARAM)ch3);

}

7)直接给对话框中的子控件发送消息,使用函数CWnd::SendDlgItemMessage

LRESULT SendDlgItemMessage(

int nID, //要接收该消息的对话框中控件的ID

UINT message, //要发送的消息类型

WPARAM wParam = 0, //

LPARAM lParam = 0 //

);

该函数的功能相当于GetDlgItemSendMessage函数的组合。因为SendDlgItemMessage函数本身就是在一个对话框中给它的子控件发送消息时使用的,因此在调用时不必先获得子控件对象,再发送消息,可以直接给子控件发送消息:

void CASCEDlg::OnBtnAdd()

{

int num1, num2, numTotal;

char ch1[10], ch2[10], ch3[10];

SendDlgItemMessage(IDC_EDIT1, WM_GETTEXT, 10, (LPARAM)ch1);

SendDlgItemMessage(IDC_EDIT2, WM_GETTEXT, 10, (LPARAM)ch2);

num1 = atoi(ch1);

num2 = atoi(ch2);

numTotal = num1 + num2;

itao(numTotal, ch3, 10);

SendDlgItemMessage(IDC_EDIT_TOTAL, WM_SETTEXT, 0, (LPARAM)ch3);

}

最后总结上面的七种访问对话框控件的方式:

1GetDlgItem()->Get(Set)WindowText();(常用)

2GetDlgItemText()/SetDlgItemText()

3GetDlgItemInt()/SetDlgItemInt()

4)将控件和非控件变量相关联;(常用)

5)将控件和控件变量相关联;(常用)

6SendMessage()

7SendDlgItemMessage()

你可能感兴趣的:(mfc)