第5讲列表控件.docx
《第5讲列表控件.docx》由会员分享,可在线阅读,更多相关《第5讲列表控件.docx(17页珍藏版)》请在冰豆网上搜索。
![第5讲列表控件.docx](https://file1.bdocx.com/fileroot1/2023-1/31/f7884216-6f60-46d0-b294-7cd460b6e9f9/f7884216-6f60-46d0-b294-7cd460b6e9f91.gif)
第5讲列表控件
第五讲列表控件
本讲主要介绍组合框(ComboBox)控件和列表框(ListBox)控件的的使
用方法。
一.创建一个基于对话框的应用程序模板
1.选择应用程序类型:
选择“File\New”菜单→在弹出的“New”对话框的选择“Projects”
选项卡→应用程序类型选择“MFCAppWizard(exe)”→“Project
name”编辑框中输入“ListBox”→“Location”编辑框中输入适当的
路径→单击“OK”
2.选择项目类型
在“MFCAppWizar–Step1”对话框中“Dialogbased”单选钮→
单击“Finish”按钮。
二.修改对话框模板
把主对话框模板修改成如下图所示:
图6-1
1.增加“编号”、“姓名”、“出生年月”、“性别”、“职称”和“职工情况列表”
等六个静态文本
2.在“编号”右侧增加一个下沉风格的静态文本,资源符号为:
IDC_NUMBER
在“Styles”选项卡的“Center-vertically”复选钮:
选中
3.在“姓名”和“出生年月”右侧,增加二个编辑框,资源符号分别为:
IDC_NAME,IDC_BIRTHDAY
4.在“性别”和“职称”右侧,增加二个组合框,资源符号分别命名为:
IDC_SEX在ComboBoxProperties对话框的styles选项卡的
type下拉列表框中选择DropList
注:
DropList选项不允许组合框编辑输入
IDC_TITLE在ComboBoxProperties对话框的styles选项卡的
type下拉列表框中选择DropList
注:
Dropdown选项允许组合框编辑输入
5.增加“添加”、“删除当前选定行”和“在选定行前插入”三个按钮,ID值命
名为:
IDC_ADD,IDC_DELETE,IDC_INSERT
6.在“职工情况列表”的下方,增加一个列表控件”ListControl”:
在”ListControlProperties”对话框中如下设置:
A.在General选项卡的ID组合框中输入:
IDC_LIST
B.在Styles选项卡中选择:
“View:
”下拉列表框:
Report
“Align:
”下拉列表框:
Top
“Sort:
”下拉列表框:
Ascending
“Singleselection”复选框:
选中
三.为控件连接变量
为各控件连接的变量名及其值类型和变量类型如下(连接方法前已述):
控件ID变量名变量类别变量类型
IDC_NUMBERm_nNumbervalueCString
IDC_NAMEm_sNamevalueCString
IDC_BIRTHDAYm_sBirthdayvalueCString
IDC_SEXm_nSexvalveint
m_cSexControlCComboBox
IDC_TITLEm_sTitlevalueCString
m_cTitleControlCComboBox
IDC_LISTm_cListControlCListBox
注:
IDC_TITLE组合框控件上各连连接了两个变量,它们值类型分别为value
和Control,连接方法是对同一个控件ID,两次使用“AddVariables…”
即可。
四.组合框控件的初始化
1.在CListBoxDlg类中添加二个成员变量:
变量类型变量名作用域
CStringstrTitlepublic
CStringm_sSexpublic
2.在CListBoxDlg类的构造函数中对变量strTitle初始化:
strTitle="助教/讲师/副教授/教授/";
3.在CListBoxDlg类中添加一个函数:
函数类型:
void函数名:
InitCombo()作用域:
Protected
4.编写函数InitCombo()成:
voidCListBoxDlg:
:
InitCombo()
{
inti,n;
CStrings1[2]={"男","女"};
for(i=0;i<2;i++)m_cSex.AddString(s1[i]);
CStrings,s2=strTitle;
while(s2!
="")
{
n=s2.Find('/',0);
s=s2.Left(n);
m_cTitle.AddString(s);
s2.Delete(0,n+1);
}
}
3.在CListBoxDlg类的OnInitDialog()函数中添加一条语句:
//TODO:
Addextrainitializationhere
InitCombo();
4.编译并运行程序,观察程序的运行情况
五.组合框内容的获取
经过下拉列表的选择或编辑输入后,组合框中具有了内容,要获取这些
内容可如下操作:
1.为组合框控件IDC_SEX增加一个CBN_SELCHANGE消息响应函数
OnSelchangeSex()如下:
1)选择“View\ClassWizard…”菜单项
2)在弹出的MFCClasswizard对话框中如下操作:
A.选择MessageMaps选项卡
B.在Classname下拉列表框中选择CListBoxDlg类
C.在ObjectIDs列表框中选择:
IDC_SEX
D.在Messages列表框中选择CBN_SELCHANGE
E.单击AddFunction按钮,在弹出的Addmemberfunction对话框中
单击OK按钮
F.再单击MFCClasswizard对话框的“Editcode”按钮,进入函数编
辑
3)编写OnSelchangeSex()如下:
voidCListBoxDlg:
:
OnSelchangeSex()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
intn=m_cSex.GetCurSel();
if(n!
=CB_ERR)m_cSex.GetLBText(n,m_sSex);
}
2.为组合框控件IDC_TITLE增加一个CBN_SELCHANGE消息响应函数
OnSelchangeTitle(),方法同上,函数程序如下:
voidCListBoxDlg:
:
OnSelchangeTitle()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData();
intn=m_cTitle.GetCurSel();
if(n!
=CB_ERR)m_cTitle.GetLBText(n,m_sTitle);
}
3.为按钮控件IDC_ADD添加一个BN_CLICKED消息响应函数OnAdd()如下:
voidCListBoxDlg:
:
OnAdd()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringstr="性别:
"+m_sSex+"\n\n职称:
"+m_sTitle;
MessageBox(str);
}
4.编译并运动程序,观察程序的运行情况。
由程序的运行情况可见:
通过下拉列表选择的内容能正确地获取,但在
IDC_TITLE控件中通过编辑输入的数据无法正确地获取。
为解决这一问
题并使编辑输入的内容能增添到下拉列表中,可如下操作:
A.仿上,为控件IDC_TITLE增添一条CBN_KILLFOCUS消息响应函数:
OnKillfocusTitle()
B.编写函数体如下:
voidCListBoxDlg:
:
OnKillfocusTitle()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
//获取编辑输入的内容
UpdateData();
intn=m_cTitle.GetCurSel();
if(n!
=CB_ERR)m_cTitle.GetLBText(n,m_sTitle);
//把编辑输入的内容增添到下拉列表中
if(m_sTitle!
=""&&strTitle.Find(m_sTitle,0)<0)
{
m_cTitle.AddString(m_sTitle);
strTitle=strTitle+m_sTitle+'/';
}
}
C.再编译并运行程序,观察运行情况。
六.列表框ListBox的初始化
1.在CListBoxDlg类中添加一个函数:
函数类型:
void函数名:
InitList()作用域:
Protected
2.编定函数体如下:
voidCListBoxDlg:
:
InitList()
{
m_cList.InsertColumn(0,"编号",LVCFMT_LEFT,70);
m_cList.InsertColumn(1,"姓名",LVCFMT_LEFT,70);
m_cList.InsertColumn(2,"出生年月",LVCFMT_LEFT,70);
m_cList.InsertColumn(3,"性别",LVCFMT_LEFT,70);
m_cList.InsertColumn(4,"职称",LVCFMT_LEFT,70);
①m_cList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
}
注:
①行设置列表控件的行被选中时整行反白显示
3.在CListBoxDlg类的OnInitDialog()函数中添加几条语句(红色):
//TODO:
Addextrainitializationhere
InitCombo();
InitList();
4编译并运行程序,观察程序的运行界面
七.在列表控件中增添、删除和插入内容
1.把输入内容增添到列表控件中
A.在CListBoxDlg类中增加一个protected类int型变量:
m_nNumber,
并在CListBoxDlg类的构造函数中添加以下赋值语句:
m_nNumber=1;
B.在CListBoxDlg类的OnInitDialog()函数中添加四条语句(红色):
InitList();
①m_sNumber.Format("%d",m_nNumber);
②GetDlgItem(IDC_DELETE)->EnableWindow(false);
③GetDlgItem(IDC_INSERT)->EnableWindow(false);
④UpdateData(false);
注:
①句:
给编号赋初值
②③:
由于刚开始时列表控件中尚无任何内容,故不能“删除”或
“插入”
④句:
回显数据。
C.修改OnAdd()函数成:
voidCListBoxDlg:
:
OnAdd()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
intm,n;
UpdateData();
m=m_cTitle.GetCurSel();//获取IDC_TITLE控件内容
if(m!
=CB_ERR)m_cTitle.GetLBText(m,m_sTitle);
m=m_cSex.GetCurSel();//获取IDC_SEX控件内容
if(m!
=CB_ERR)m_cSex.GetLBText(m,m_sSex);
if(m_sName==""||m_sBirthday==""||m_sSex==""||m_sTitle=="")
return;
//把输入内容增添到列表控件中
n=m_cList.InsertItem(0,m_sNumber);
m_cList.SetItemText(n,1,m_sName);
m_cList.SetItemText(n,2,m_sBirthday);
m_cList.SetItemText(n,3,m_sSex);
m_cList.SetItemText(n,4,m_sTitle);
m_nNumber++;//把职工资料初始化为空
m_sNumber.Format("%d",m_nNumber);
m_sName="";
m_sBirthday="";
m_sSex="";
m_nSex=-1;//把性别组合框设置成空
m_sTitle="";
GetDlgItem(IDC_NAME)->SetFocus();//把输入焦点置于IDC_NAME
//控件上
UpdateData(false);
}
D.编译并运行程序,观察运行结果。
此时,编辑框和组合框中的输入内容能依次添加到列表控件中,并且,
若输入内容不全,会拒绝添加。
2.删除列表控件中选定行的内容
A.用“MFCCLasswizard”对话框,为控件IDC_LIST添加一个消息响应函
数OnClickList(),并编写该函数如下:
voidCListBoxDlg:
:
OnClickList(NMHDR*pNMHDR,LRESULT*pResult)
{
//TODO:
Addyourcontrolnotificationhandlercodehere
*pResult=0;
intn=m_cList.GetNextItem(-1,LVNI_SELECTED);
if(n!
=-1)//若所选行有效,则向对话框回显其内容
{
m_sNumber=m_cList.GetItemText(n,0);
m_sName=m_cList.GetItemText(n,1);
m_sBirthday=m_cList.GetItemText(n,2);
m_sSex=m_cList.GetItemText(n,3);
m_nSex=(m_sSex=="男")?
0:
1;//把性别回显至性别组合框
m_sTitle=m_cList.GetItemText(n,4);
GetDlgItem(IDC_DELETE)->EnableWindow(true);
GetDlgItem(IDC_INSERT)->EnableWindow(true);
GetDlgItem(IDC_ADD)->SetWindowText("修改");
UpdateData(false);
}
}
B.用“MFCCLasswizard”对话框,为控件IDC_DELETE添加一个消息响应
函数OnDelete(),并编写该函数如下:
voidCListBoxDlg:
:
OnDelete()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
intn;
CStrings1,s2,s3,s4,str;
n=m_cList.GetNextItem(-1,LVNI_SELECTED);
if(n!
=-1)
{
m_cList.DeleteItem(n);
m_nNumber--;
m_sNumber.Format("%d",m_nNumber);
m_sName="";
m_sBirthday="";
m_nSex=-1;
m_sTitle="";
UpdateData(false);
}
}
C.编译并运行程序,可见:
能在列表框中删除选行的内容,但删除内容的编号不再连续,并且按
钮IDC_APPEND的行为不正常,为解决上述问题,应:
D.在OnAdd()函数中增添几条语句(红色):
if(m_sName==""||m_sBirthday==""||m_sSex==""||m_sTitle=="")
return;
boolbState=GetDlgItem(IDC_DELETE)->IsWindowEnabled();
if(bState)//"删除"按钮可用时,先删除所选行
{
n=m_cList.GetNextItem(-1,LVNI_SELECTED);
m_cList.DeleteItem(n);
GetDlgItem(IDC_DELETE)->EnableWindow(false);
GetDlgItem(IDC_INSERT)->EnableWindow(false);
GetDlgItem(IDC_ADD)->SetWindowText("添加");
m_nNumber--;
}
E.函数OnDelete()应如下编写:
voidCListBoxDlg:
:
OnDelete()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti,n,ItemNo;
CStrings[5];
CStringstr="";
n=m_cList.GetNextItem(-1,LVNI_SELECTED);
m_cList.DeleteItem(n);
ItemNo=m_cList.GetItemCount();
for(n=0;n{
for(i=1;i<5;i++)
{
s[i]=m_cList.GetItemText(n,i);
str=str+s[i]+"/";
}
}
m_cList.DeleteAllItems();
for(n=0;n{
m_sNumber.Format("%d",n+1);
m_sName=str.Left(i=str.Find("/",0));
str.Delete(0,i+1);
m_sBirthday=str.Left(i=str.Find("/",0));
str.Delete(0,i+1);
m_sSex=str.Left(i=str.Find("/",0));
str.Delete(0,i+1);
m_sTitle=str.Left(i=str.Find("/",0));
str.Delete(0,i+1);
n=m_cList.InsertItem(0,m_sNumber);
m_cList.SetItemText(n,1,m_sName);
m_cList.SetItemText(n,2,m_sBirthday);
m_cList.SetItemText(n,3,m_sSex);
m_cList.SetItemText(n,4,m_sTitle);
}
m_nNumber=ItemNo+1;//把职工资料初始化为空
m_sNumber.Format("%d",m_nNumber);
m_sName="";
m_sBirthday="";
m_sSex="";
m_cSex.SetCurSel(-1);
m_sTitle="";
GetDlgItem(IDC_DELETE)->EnableWindow(false);
GetDlgItem(IDC_INSERT)->EnableWindow(false);
GetDlgItem(IDC_APPEND)->SetWindowText("添加");
GetDlgItem(IDC_NAME)->SetFocus();//把输入焦点置于IDC_NAME
//控件上
UpdateData(false);
}
F.上述函数OnDelete()编写得较复杂,当列表框中数据较多时更新速度较
慢,并且可能产生意想不到的问题。
为此,函数OnDelete()可在功能不
变的前提下简化如下:
voidCListBoxDlg:
:
OnDelete()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti,n,ItemNo,m,nc;
CStrings[5];
CStringstr="";
n=m_cList.GetNextItem(-1,LVNI_SELECTED);
m_cList.DeleteItem(n);
ItemNo=m_cList.GetItemCount();
for(m=n;m{
for(i=1;i<5;i++)s[i]=m_cList.GetItemText(m,i);
m_cList.DeleteItem(m);
s[0].Format("%d",m+1);
nc=m_cList.InsertItem(0,m_sNumber);
for(i=1;i<5;i++)m_cList.SetItemText(nc,i,s[i]);
}
m_nNumber=ItemNo+1;//把职工资料初始化为空
m_sNumber.Format("%d",m_nNumber);
m_sName="";
m_sBirthday="";
m_sSex="";
m_nSex=-1;
m_sTitle="";
GetDlgItem(IDC_DELETE)->EnableWindow(false);
GetDlgItem(IDC_INSERT)->EnableWindow(false);
GetDlgItem(IDC_ADD)->SetWindowText("添加");
GetDlgItem(IDC_NAME)->SetFocus();//把输入焦点置于IDC_NAME
//控件上
UpdateData(false);
}
3.在列表控件的选定行前插入内容
A.为“插入”按钮控件添加一条消息响应函数OnInsert();
B.编写OnInsert()函数如下:
voidCListBoxDlg:
:
OnInsert()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti,n,ItemNo,m,nc;
CStrings[5];
n=m_cList.GetNextItem(-1,LVNI_SELECTED);
ItemNo=m_cList.GetItemCount();
for(m=ItemNo-1;m>=n;m--)
{
for