【教学课件】第4章常用控件.ppt
第4章 常用控件,4.1.1 控件的创建方法,常用控件类,4.1.1 控件的创建方法,例Ex_DlgCtrls 用控件的编程方式来创建一个按钮(1)选择“文件”“新建”菜单,在弹出的“新建”对话框中单击“工程”标签,选择MFCAppWizard(exe)的项目类型,在工程框中输入项目名Ex_DlgCtrls,结果如图,4.1.1 控件的创建方法,单击确定按钮,在出现的“Step 1”对话框中选择“基本对话框)”应用程序类型,单击完成按钮,创建一个默认的基于对话框的应用程序项目。将项目工作区切换到ClassView页面,展开CEx_DlgCtrlsDlg类,右击CEx_DlgCtrlsDlg类名,弹出如图所示的快捷菜单。,4.1.1 控件的创建方法,从快捷菜单中选择Add Member Variable,出现如图所示的对话框,在Variable Type(变量类型)编辑框中输入CButton(MFC按钮类),在Variable Name(变量名)编辑框中输入要定义的CButton类对象名m_btnWnd。,单击OK按钮,这样Visual C+就会自动在CEx_DlgCtrlsDlg类中添加该成员变量。,4.1.1 控件的创建方法,在项目工作区的ClassView页面中,双击OnInitDialog函数名,在该函数中添加下列代码:BOOL CEx_DlgCtrlsDlg:OnInitDialog()CDialog:OnInitDialog();m_btnWnd.Create(你好,WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(20,20,120,60),this,201);/创建CFont*font=this-GetFont();/获取对话框的字体m_btnWnd.SetFont(font);/设置控件字体return TRUE;/return TRUE unless you set the focus to a control,4.1.1 控件的创建方法,(7)编译并运行,结果如图所示。,控件编程创建方法涉及到的编程内容比较复杂,且不能发挥对话框编辑器可视化的优点,故本书采用前一种方法,即在对话框模板中用编辑器指定控件。,4.1.2 控件的消息及消息映射,应用程序创建一般控件或公共控件之后,当控件的状态发生改变时,控件就会向其父窗口发送消息,这个消息称为“通知消息”。系统都会用一个MSG结构来记录,MSG具有下列结构:typedef struct tagMSG/msg HWND hwnd;/接收到消息的窗口句柄 UINT message;/消息 WPARAM wParam;/消息的附加信息,它的含义取决 于message LPARAM lParam;/消息的附加信息,它的含义取决 于message DWORD time;/消息传送时的时间 POINT pt;/消息传送时,光标所在的屏幕坐标 MSG;,4.1.2 控件的消息及消息映射,映射控件消息 在MFC中,映射一个控件消息是非常简便的,如下面的过 程是对新添加的按钮控件映射BN_CLICKED(单击)消息。将项目工作区窗口切换到ResourseView页面,双击Dialog 资源下的标识IDD_EX_DLGCTRLS_DIALOG,打开该对 话框资源模板。删除“TODO:在这里设置对话控制。”控件,添加一个按钮控件,保留其默认属性。如图所示。,4.1.2 控件的消息及消息映射,按快捷键Ctrl+W,打开MFC ClassWizard对话框,查看“Class name”列表中是否选择了CEx_DlgCtrlsDlg,在IDs列表中选择IDC_BUTTON1,这是添加按钮后,系统自动为此按钮设置的默认标识符,然后在Messages框中选择BN_CLICKED消息。(4)单击Add Function按钮或双击BN_CLICKED消息,出现“Add Member Function”对话框,在这里可以输入成员函数的名称,系统默认的函数名为OnButton1。,4.1.2 控件的消息及消息映射,单击OK按钮,在MFC ClassWizard的“Member functions”列表中将列出新增加的成员函数。在此成员函数中添加下列代码:void CEx_DlgCtrlsDlg:OnButton1()MessageBox(你按下了Button1按钮!);(6)编译并运行,当单击Button1按钮时,就会执行OnButton1函数,弹出一个消息对话框。这就是按钮BN_CLICKED消息的映射过程,其他控件的消息也可以类似操作。,4.1.2 控件的消息及消息映射,2.控件消息映射机制,将项目工作区切换到FileView(文件视图)页面,展开Head Files(头文件)所有项,双击CEx_DlgCtrlsDlg 类的头文件Ex_DlgCtrlsDlg.h,在Ex_DlgCtrlsDlg.h文档内容可以找到这样的代码(加粗的代码,以下同):protected:/Generated message map functions/AFX_MSG(CEx_DlgCtrlsDlg)afx_msg void OnButton1();/AFX_MSGDECLARE_MESSAGE_MAP();,4.1.2 控件的消息及消息映射,在项目工作区FileView页面中,展开Source Files(源文件)所有项,双击CEx_DlgCtrlsDlg 类的源文件Ex_DlgCtrlsDlg.cpp,在Ex_DlgCtrlsDlg.h文档内容可以找到这样的代码:BEGIN_MESSAGE_MAP(CEx_DlgCtrlsDlg,CDialog)/AFX_MSG_MAP(CEx_DlgCtrlsDlg)ON_BN_CLICKED(IDC_BUTTON1,OnButton1)/AFX_MSG_MAP END_MESSAGE_MAP(),在Ex_DlgCtrlsDlg.cpp文件的后部分还有消息函数的实现代码,它与一般函数实现相同。,4.1.2 控件的消息及消息映射,4.映射控件通用消息,通过WM_COMMAND消息的映射来处理一个或多个控件通用消息,如下面的过程。按快捷键Ctrl+W,打开MFC ClassWizard对话框,“Class name”列表中是否选择了CEx_DlgCtrlsDlg,在IDs表中选择CEx_DlgCtrlsDlg,在Messages框中找到并双击OnCommand,这样OnCommand消息函数就添加好了,由于OnCommand函数是一个用来处理WM_COMMAND消息的虚函数,因此这里添加的OnCommand函数事实上是一个在类中实际调用的函数,可称为“实例函数”。这样的映射操作,可以称之为“对虚函数OnCommand的重载”。,4.1.2 控件的消息及消息映射,(2)在OnCommand函数中添加下列代码:BOOL CEx_DlgCtrlsDlg:OnCommand(WPARAM wParam,LPARAM lParam)WORD nCode=HIWORD(wParam);/控件的通知消息 WORD nID=LOWORD(wParam);/控件的ID号if(nID=201),(3)编译并运行。,4.1.3 控件的数据交换(DDX)和数据校验(DDV),MFC采用了独特的DDX和DDV技术。使用MFC ClassWizard可以很容易地为一个控件定义关联变量并可设置其数据范围。为CEx_DlgCtrlsDlg类的按钮控件IDC_BUTTON1添加并使用其关联变量m_RelBtn。,(1)按快捷键Ctrl+W,打开MFC ClassWizard,并切换到Member Variables页面。(2)选定Class name为CEx_DlgCtrlsDlg,然后在Control IDs列表中,选定所要关联的控件ID号IDC_BUTTON1,双击鼠标右键或 单击Add Variable按钮,弹出Add Member Variable对话框,对话框设置变量的名称、类别和数据类型。,4.1.3 控件的数据交换(DDX)和数据校验(DDV),对于编辑框来说,Variables type中的数值类型可以有CStringint、UINT、long、DWORD、float、double、BYTE、short、BOOL等。,MFC ClassWizard的“MembeVariables”页面,“Add Member Variable”对话框,4.1.3 控件的数据交换(DDX)和数据校验(DDV),(3)在Member variable name框中填好与控件相关联的成员变量m_RelBtn,单击OK按钮,又回到MFC ClassWizard对话框的Member Variables页面中,在Control IDs列表中出现刚才添加的控件关联变量(或直接称之为“控件变量”)。,4.1.3 控件的数据交换(DDX)和数据校验(DDV),在Ex_DlgCtrlsDlg.h文件中,添加控件关联变量声明,代码如下面加粗部分:/Dialog Data FX_DATA(CEx_DlgCtrlsDlg)enum IDD=IDD_EX_DLGC TRLS_DIALOG;/枚举类型CButtonm_RelBtn;CStringm_strEdit;/AFX_DATA,在Ex_DlgCtrlsDlg.cpp文件中的CEx_DlgCtrlsDlg构造函数实现代码处,添加控件变量的一些初始代码:CEx_DlgCtrlsDlg:CEx_DlgCtrlsDlg(CWnd*pParent/*=NULL*/):CDialog(CEx_DlgCtrlsDlg:IDD,pParent)/AFX_DATA_INIT(CEx_DlgCtrlsDlg)m_strEdit=_T();/AFX_DATA_INIT,(4)单击确定按钮后,打开CEx_DlgCtrlsDlg类源文件,可以发现MFC ClassWizard对上述操作作了以下三方面的修改。,4.1.3 控件的数据交换(DDX)和数据校验(DDV),在Ex_DlgCtrlsDlg.cpp文件中的DoDataExchange函数体内,添加了控件的DDX/DDV代码,它们都是一些以DDV_或DDX_开头的函数调用。void CEx_DlgCtrlsDlg:DoDataExchange(CDataExchange*pDX)CDialog:DoDataExchange(pDX);/调用此函数作为DDX的开始/AFX_DATA_MAP(CEx_DlgCtrlsDlg)DDX_Control(pDX,IDC_BUTTON1,m_RelBtn);DDX_Text(pDX,IDC_EDIT1,m_strEdit);/将控件IDC_EDIT1与m_strEdit进行数据交换DDV_MaxChars(pDX,m_strEdit,20);/校验m_strEdit的最大字符个数不超过20/AFX_DATA_MAP,4.1.3 控件的数据交换(DDX)和数据校验(DDV),(5)当为一个控件定义一个关联的数据变量后,可以使用CWnd:UpdateData函数实现控件数据的输入和读取。将CEx_DlgCtrlsDlg:OnButton1修改成下列代码:void CEx_DlgCtrlsDlg:OnButton1(),UpdateData();/没有参数,表示使用的是默认参数值TRUE m_RelBtn.SetWindowText(m_strEdit);,UpdateData函数只有一个为TRUE或FALSE的参数。调用UpdateData(FALSE)时,数据由控件相关联的成员变量向控件传输,当调用UpdateData(TRUE)或不带参数的UpdateData时,数据从控件向相关联的成员变量复制。,4.1.3 控件的数据交换(DDX)和数据校验(DDV),(6)运行该程序,当在编辑框中输入“Hello”后,单击Button1按钮,OnButton1函数中的UpdateData将编辑框内容保存到m_strEdit变量中,从而执行下一条语句后按钮的名称就变成了编辑框控件中的内容“Hello”。,使用控件的数据成员变量:,4.2 静态控件和按钮,静态控件和按钮是Windows最基本的控件之一。,静态控件是用来显示一个字符串、框、矩形、图标,位图或增 强的图元文件。在对话框编辑器的控件工具栏中,属于静态控件的有:静态文本()、组框()和静态图片()三种。静态图片控件的General属性对话框:,4.2.1 静态控件,4.2 静态控件和按钮,静态图片控件的一般属性对话框,表列出了其一般属性的各个项的含义。,4.2 静态控件和按钮,在属性对话框中,用户可以选择图片“类型”、“图像”两个组合框中的有关选项内容,并可将应用程序资源中的图标、位图等内容显示在该静态图片控件中。,(1)打开Ex_DlgCtrls项目中的对话框资源模板IDD_EX_DLIDD_EX_DLGCTRLS_DIALOG。(2)在该对话框适当的位置处添加一个静态图片控件,右击该控件,从弹出的快捷菜单中选择“属性”,弹出如图所示的属性对话框。,4.2 静态控件和按钮,(3)在属性对话框中,选择“颜色”类型为Etched,然后关闭属性对话框。(4)将鼠标移动到添加的静态图片控件的右下角位置,使鼠标指针变成拖动 鼠标使控件的大小变成一条水平线,单击对话框测试按扭,则结果如图所示。,,,水平蚀刻线,2.2.1 按钮,在Windows中所用的按钮是用来实现一种开与关的输入,常见的按钮有三种类型:按键按钮 单选按钮 复选框按钮按钮的不同类型:,1.不同按钮的作用,按键按钮通常可以立即产生某个动作,执行某个命令,因此也常被称为命令按钮。按钮有两种风格:标准按键按钮 默认按键按钮button)”项。,2.2.1 按钮,复选框的外形是在文本前有空心方框,当被选中时,复选框中就加上一个“”标记,通常复选框只有选中和未选中两种状态,若复选框前面有一个灰色是“”,这样的复选框是三态复选框。,2.按钮的消息 在按钮映射的消息中,常见只有两个BN_CLICKED和 BN_DOUBLE-CLICKED(双击按钮)。,3.按钮选中操作 最常用的按钮操作是设置或获取一个按钮或多个按钮的选中状态。CButton类的成员函数SetCheck和GetCheck分别用来设置或获取指定按钮的选中状态。,4.2.3 示例:制作问卷调查,问卷调查是日常生活中经常遇到的调查方式。,本例用到了组框、静态文本、单选按钮、复选框等控件。需要通过CheckRadioButton函数来设置同组单选按钮的通过GetDlgItemText 或GetWindowText获取选中控件的窗口文本。,4.2.3 示例:制作问卷调查,例Ex_Research 制作问卷调查创建并设计对话框(1)创建一个默认的基于对话框应用Ex_Research。(2)Visual C+会打开对话框编辑器并显示对话框资源模板。,(3)调整对话框的大小,删除对话框中间的“TODO:在这里设置对话控制。,(4)右击添加的组框控件,从弹出的快捷菜单中选择“属性”菜单,在属性对话框窗口中可以看到它的ID为默认的IDC_STATIC。在组框控件的Styles属性中,“水平对齐”属性用来指定文本在顶部的左边(Left)、居中(Center)还是右边(Right)。默认(Default)选项表示左对齐。,4.2.3 示例:制作问卷调查,(5)在组框内添加4个单选按钮,默认的ID依次为_RADIO1、IDC_RADIO2、IDC_RADIO3和IDC_RADIO4。,4.2.3 示例:制作问卷调查,接下来添加一个静态文本,标题设为“你使用的接入方式:然后在其下再添加4个单选按钮,标题分别是“FTTL或ADSL”、“单位LAN”、“拨号56K”和“其他”,并将相应的ID属性依次改成:IDC_CM_FTTL、DC_CM_LAN、IDC_CM_56K和IDC_CM_OTHER。再添加单选框图:,4.2.3 示例:制作问卷调查,对话框的下方,再添加一个组框控件,标题为“你上网主要是”。添加四个复选框,其标题分别为“收发邮件”、“浏览资料”、“聊天游戏”和“其他”,ID分别为IDC_DO_POP、IDC_DO_GAME和IDC_DO_OTHER。,4.2.3 示例:制作问卷调查,(8)单击工具栏上的测试对话框按钮 对话框测试后,可以发现:顺序添加的这8个单选按钮全部变成一组,在这组中只有一个单选按钮被选中,这不符合我们的本意。解决这个问题的最好的办法是将每一组中的第一个单选按钮的Group(组)属性选中。,。,分别将这二个问题中的第一个单选按钮的Group(组)属性均选中。图所示是对第二个问题设置的结果。,4.2.3 示例:制作问卷调查,单击对话框编辑器工具栏上的切换辅助线按钮,然后将对话框中的控件调整到辅助线以内,并适当对其他控件进行调整。整个问卷调查的对话框就设计好了,单击工具栏上的测试对话框按钮。,4.2.3 示例:制作问卷调查,5.完善代码,(1)将项目工作区切换到ClassView(类视图)页面,展开类CEx_ResearchDlg的所有成员,双击OnInitDialog函数名就会在文档窗口中自动定位到该函数的实现代码处,在此函数添加下列初始化代码:BOOL CEx_ResearchDlg:OnInitDialog(),CDialog:OnInitDialog();CheckRadioButton(IDC_AGE_L18,IDC_AGE_M38,IDC_AGE_18T27);CheckRadioButton(IDC_CM_FTTL,IDC_CM_OTHER,IDC_CM_FTTL);CButton*pBtn=(CButton*)GetDlgItem(IDC_DO_POP);pBtn-SetCheck(1);/使“收发邮件”复选框选中 return TRUE;,4.2.3 示例:制作问卷调查,用MFC ClassWizard在CEx_ResearchDlg类中添加IDOK按钮BN_CLICKED消息映射,并添加下列代码,使得用按确定按钮取用户所作的选择内容。void CEx_ResearchDlg:OnOK(),CString str,strCtrl;/定义两个字符串变量,CString是操作字串的MFC类/获取第一个问题的用户选择str=你的年龄:;UINT nID=GetCheckedRadioButton(IDC_AGE_L18,IDC _AGE_M38);GetDlgItemText(nID,strCtrl);/获取指定控件的标题文本str=str+strCtrl;/获取第二个问题的用户选择,4.2.3 示例:制作问卷调查,str=str+“n你使用的接入方式:nID=GetCheckedRadioButton(IDC_CM_FTTL,IDC_CM_OTHER);GetDlgItemText(nID,strCtrl);/获取指定控件的标题文本str=str+strCtrl;/获取第三个问题的用户选择str=str+n你上网主要是:n;UINT nCheckIDs4=IDC_DO_POP,IDC_DO _READ,IDC_DO_GAME,IDC_DO_OTHER;CButton*pBtn;for(int i=0;iGetCheck()pBtn-GetWindowText(strCtrl);str=str+strCtrl;str=str+;MessageBox(str);CDialog:OnOK();,4.2.3 示例:制作问卷调查,代码中,GetDlgItemText是CWnd类成员函数。该函数有两个参数:第一个参数用来指定控件的标识 第二个参数是返回的窗口文本。函数GetWindowText的作用与GetDlgItemText相同,也是获取窗口的文本内容。,(3)编译并运行,出现“上网问卷调查”对话框,当回答问题后,按确定按钮,出现如图所示的消息对话框,显示用户选择的内容。,4.3.1 编辑框的属性和通知消息,用对话框编辑器可以方便地设置编辑框的属性和风格。编辑框的属性对话框:,表4.4 编辑框的通知消息,4.3.1 编辑框的属性和通知消息,表4.3 编辑框的Style属性,4.3.2 编辑框的基本操作,1.口令设置 口令设置在编辑框中不同于一般的文本编辑框,每个字符都被一个特殊的字符代替显示,这个特殊的字符称为口令字符。,void SetPasswordChar(TCHAR ch);参数ch表示设定的口 令字符;当ch=0时,编辑框内将显示实际字符。,2.选择文本 当编辑框中编辑文本时,往往需要选定文本作为整体进行各种编辑操作。用鼠标来选择文本的操作方法是:在要选择的文本的一端按下鼠标左键并拖动鼠标,到另一端释放鼠标键。用键盘来选择文本的方法是:按光标方向移动键的同时,按住Shift。,4.3.2 编辑框的基本操作,3.设置编辑框的页面边距设置编辑框的页面边距可以使文本在编辑框显示更具满意 效果,这在多行编辑框中尤为重要,应用程序可通过调用 成员函数CEdit:SetMargins来实现,这个函数的原型如下:oid SetMargins(UINT nLeft,UINT nRight);参数nLeft和nRight分别用来指定左、右边距的像素大小。,剪帖板操作 编辑框通过CEdit类的Copy、Paste和Cut成员函数来实现 文本的复制、粘贴、剪切的操作,并还自动支持键盘快捷 操作,其对应的快捷健分别为Ctrl+C、Ctrl+V和Ctrl+X。若 应用程序调用CEdit:Undo函数时,则还可撤消当前的操作,调用一次该函数,则恢复刚才的操作。例如下面的代码:if(m_Edit.CanUndo()m_Edit.Undo();,4.3.2 编辑框的基本操作,5.获取多行编辑框文本 一是使用DDX/DDV,将编辑框控件所关联的变量类型选 定为CString 一种是使用编辑框CEdit类的相关成员函数来获取文本。如,下面的代码将显示编辑框中第二行的文本内容:,char str100;if(m_Edit.GetLineCount()=2)/判断编辑框的文本是否是两行以上 int nChar nChars=m_Edit.LineLength(m_Edit.LineIndex(1);/获取第二行文本的字符个数/0表示第一行,1表示第二行,依次类推。LineIndex用于将文本行转换成/能被LineLength识别的索引 m_Edit.GetLine(1,str,nChars);/获取第二行文本 strnChars=0;MessageBox(str);,4.3.3 旋转按钮控件,“旋转按钮控件”是一对箭头按钮,用户点击它们来增加或减小某个值,比如一个滚动位置或显示在相应控件中的一个数字。,一个旋转按钮控件通常是与一个相伴的控件一起使用的,这个控件称为“伙伴窗口”。若相伴的控件的Tab键次序刚好在旋转按钮控件的前面,则这时的旋转按钮控件可以自动定位在它的伙伴窗口的旁边,看起来就象一个单一的控件。点击向上箭头使当前位置向最大值方向移动,而点击向下箭头使当前位置向最小值的方向移动。,旋转按钮控件的最小值是100,最大值是0。,4.3.3 旋转按钮控件,1.旋转按钮控件常用的风格(1)旋转按钮控件有许多风格,它们都可以通过旋转 按钮控件属性对话框进行设置,如图所示,其中各项 的含义见表。,4.3.3 旋转按钮控件,(1)旋转按钮控件的基本操作 MFC的CSpinButtonCtrl类提供了旋转按钮控件的各种 操作函数,使用它们可以进行基数、范围、位置设置和获取等基本操作。,int SetBase(int nBase);成员函数SetPos和SetRange分别用来设置旋转按钮控 件的当前位置和范围,它们的函数原型如下:int SetPos(int nPos);void SetRange(int nLower,int nUpper);,(2)成员函数SetBase,的原型如下:,旋转按钮控件的通知消息旋转按钮控件的通知消息只有一个:UDN_DELTAPOS,它是在当控件的当前数值将要改变时向其父窗口发送的。,4.3.4 示例:用对话框输入学生成绩,本例将用到静态文本、编辑框、旋转按钮控件等控件。实现时,最关键的是如何将编辑框设置成旋转按钮控件的伙伴窗口。,4.3.4 示例:用对话框输入学生成绩,例Ex_Ctrl1SDI 用对话框输入学生成绩添加并设计对话框 用MFC AppWizard(exe)创建一个默认的单文档应用程序Ex_Ctrl1SDI。添加一个新的对话框资源,将ID号改为IDD_INPUT,标题为“学生成绩输入”,将对话框字体改为“宋体,9号”。将OK和Cancel按钮标题改为“确定”和“取消”。(3)调整对话框的大小,将确定和取消按钮移至对话框的下方,然后显示对话框网格。,4.3.4 示例:用对话框输入学生成绩,向对话框添加如表所示的控件,调整控件的位置,结果如图,4.3.4 示例:用对话框输入学生成绩,(5)选择“编排”“Tab Order”命令,或按快捷键Ctrl+D,此时每个控件的左上方都有一个数字,表明了当前Tab键次序,单击对话框中的控件,重新设置控件的Tab键次序,以保证旋转按钮控件的Tab键次序在相对应的编辑框(伙伴窗口)之后,结果如图所示,单击对话框或按Enter键结束Tab Order 方式。,双击对话框模板空白处,为该对话框模板创建一个对话框类CInputDlg。,4.3.4 示例:用对话框输入学生成绩,2.完善CInputDlg类代码在MFC ClassWizard的Member Variables页面中,确定Class name中是否已选择了CInputDlg,选中所需的控件ID号,双击鼠标或单击Add Variables按钮。依次为表控件增加成员变量。,4.3.4 示例:用对话框输入学生成绩,(2)在MFC ClassWizard的Messsage Maps页面中,为CInputDlg添加WM_INITDIALOG消息映射,并添加下列代码:BOOL CInputDlg:OnInitDialog()CDialog:OnInitDialog();m_spinScore1.SetRange(0,100);/设置旋按纽控件范围 m_spinScore2.SetRange(0,100);m_spinScore3.SetRange(0,100);return TRUE;/return TRUE unless you set the focus to a control,4.3.4 示例:用对话框输入学生成绩,用MFC ClassWizard为CInputDlg增加IDC_SPIN_S1控件的UDN_DELTAPOS消息映射,并添加下列代码:void CInputDlg:OnDeltaposSpinS1(NMHDR*pNMHDR,LRESULT*pResult)NM_UPDOWN*pNMUpDown=(NM_UPDOWN*)pNMHDR;UpdateData(TRUE);/将控件的内容保存到变量中m_fScore1+=(float)pNMUpDown-iDelta*0.5f;if(m_fScore1100.0)m_fScore1=100.0f;UpdateData(FALSE);/将变量的内容显示在控件中*pResult=0;,4.3.4 示例:用对话框输入学生成绩,调用对话框打开Ex_Ctrl1SDI单文档应用程序的菜单资源,添加顶层菜单项“测试(,4.3.4 示例:用对话框输入学生成绩,在文件MainFrm.cpp的前面添加CInputDlg类的头文件 包含:#include Ex_Ctrl1SDI.h#include MainFrm.h#include InputDlg.h“编译并运行,在应用程序的菜单上,选择“测试”“学 生成绩输入”菜单项,将弹出如图所示的对话框。单 击成绩1的旋转按钮控件将以0.5增量来改变它的伙伴窗 口的数值。而成绩2和成绩3的旋转按钮控件由于设置了 Set buddy integer属性,因此它按默认增量1自动改变伙 伴窗口的数值。,4.4.1 列表框的风格和消息,按性质来分,列表框有单选、多选、扩展多选以及非选四种类型。默认风格下的单选列表框让用户一次只能选择一个项,多选列表框可让用户选择几个项,扩展多选列表框允许用户用鼠标拖动或其他特殊组合键进行选择,非选列表框则不提供选择功能,如图,列表框还有一系列其它风格,用来定义列表框的外观及操作方式,这些风格可在如图(右上),4.4.1 列表框的风格和消息,列表框的Style属性,4.4.2 列表框的基本操作,添加列表项列表框创建时是一个空的列表,需要用户添加或插入一些列表项。CListBox类成员函数AddString 和InsertString 分别用来向列表框增加列表项,其函数原型如下:int AddString(LPCTSTR lpszItem);int InsertString(int nIndex,LPCTSTR lpszItem);,上述两个函数只能将字符串增加到列表框中,但有时用户还会需要根据列表项使用其他数据。这时,就需要调用CListBox的SetItemData和SetItemDataPtr,它们能使用户数据和某个列表项关联起来。int SetItemData(int nIndex,DWORD dwItemData);int SetItemDataPtr(int nIndex,void*pData);,4.4.2 列表框的基本操作,CListBox类成员函数DeleteString和ResetContent分别用来 删除指定列表项和清除列表框所有项目。它们函数原型如下:int DeleteString(UINT nIndex);/nIndex指定要删除的列表项的索引 void ResetContent();,3.查找列表项 为保证列表项不会重复地添加在列表框中,有时还需要 对列表项进行查找.CListBox类成员函数FindString 和 indStringExact分别用来在列表框中查找所匹配的列表项。其中,indStringExact的查找精度最高。int FindString(int nStartAfter,LPCTSTR lpszItem)const;int FindStringExact(int nIndexStart,LPCTSTR lpszFind)const;,2.删除列表项,4.4.2 列表框的基本操作,列表框的单项选择当选中列表框中某个列表项,用户可以使用ListBox:GetCurSel来获取这个结果,与该函数相对应的CListBox:SetCurSel 函数是用来设定某个列表项呈选中状态(高亮显示)。int GetCurSel()const;/返回当前选择项的索引 int SetCurSel(int nSelect);其中,nSelect指定要设置的列表项索引,错误时这两个 函数都将返回LB_ERR。若要获取某个列表项的字符串,可使用下列函数:int GetText(int nIndex,LPTSTR lpszBuffer)const;void GetText(int nIndex,CString 其中,nIndex指定列表项索引,lpszBuffer 和rString是 用来存放列表项文本。,4.4.2 列表框的基本操作,列表框的多项选择当在列表框的Style属性对话框中选中多选(Multiple)或扩展多选(Extended)类型后,就可以在列表框中进行多项选择。要获得需要用FCClassWizard映射列表框控件LBN_SELCHANGE消息,并添加类似下面的一些代码:void CListBoxDlg:OnSelchangeList1()int nCount=m_list.GetSelCount();/获取用户选中的项数 if(nCount=LB_ERR)return;int*buffer=new intnCount;/开辟缓冲区 m_list.GetSelItems(nCount,buffer)/将各个选项的索引号内容放在缓冲区中 CString allStr=NULL,str;for(int i=0;inCount;i+)m_list.GetText(bufferi,str);/获得各个索引的项目文本 allStr=allStr+str+;/处理项目文本 delete buffer;/释放内存/MessageBox(allStr);/处理获得的文本,示例:城市邮政编码,在一组城市邮政编码中,城市名和邮政编码是一一对应的。为了能添加和删除城市邮政编码列表项,需要设计一个这样的对话框,如图所示。单击添加按钮,将城市名和邮政编码添加到列表框中,为了使添加不重复,还要进行一些判断操作,单击列表框的城市名,将在编辑框中显示出城市名和邮政编码,单击删除按钮,删除当前的列表项。,示例:城市邮政编码,例Ex_Ctrl2SDI 创建并使用城市邮政编码对话框1.添加并设计对话框(1)用MFC AppWizard(exe)创建一个默认的单文档应用程序Ex_Ctrl2SDI。(2)向应用程序中添加一个对话框资源IDD_CITYZIP,标题定为“城市邮政编码”,字体设为“宋体,9号”,创建此对话框类为CCityDlg。(3)删除原来的Cancel按钮,将OK按钮标题改为“退出”。(4)打开对话框网格,用编辑器为对话框添加如表所示的一些控。,示例:城市邮政编码,2.完善CCityDlg类代码打开ClassWizard的Member Variables页面,看看Class name是否是CCityDlg,然后选中所需的控件ID号,双击鼠标或单击Add Variables按钮,依次为下列控件增加成员变量。如表,4.4.3 示例:城市邮政编码,(2)将项目工作区切换到ClassView页面,右击CCityDlg类名,从弹出的快捷菜单中选择“Add Member Function”,弹出如图所示的对话框,在Function Type(函数类型)框中输入BOOL,在Function Declaration(函数声明)框中输入IsValidate,单击OK按钮。,4.4.3 示例:城市邮政编码,(3)在CCityDlg:IsValidate函数输入下列代码:BOOL CCityDlg:IsValidate()UpdateData();m_strCity.TrimLeft();if(m_strCity.IsEmpty()MessageBox(城市名输入无效!);return FALSE;return TRUE;IsValidate函数的功能是判断城市名编辑框中的内容是否是有效的字符串。代码中,TrimLeft是CString类的一个成员函数,用来去除字符串左边的空格。,4.4.3 示例:城市邮政编码,打开MFC ClassWizard,切换到Messsage Maps页面,为对话框添加WM_INITDIALOG消息映射,并增加下列代码:BOOL CCityDlg:OnInitDialog()CDialog:OnInitDialog();m_dwZipCode=100000;/设置初始的邮政编码 UpdateData(FALSE);/将邮政编码显示在控件中 GetDlgItem(IDC_BUTTON_DEL)-EnableWindow(FALSE);/使删除按钮灰显 return TRUE;/return TRUE unless you set the focus to a control,4.4.3 示例:城市邮政编码,打开MFC ClassWizard,切换到Messsage Maps页面,为按钮IDC_BUTTON_ADD添加BN_CLICK