📄 07.4.3 编辑框控件.txt
字号:
7.4.3 编辑框控件
接着利用上面的对话框实现这样的功能:在前两个编辑框中分别输入一个数字,然后单击Add按钮,对前两个编辑框中的数字求和,并将结果显示在第三个编辑框中。
1.第一种方式
为了对前两个编辑框中的数字求和,那么首先就要获得这两个编辑框中的内容。根据上面介绍的知识,我们知道可以利用GetWindowText函数来实现这个功能。同时,可以利用 SetWindowText函数将求和结果显示在第三个编辑框中。因此,实现代码如例7-14所示:
, ~IJ 7-14
void CTestDlg: :OnBtnAdd(}
int numl , num2 , num3;
char chl[lO] , ch2[ lO] , ch3[ lO ];
…
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1, 10) ;
GetDlgltern(IDC_ED工T2)->GetWindowText(ch2, 10);
nurnl = atoi (chl) ; nurn2 = atoi(ch2); nurn3 = nurnl + num2;
itoa(num3 , ch3 , 10) ; GetDlgltem(IDC_EDIT3)->SetWindowText(ch3) ;
注:读者可以先将 Add按钮单击消息响应函数 OnB tnAdd中已有代码注释起来,然后将上述代码添加到这个函数中。以下几种实现方式与此相同。
上述例 7-14所示代码中,首先定义了三个数值型变量和三个大小为 10的字符数组。接下来获得前两个编辑框中的文本内容,但为了进行求和运算,必须将字符形式的内容转换为数值, C语言提供了一个这样的转换函数: atoi,可以将一个由数字组成的字符串转换为相应的数值。接着上述程序对转换后的数值求和,结果是一个数值,但为了将结果显示在第三个编辑框中,还必须将这个数值转换为文本,这可以利用 C语言中与 atoi函数相对应的另一个函数: itoa来实现。最后,调用 SetWindowText函数将转换后的文本结果显示在第三个编辑框中。
目的示 :itoa函数的第三个参数表示转换的进制,数字 10表示十进制。
Build井运行 Mybole程序,单击程序菜单栏上的【对话框】菜单,测试对话框窗口出现了,读者可以试着在前两个编辑框中分别输入一个数字,例如,分别输入 34和元,然后单击 Add按钮,即可看到在第三个编辑框中显示了求和结果 :90。程序运行界面如图 7.21所示。
2.第二种方式
下面再介绍另一种实现方法。 CWnd类还提供了一个成员函数: GetDlgltemText,这个函数将返回对话框中指定 ID的控件上的文本。也就是说, GetDlgltemText函数把上面介绍的 GetDIgltem和 GetWindowText这两个函数的功能组合起来了。同样, CWnd类还有一个与之对应的成员函数: SetDlg ItemText,用来设置对话框中指定 m的控件上的文本。例 7-15就是利用 GetDlgltemText和 SetDlgltemText函数的实现代码。
例 7-15
void CTestDlg : : OnBtnAdd()
{ int numl , num2 , num3; char chl[lO] , ch2[lO] , ch3 [lO] ;
GetDlgItemText(IDC_EDIT1, ch1, 10) ;
GetDlgItemText(工 DC_ED工 T 2 , c h2 , 10) ;
num1 = atoi(ch1);
num2 = ato工 (ch2) ;
num3 = numl + num2;
itoa(num3 , ch3 , lO); SetDlgItemText(工 DC_ED工 T 3 , c h3) ;
读者可以试试这段代码,会发现同样实现了要求的功能。
3.第三种方式
利用 CWnd类的另一对成员函数: GetDlglternInt和 SetDlgltemInt来实现上述功能。其中, GetDlgltemInt函数返回指定控件的文本,并将其转换为一个整型数值,它的声明形式如下所示:
UINT GetDlgItemlnt( int n工D, BOOL* lpTrans = NULL , BOOL bSigned = TRUE ) const;
其中,各参数的意义如下所述:
. nID
控件的E。
. lpTrans
指向一个布尔型变量,该变量接收转换标志。如果这个函数在调用时有错误发生,例如,遇到一个非数值型的字符,或者得到的数值超过了 UINT类型所能表示的最大值,则这个函数将一个 O值〈即 FALSE)放置到这个参数所指向的地址空间中:否则,给这个参数所指向的地址空间中设置一个非 O值(即 TRUE)。如果调用这个函数时,将这个参数设置为 NULL,则这个函数将不对错误提出警告。
. bSigned
指定被检索的值是否有符号。如果为真,说明这个数字是有符号的:否则,是无符号的数值。
与 GetDlgltemInt函数的功能相对应, SetDlgltemInt函数用指定的数值来设置特定控件的文本,该函数具有如下形式的声明:
void SetDlg工 temlnt( int nID, U工NT nValue , BOOL bSigned = TRUE );
该函数各个参数的意义如下所述:
.nID
控件的ID。
. nValue
指定用来产生控件上文本的整型数值。
. bSigned
指定nValue参数指定的数值是否是有符号数。如果其值为TRUE,则 nValue指定的数值就是一个有符号数:否则是无符号数。
例7-16就是利用GetDlgItemInt和 SetDlgItemInt这两个函数实现本例所需功能的具体代码。
例7-16
void CTestDlg : :OnBtnAdd() int numl , num2 , num3;
num1 = GetDlgItemInt(IDC_EDIT1);
num2 = GetDlgItemInt(IDC_EDIT2);
num3 = num1+ num2;
SetDlgItemInt(IDC_EDIT3 , num3);
读者可以试试这段代码,会发现同样实现了要求的功能。井且可以试试在前两个编辑框中输入负值,看看求和的结果如何。读者将会发现结果一样是正确的。
4.第四种方式
将这三个编辑框分别与对话框类的三个成员变量相关联,然后通过这些成员变量来检索和设置编辑框的文本,这是最简单的访问控件的方式。
为了将对话框控件与类成员变量相关联,需要利用ClassWizard来帮助我们完成。首先打开ClassWizard对话框,并单击MemberVariables选项卡,在Class name下拉列表框中选择 CTestDlg,这时在ControlIDs列表中将列出这个对话框中的所有控件的ID。如图7.22所示。
首先为IDCEDIT1编辑框添加一个关联的成员变量,方法是在Control IDs列表中选中IDC_EDIT1,然后单击【Add Variable】按钮,这时将出现如图7.23所示的对话框。在此对话框中,设置与控件相关联的成员变量的名称为:mJum1:变量的类别为: Va1ue; 变量的类型为: int。然后单击【OK】按钮,这时,在ClassWizard对话框的Member Variables 选项卡的ControlIDs列表中,就可以看到IDC_EDIT1控件有了一个与之关联的int类型成员变量: m_numl,如图7.24所示。
利用同样的方法,为IDCEDIT2和IDC EDIT3这两个编辑控件分别添加与之相关联的成员变量: m nurn2和m_num3,并且都是int类型。之后,单击ClassWizard对话框上的【OK】按钮,关闭这个对话框。这时,可以浏览一下CTestDlg类的源代码,看看Cl出sWìzard添加了哪些新内容?
首先,在这个类的头文件中,可以看到在两个 AFX DATA注释宏之间增加了三个成员变量,代码如例7-17所示。
例7-17
// Dialog Data // {{AFX_DATA(CTestDlg)
enum { 100 =100_01ALOGl };
int m_num1;
int ffi_num2;
int m_num3 ; // }}AFX_DATA
接着,在CTestDlg类的构造函数中,可以看到对这三个成员变量进行了初始化,将它们分别赋值为: 0。代码如例7-18所示。
例7-18
CTestDlg: : CTestDlg(CWnd* pParent / * =NULL* / ) CDialog(CTestDlg: :工00, pParent)
// ({AFX_DATA_INIT(CTestDlg) ffi_numl = 0 ;
·、
ffi_num2 = 0;
ffi_num3 = 0;
// }}AFX_DATA_工NIT
ffi_bIsCreated = FALSE;
Build井运行Mybole程序,单击程序菜单栏上的【对话框】菜单项,将打开我们自己定义的测试对话框,可以发现这时三个编辑框中都显示了一个数值: 0。这个初始的值就是CTestDlg构造函数为这三个成员变量所设置的,因为这三个成员变量已经与这三个控件相关联了。但是这个关联是在什么地方完成的呢?继续浏览CTestDlg类的源文件,可以发现它有一个 DoDataExchange函数(代码如例 7-19所示),这个函数由程序框架调用,以完成对话框数据的交换和校验。可以看到在这个函数内部调用了三个DDX TEXT函数,后者的功能就是将 E指定的控件与特定的类成员变量相关联。因此,就是在 DoDataExcbange函数内部实现了对话框控件与类成员变量的关联。
例7-19
vo工d CTestDlg : : DoDataExchange (CDataExchange* pDX)
CDialog : : DoDataExchange (pDX) ;
// ({AFX_DATA_MAP(CTestDlg)
DDX_Text(pDX,工DC_ED工Tl, ffi_numl) ;
DDX_Text(pDX,工DC_ED工T2, ffi_num2);
DDX_Text {pDX,工DC_EDIT3, ffi_num3);
//}}AFX_DATA_MAP
~姐iflMFC提供了多种以DDX为前缀的函数,这些函数分别用于不同控件的
数据交换。
既然编辑框控件已经与类成员变量相关联了,我们就可以直接利用这些相关联的变量来编程实现上述所需功能,具体实现代码如例7-20所示。
例 7-20
void CTestDlg ::OnBtnAdd()
m_num3 = m_num1 + ffi_num2 ;
Build并运行 Mybole程序,打开测试对话框窗口,然后在前两个编辑框中输入两个数值,单击【 Add】按钮,但是发现在第三个编辑框中并没有出现所需的结果。在上述语句处设置一个断点,然后调试运行 Mybole程序,打开测试对话框,并在测试对话框的前两个编辑框中分别输入两个数值,例如 34和坷,然后单击对话框上的【 Add】按钮,程序
将暂停在刚才设置的断点处。此时,我们可以看看这几个。 oid crestDlg::OnBtnAdd()
变量的值,前面已经介绍过一种查看的方法,就是把鼠标。 I 4 __nu回3.气'量,时+ . nu.2; 放到想查看的变量上,稍停片刻, VC++就会弹了一个小框,|m_numl = OxOOOOOOOO I 里面显示了该变量的当前值,如图 7.25所示。' 从图 7.25可知, m_numl变量的当前值是 0。利用同图 7.25 m_numl变量的当前值
样的方法,可以获得 m num2变量的当前值,发现它也是 0。也就是说,这两个变量没有获取到在编辑框控件中输入的数字。但是,先前我们看到了在对话框初始显示时,这几个编辑框的文本确实是由与它们相关联的几个变量的初始值设置的,即在 CTestDlg类的构造函数中将这几个变量初始化为 0,然后在对话框显示时'.这几个编辑框的文本都为 "0"。那么为什么在这里却没有获得编辑框的文本呢?刚才已经提到对话框数据交换是由 DoDataExchange函数完成的,我们再来研究一下这个函数。由 MSDN提供的帮助信息,可以知道:在程序代码中从来不直接调用这个函数,而是通过 CWnd类的另一个成员函数: UpdateData来调用。通过调用后者来初始化对话框控件或从对话框获取数据。也就是说,为了让数据交换生效,就必须去调用 DoDataExchange函数,但程序代码不是直接调用这个函数,而是需要去调用 UpdateData这个函数。后者具有如 F声明形式:
BOOL UpdateData( BOOL bSaveAndValidate = TRUE );
UpdateData函数有一个 BOOL类型的参数。如果其值为 TR阻,则说明该函数正在获取对话框的数据:如果其值为 FALSE,则说明该函数正在初始化对话框的控件。对模态对话框来说,当它创建时,框架自动以参数值 FALSE调用 UpdateData函数来初始化对话框控件的内容。因此,上面 Mybole程序中的测试对话框中的几个编辑框控件才能收到在 CTestD lg类的构造函数中设置的初始值。那么,现在要想获得编辑框中的文本,那就需要以参数值 TRUE调用 UpdateData函数,然后再对与编辑框控件相关联的变量进行计算。也就是在上述例 7-20所示的 OnBtnAdd函数代码中,在计算语旬之前需要加上下面这行代
码:
UpdateData(); .
国际:因为 UpdateData函数糊的默认值就是 TR田,所以从对话框获取数据时可以省略其参数值。
在调用了先前的计算语句之后, m num3变量就保存了计算结果,但要想把这个结果显示在第三个编辑框中,还需要进行一次数据交换,但这次是要以参数值 FALSE来调用 UpdateData函数,即用变量的值来初始化对话框控件。也就是在上述例 7-20所示的 OnBtnAdd函数中,在先前编写的那条计算语旬之后再加上下面这条语句:
UpdateData(FALSE);
这时, CTestDlg类的OnBtnAdd函数的完整代码应该如例7-21所示。
1Jtl 7-21
void CTestDlg: :OnBtnAdd()
UpdateData() ;
ffi_num3 = ffi_numl + ffi_num2;
UpdateDat a(FALSE) ;
读者可以再次Build井运行Mybole程序,测试一下对编辑框中输入数据的计算结果,将会发现这时程序正确地实现了所需功能。这时,如果在前两个编辑框的任一个中输入一个非数值型的字符,然后单击【Add】按钮,程序会弹出一个对话框,提示:"请键入一个整数",如图7.26所示。
图 7.27设定变量的取值范围
图 7.28错误提示二
这个功能也不是我们自己实现的,而是因为我们刚才在 ClassWizard中设定了这两个编辑框的取值范围而产生的。这时,查看一下 CTestDIg类的源程序,发现添加控件取值范围之后, ClassWizard又在程序的 DoDataExchange函数中添加了几行代码。例 7-22是这时的 DoDataExchange函数的代码。
例 7-22
void CTestDlg: : DoDataExchange (CDataExchange* pDX)
CDialog ::DoDataExchange(pDX) ;
//{{AFX_DATA_MAP(CTestDlg)
DDX_Text(pDX,工 DC_EDIT1, ffi_numl);
DDV_MinMax工且t(pDX, rn-pum1 , 0 , 100);
DDX_Text(pDX,工 DC_EDIT2, ffi_num2);
DDV:二~inMaxlnt(pDX, rn_num2 , 0 , 100);
DDX_Text(pDX , IDC_EDIT3 , ffi_num3) ;
// }}AFX_DATA_MAP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -