昨天学习了MFC的对话框的添加和简单的使用,了解到对话框有模态和非模态两种区别。今天继续学习对话框的使用,主要是来讨论对话框控件的访问。我们今天使用VS2008新建一个MyDlg1项目,然后按照昨天的思路添加资源对话框,创建CDlg类绑定对话框资源,然后添加菜单“对话框”用于点击时显示模态的对话框。具体的步骤是:
1. 添加新资源:对话框
2. 为对话框创建类CDlg::publicCDialog
3. 新建菜单“对话框”
4. 为“对话框”添加事件响应,添加到View类下
5. 在响应函数中添加创建显示模态对话框的代码
在这个基础之上,我们从右侧隐藏的工具栏中拖动静态文本框和编辑框空间,添加一个Add按钮,布局如下:
一、静态文本控件的事件响应
一般来说静态文本控件主要用来作为标签起到注释的作用,如上面的对话框用来说明其右侧编辑框的意义。但是有时候我们也想编辑静态文本框,使得其可以响应一些操作,比如我们点击"Number1"时显示的名称会发生改变。为了实现这一个目的,我们需要以下工作:
1. 修改静态文本控件的ID
静态文本控件一般用于注释不需要编辑,因此其默认具有统一的ID:IDC_STATIC,我们需要将其修改为IDC_NUMBER1。
2. 在其属性栏中修改Notify为True使得其可以接受消息
3. 双击控件添加、编辑响应函数
由于MFC中为每个控件都提供了ID用于标识,因此我们使用ID作为空间识别引用的手段。CWnd类为我们提供了三个函数用于实现静态文本控件的事件响应,具体用法可查询MSDN:
--GetDlgItem():接收一个控件ID,返回指向该窗口或控件的指针;
--GetWindowText():接收一个控件ID,获取其文本值;
--SetWindowText():接收一个文本值,设置对应控件的文本值;
具体实现代码如下:
-
void CDlg1::OnStnClickedNumber1()
-
{
-
CString str;
-
if (GetDlgItem(IDC_Number1)->GetWindowText((str)), str == L"Number1")
-
{
-
GetDlgItem(IDC_Number1)->SetWindowText(L"数值1:");
-
}
-
else
-
{
-
GetDlgItem(IDC_Number1)->SetWindowText(L"Number1");
-
}
-
-
// TODO: 在此添加控件通知处理程序代码
-
}
运行的结果是,当点击标签"Number1"时会发生改变为”数值1“:
二、编辑框控件
这里我们的目的是实现一个MFC入门的时候经常使用的例子,记得当时接触过一段C#,首先编写的也是一个这样的加法计算器程序。这里实现num1和num2的求和,结果放入到num3中。为了实现这个效果,必须对编辑框的文本值进行读取、处理和最后的写入,我们可以继续使用上面类似的SDK,需要注意的是编辑框控件的文本值是wchar_t的,需要转换成int才可以进行运算,得到结果之后还需要再转换成wchar_t:
--使用GetDlgItem()获取目标控件的指针
--使用GetWindowTextW获取目标控件的文本值,写入变量
--使用SetWindowTextW将特定的wchar_t字符串设置为控件的文本显示
--使用_wtoi和_itow实现wchar_t与int的转换
-
void CDlg1::OnBnClickedAdd()
-
{
-
int num1, num2, num3;
-
wchar_t ch1[10], ch2[10], ch3[10];
-
-
GetDlgItem(IDC_EDIT1)->GetWindowTextW(ch1, 10);
-
GetDlgItem(IDC_EDIT2)->GetWindowTextW(ch2, 10);
-
-
-
-
num1 = _wtoi(ch1); //atoi的宽字符版
-
num2 = _wtoi(ch2);
-
num3 = num1 + num2;
-
-
_itow(num3, ch3, 10); //itoa的宽字符版,可以查阅MSDN
-
GetDlgItem(IDC_EDIT3)->SetWindowTextW(ch3);
-
-
-
// TODO: 在此添加控件通知处理程序代码
-
-
-
}
运行结果如下:
这里使用最基本的SDK来写,有助于我们弄清整个过程的实现思路。明白这一点之后,可以使用MFC为我们提供的其他函数来简化一些操作,比如:
--使用GetDlgItemText取代GetDlgItem与GetWindowTextW两个函数
--使用GetDlgItemInt取代GetDlgItemText和_wtoi两个函数
使用上面两种函数替代之后效果是一样的,都可以实现我们的目的。以上是使用SDK来实现的,下面我们使用更像MFC风格的方法来实现,通过为控件绑定变量来实现,这样我们就可以直接操作类的成员变量了。
1. 右键单击控件IDC_EDIT1,选择添加变量
2. 在弹出的对话框中”类别--value“, 变量类型-int,具体设置如下,其中的控件ID应为IDC_EDIT1:
3. 依次为IDC_EDIT2和IDC_EDIT3绑定变量
4. 编译运行,可以看到MFC为三个编辑控件设定了默认值0,这时查看Dlg1.h/cpp会发现添加变量的声明和构造函数的默认初始化
CDlg.h中的声明代码:
-
protected:
-
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
-
-
DECLARE_MESSAGE_MAP()
-
public:
-
afx_msg void OnStnClickedNumber1();
-
afx_msg void OnBnClickedAdd();
-
afx_msg void OnEnChangeEdit1();
-
-
int m_num1;
-
int m_num2;
-
int m_num3;
-
afx_msg void OnBnClickedOk();
CDlg.cpp中的构造函数:
-
CDlg1::CDlg1(CWnd* pParent /*=NULL*/)
-
: CDialog(CDlg1::IDD, pParent)
-
, m_num1(0)
-
, m_num2(0)
-
, m_num3(0)
-
{
-
-
}
5.由于变量添加在对话框绑定的类内部,因此直接双击Add按钮,编写其响应函数:
-
void CDlg1::OnBnClickedAdd()
-
{
-
/*
-
int num1, num2, num3;
-
wchar_t ch1[10], ch2[10], ch3[10];
-
-
//GetDlgItem(IDC_EDIT1)->GetWindowTextW(ch1, 10);
-
//GetDlgItem(IDC_EDIT2)->GetWindowTextW(ch2, 10);
-
-
//另一种实现
-
//GetDlgItemText(IDC_EDIT1, ch1, 10);
-
//GetDlgItemText(IDC_EDIT2, ch2, 10);
-
-
//更加简便的实现
-
num1 = GetDlgItemInt(IDC_EDIT1);
-
num2 = GetDlgItemInt(IDC_EDIT2);
-
-
-
//num1 = _wtoi(ch1); //atoi的宽字符版
-
//num2 = _wtoi(ch2);
-
num3 = num1 + num2;
-
-
//_itow(num3, ch3, 10); //itoa的宽字符版,可以查阅MSDN
-
//GetDlgItem(IDC_EDIT3)->SetWindowTextW(ch3);
-
//SetDlgItemText(IDC_EDIT3, ch3);
-
-
SetDlgItemInt(IDC_EDIT3, num3);
-
-
// TODO: 在此添加控件通知处理程序代码
-
*/
-
-
-
UpdateData();
-
m_num3 = m_num1 + m_num2;
-
UpdateData(FALSE);
-
}
上面把之前的实现代码一并列上便于分析比较,最后的这种直接绑定类变量的方法需要注意以下几点:
1. 由于将对话框的控件与类变量绑定,在绑定时设置好了类型,因此MFC会为我们定义声明并自动为我们进行类型检查;
2. 关键代码就是一句:num3 = num1 + num2
3. 对话框数据交换由函数DoDataExchange完成,但是该函数不会自动调用,需要我们人工调用
4. CWnd提供了UpdateData函数进行调用DoDataExchange函数,默认参数true表示获取对话框数据,false表示初始化对话框的控件
5. 我们先调用UpdateData()获取对话框当前数据,再使用FALSE标识初始化对话框IDC_EDIT3
实现的效果是一样的,但是代码要简便了许多。在弄清原理之后推荐使用这种方式来实现编辑框控件的操作。通过今天的学习,我们发现MFC通过控件的ID进行标识,相关的SDK也以此作为参数返回其可引用的指针;不同的控件之间可以进行数据交换,我们可以通过SDK实现,也可以通过绑定MFC变量实现,后者的实现更加简便,但是删除控件时比较麻烦。
阅读(338) | 评论(0) | 转发(0) |