zoukankan      html  css  js  c++  java
  • MFC编程入门之二十四(常用控件:列表框控件ListBox)

      前面两节讲了比较常用的按钮控件,并通过按钮控件实例说明了具体用法。本文要讲的是列表框控件(ListBox)及其使用实例。

      列表框控件简介

      列表框给出了一个选项清单,允许用户从中进行单项或多项选择,被选中的项会高亮显示。列表框可分为单选列表框和多选列表框,顾名思义,单选列表框中一次只能选择一个列表项,而多选列表框可以同时选择多个列表项。

      列表框也会向父窗口发送通知消息。这些通知消息含义如下:

      LBN_DBLCLK:用户用鼠标双击了一列表项,只有具有LBS_NOTIFY的列表才能发送该消息。

      LBN_ERRSPACE:列表框不能申请足够的动态内存来满足需要。

      LBN_KILLFOCUS:列表框失去焦点。

      LBN_SELCANCEL:当前的选择被取消,只有具有LBS_NOTIFY的列表框才能发送该消息。

      LBN_SETFOCUS:列表框获得输入焦点。

      WM_CHARTOITEM:当列表框收到WM_CHAR消息后,向父窗口发送该消息,只有具有LBS_WANTKEYBOARDINPUT风格的列表框才会发送该消息。

      WM_VKEYTOITEM:当列表框收到WM_KEYDOWN消息后,向父窗口发送该消息,只有具有LBS_WANTKEYBOARDINPUT风格的列表框才会发送该消息。

      列表框控件的创建

      MFC将列表框控件的所有操作都封装到了CListBox类中。

      创建列表框控件时,可以在对话框模板中直接拖入列表框控件ListBox,然后添加控件变量使用。但如果需要动态创建列表框,就要用到CListBox类的Create成员函数了。Create成员函数的原型如下:

      virtual BOOL Create(

        DWORD dwStyle,

        const RECT& rect,

        CWnd* pParentWnd,

        UINT nID

      );

      参数rect指定了列表框控件的位置和尺寸,pParentWnd为父窗口的指针,nID用于指定列表框控件的ID。最后终点讲讲参数dwStyle,它指定了列表框的风格,以下是各种风格的说明:

      LBS_EXTENDEDSEL:支持多重选择,在点击列表框项时按住Shift键或Ctrl键即可选择多个项。

      LBS_MULTICOLUMN:指定一个水平滚动的多列列表框,通过调用CListBox::SetColumnWidth来设置每列的宽度。

      LBS_MULTIPLESEL:支持多重选择。列表项的选择状态随着用户对该项单机或双击鼠标而翻转。

      LBS_NOINTEGRALHEIGHT:列表框的尺寸由应用程序而不是Windows指定。通常,Windows指定尺寸会使列表项的某些部分隐藏起来。

      LBS_NOREDRAW:当选择发生变化时防止列表框被更新,可发送消息改变改变该风格。

      LBS_NOTIFY:当用户单击或双击鼠标时通知父窗口。

      LBS_OWNERDRAWFIXED:指定自绘式列表框,即由父窗口负责绘制列表框的内容,并且列表项具有相同的高度。

      LBS_SORT:使插入列表框中的项按升序排列。

      LBS_STANDARD:相当于指定了WS_BORDER|WS_VSCROLL|LBS_SORT。

      LBS_USETABSTOPS:使列表框在显示列表项时识别并扩展制表符(' '),默认的制表宽度是32个对话框单位。

      LBS_WANTKEYBOARDINPUT:允许列表框的父窗口接收WM_VKEYTOITEM和WM_CHARTOITEM消息,以响应键盘输入。

      LBS_DISABLEENOSCROLL:使列表框在不需要滚动时显示一个禁止的垂直滚动条。

      dwStyle可以是以上所列风格的组合。与其他控件一样,除了这些风格一般还要为列表框控件设置WS_CHILD、WS_VISIBLE、WS_TABSTOP、WS_BORDER、WS_VSCROLL等风格。一般创建单选列表框时,风格要设置为:WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_STANDARD,如果不希望列表框排序显示则应去掉LBS_STANDARD。创建多选列表框时,只需要在单选列表框风风格后添加LBS_MULTIPLESEL或LBS_EXTENDEDSEL风格。

      对于对话框模板中直接添加的列表框控件,其属性页中的属性也包含了以上风格,例如属性Multicolumn对应的就是LBS_MULTICOLUMN风格。

      CListBox类的主要成员函数

      int GetCount() const;

      返回值:返回列表框中列表项的数目,如果发生错误则返回LB_ERR。

      int GetSel(int nIndex) const;

      参数:nIndex指定某个列表项的索引。

      返回值:返回nIndex制定的列表项的状态。如果此列表项倍选择了则返回一个正值,否则返回0,若发生错误则返回LB_ERR。

      int SetSel(int nIndex, BOOL bSelect = TRUE);

      此函数用于多选列表框,使用它可以选择或取消选择指定的列表项。

      参数:nIndex指定某个列表项的索引,若为-1则相当于指定了所有列表项。bSelect为TRUE时选择制定列表项,否则取消选择列表项。

      返回值:如果发生错误则返回LB_ERR。

      int AddString(LPCTSTR lpszItem);

      此函数用来向列表框中添加字符串。如果列表框指定了LBS_SORT风格,字符串就被以排序顺序插入到列表框中,如果没有指定LBS_SORT风格,字符串就被添加到列表框的结尾。

      参数:lpszItem指定了要添加的字符串。

      返回值:返回字符串在列表框中添加的位置。如果发生错误则返回LB_ERR,内存不够则返回LB_ERRSPACE。

      int InsertString(int nIndex, LPCTSTR lpszItem);

      该函数用来在列表框中的指定位置插入字符串。与AddString函数不同的是,InsertString函数不会导致LBS_SORT风格列表框重新排序。不要在具有LBS_SORT风格的列表框中使用InsertString函数,以免破坏列表项的次序。

      参数:参数nIndex给出了插入位置(索引),如果值为-1,则字符串将被添加到列表的末尾。参数lpszItem指定了要插入的字符串。

      返回值:返回实际的插入位置,若发生错误,会返回LB_ERR或LB_ERRSPACE。

      int DeleteString(UINT nIndex);

      该函数用于删除指定的列表项。

      参数:nIndex指定了要删除项的索引。

      返回值:函数的返回值为剩下的列表项数目,如果nIndex超过了实际的列表项总数,则返回LB_ERR。

      void ResetContent();

      该函数用于清除所有列表项。

      int GetText(int nIndex, LPCTSTR lpszBuffer) const;

      void GetText(int nIndex, CString& rString) const;

      这两个成员函数用于获取指定列表项的字符串。参数nIndex指定了列表项的索引。参数lpszBuffer指向一个接收字符串的缓冲区。引用参数rString则指定了接收字符串的CString对象。第一个版本的函数会返回获得的字符串的长度,若出错,则返回LB_ERR;第二个版本的函数则不会。

      int GetTextLen(int nIndex) const;

      该函数返回指定列表项的字符串的字节长度。

      参数:nIndex指定了列表项的索引。

      返回值:若出错则返回LB_ERR。

      int GetCurSel() const;

      该函数仅适用于单选列表框,用来返回当前被选择项的索引,如果没有列表项被选择或有错误发生,则函数返回LB_ERR。

      

      int SetCurSel(int nSelect);

      该函数仅适用于单选列表框,用来选择指定的列表项。该函数会滚动列表框以使选择项可见。参数nIndex指定了列表项的索引,若为-1,那么将清除列表框中的选择。若出错函数返回LB_ERR。

      int GetSelCount() const;

      该函数仅用于多重选择列表框,它返回选择项的数目,若出错函数返回LB_ERR。

      int FindString(int nStartAfter, LPCTSTR lpszItem) const;

      该函数用于对列表项进行与大小无关的搜索。参数nStartAfter指定了开始搜索的位置,合理指定nStartAfter可以加快搜索速度,若nStartAfter为-1,则从头开始搜索整个列表。参数lpszItem指定了要搜索的字符串。函数返回与lpszItem指定的字符串相匹配的列表项的索引,若没有找到匹配项或发生错误,则会返回LB_ERR。FindString函数想从nStartAfter指定的位置开始搜索,若没有找到匹配项,则会从头开始搜索列表。只有找到匹配项,或对整个列表搜索完一遍后,搜索过程才会停止,所以不必担心会漏掉要搜索的列表项。

      

      int SelectString(int nStartAfter, LPCTSTR lpszItem);

      该函数仅适用于单选列表框,用来选择与指定字符串相匹配的列表项。该函数会滚动列表框以使选择项可见。参数的意义及搜索的方法与函数FindString类似。如果找到了匹配的项,函数返回该项的索引,如果没有匹配的项,函数返回LB_ERR并且当前的选择不被改变。

      

      CListBox类应用实例

      最后给大家写一个简单的实例,说明CListBox的几个成员函数及通知消息等的使用方法。此实例实现的功能:在单选列表框中显示一个网站列表,然后再用鼠标左键选择某列表项时,将选中列表项的文本显示到编辑框中。下面是具体实现步骤:

      1、创建一个基于对话框的MFC工程,名称设置为”MFCListBoxDemo“。

      2、在自动生成的对话框模板IDD_MFCLISTBOXDEMO_DIALOG中,删除"TODO:Place dialog controls here."静态文本框、“确定”按钮和“取消”按钮。添加一个ListBox控件,ID设置为IDC_WEB_LIST,Sort属性设为False,以取消排序显示。再添加一个静态文本控件和一个编辑框,静态文本控件的Caption属性设为“您选择的站点:”,编辑框的ID设为IDC_SEL_WEB_EDIT,Read Only属性设为True。此时的对话框模板如下图:

      3、为列表框IDC_WEB_LIST添加CListBox类型的控件变量m_listBox。

      4、在对话框初始化时,我们将站点名加入到列表框,那么需要修改CMFCListBoxDemoDlg::OnInitDialog()函数为:

    C++代码:

    BOOL CMFCListBoxDemoDlg::OnInitDialog()
    {
    	CDialogEx::OnInitDialog();
    
    	// 将“关于...”菜单项添加到系统菜单中。
    
    	// IDM_ABOUTBOX 必须在系统命令范围内。
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		BOOL bNameValid;
    		CString strAboutMenu;
    		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    		ASSERT(bNameValid);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    	//  执行此操作
    	SetIcon(m_hIcon, TRUE);			// 设置大图标
    	SetIcon(m_hIcon, FALSE);		// 设置小图标
    
    	// TODO: 在此添加额外的初始化代码
    	m_listBox.AddString(_T("新浪"));	// 在列表框末尾添加字符串“新浪”
    	m_listBox.AddString(_T("博客园"));	// 在列表框末尾添加字符串“博客园”
    	m_listBox.AddString(_T("猫扑"));	// 在列表框结尾处添加字符串“猫扑”
    	m_listBox.AddString(_T("网易"));	// 在列表框结尾处添加字符串“网易”
    	m_listBox.InsertString(2, _T("百度"));	// 在列表框中索引为2的位置插入字符串“百度”
    
    	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    

      5、我们希望在选中列表项改变时,将最新的选择项实时显示到编辑框中,那么这就要用到LBN_SELCHANGE通知消息。为列表框IDC_WEB_LIST的通知消息LBN_SELCHANGE添加消息处理函数CMFCListBoxDemoDlg::OnLbnSelchangeWebList(),并修改如下:

    C++代码:

    void CMFCListBoxDemoDlg::OnLbnSelchangeWebList()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	CString strText;
    	int nCurSel;
    
    	nCurSel = m_listBox.GetCurSel();	// 获取当前选中列表项
    	m_listBox.GetText(nCurSel, strText);	// 获取选中列表项的字符串
    	SetDlgItemText(IDC_SEL_WEB_EDIT, strText);	//将选中列表项的字符串显示到编辑框中
    }
    

      6、运行程序,弹出结果对话框,在对话框的列表中用鼠标改变选中项时,编辑框的显示会相应改变。效果图如下:

      关于列表框ListBox的讲解就到此为止了。如果大家想试验更多的列表框成员函数,可以在上面的小例子中加入更多的更能来体会。

  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/mupiaomiao/p/6249118.html
Copyright © 2011-2022 走看看