获取和设置对话框控件标题或内容的相关方法介绍:
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);
1)CWnd::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);
2)CWnd::GetDlgItemText函数用来返回对话框中指定ID的控件上的文本,也就是说,GetDlgItemText函数将GetDlgItem和GetWindowText这两个函数的功能组合起来了:
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消息给指定的控件。
3)CWnd::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.0和VC10.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
);
当参数bSaveAndValidate是TRUE时,说明该函数正在获取对话框数据;当为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类,因此,可以利用这些控件变量调用GetWindowText和SetWindowText这两个函数来获取和设置编辑框中的文本。
6)Windows程序都是基于消息的系统,为了获取或设置窗口的文本,只要知道获取或设置窗口文本的消息,就可以通过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 //
);
该函数的功能相当于GetDlgItem和SendMessage函数的组合。因为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);
}
最后总结上面的七种访问对话框控件的方式:
1)GetDlgItem()->Get(Set)WindowText();(常用)
2)GetDlgItemText()/SetDlgItemText();
3)GetDlgItemInt()/SetDlgItemInt();
4)将控件和非控件变量相关联;(常用)
5)将控件和控件变量相关联;(常用)
6)SendMessage();
7)SendDlgItemMessage()。