Visual C++程序开发范例宝典(软件工程师典藏版)
上QQ阅读APP看书,第一时间看更新

2.4 列表框控件典型实例

利用列表框控件浏览数据具有简洁、直观的特点,在开发应用程序时经常用到该控件,本节通过几个实例介绍列表框控件在程序中的应用。

实例051 利用列表框控件实现标签式数据选择

本实例可以方便操作、提高效率

实例位置:光盘\mingrisoft\02\051

实例说明

本实例实现了列表控件的标签复选功能。运行程序,列表中有4项,分别对应窗体上面的4个按钮,列表中哪一项处于选中状态,对应的按钮就可用,实例运行结果如图2.12所示。

图2.12 利用ListBox控件实现标签式数据选择

技术要点

本实例主要通过CCheckListBox类实现,CCheckListBox类是对CListBox类的扩充,使ListBox具有标签复选功能。通过CCheckListBox类的SetCheckStyle方法实现列表的标签复选样式,然后通过SetCheck方法使列表项前的复选框处于选中状态,通过GetCheck方法获得列表项前的复选框状态,如果方法返回1表示已经选中,如果返回0表示没有被选中。

实现过程

(1)新建一个基于对话框的应用程序。

(2)在对话框上添加5个按钮控件和1个列表框控件,设置ID属性为IDC_DATALIST,将Owner draw属性改为Fixed,并设置Has strings属性,去除Sort属性。添加成员变量m_chklist,并将其改为继承自CCheckListBox类。

(3)在对话框初始化时向列表框中添加数据,设置按钮控件不可用,代码如下:

        BOOL CListboxChkSelDlg::OnInitDialog()
        {
            CDialog::OnInitDialog();
            //…此处代码省略
            m_chklist.SetCheckStyle(BS_CHECKBOX);
            m_chklist.AddString("浏览文件");
            m_chklist.AddString("操作数据库");
            m_chklist.AddString("前台操作");
            m_chklist.AddString("后台管理");
            GetDlgItem(IDC_VIEW)->EnableWindow(FALSE);
            GetDlgItem(IDC_DATABASE)->EnableWindow(FALSE);
          GetDlgItem(IDC_FRONT)->EnableWindow(FALSE);
          GetDlgItem(IDC_BACK)->EnableWindow(FALSE);
          return TRUE;
        }

(4)处理“设置权限”按钮的单击事件,在该事件的处理函数中设置与列表中选中复选框的按钮可用,代码如下:

        void CListboxChkSelDlg::OnOper()
        {
          //判断列表项前的复选框是否选中,如果选中则设置对应按钮可用
          if(m_chklist.GetCheck(0))
            GetDlgItem(IDC_VIEW)->EnableWindow(TRUE);
          else
            GetDlgItem(IDC_VIEW)->EnableWindow(FALSE);
          if(m_chklist.GetCheck(1))
            GetDlgItem(IDC_DATABASE)->EnableWindow(TRUE);
          else
            GetDlgItem(IDC_DATABASE)->EnableWindow(FALSE);
          if(m_chklist.GetCheck(2))
            GetDlgItem(IDC_FRONT)->EnableWindow(TRUE);
          else
            GetDlgItem(IDC_FRONT)->EnableWindow(FALSE);
          if(m_chklist.GetCheck(3))
            GetDlgItem(IDC_BACK)->EnableWindow(TRUE);
          else
            GetDlgItem(IDC_BACK)->EnableWindow(FALSE);
        }

(5)处理列表框控件的双击事件,当双击列表控件中的列表项时,将对应列表项前的复选框选中,代码如下:

        void CListboxChkSelDlg::OnDblclkChklist()
        {
          int i=m_chklist.GetCurSel();   //获得当前选中列表项索引
          if(i<0)return;
          if(m_chklist.GetCheck(i)<1)   //如果当前列表项没被勾选
            m_chklist.SetCheck(i,1);    //勾选当前列表项的复选框
          else                          //否则
            m_chklist.SetCheck(i,0);    //去掉当前列表项的选择状态
        }

举一反三

根据本实例,读者可以:

开发设置操作员权限的程序。

实例052 位图背景列表框控件

本实例是一个提高基础技能的程序

实例位置:光盘\mingrisoft\02\052

实例说明

图2.13 位图背景列表框控件

在实际的应用程序中,除了设置列表框的各种属性以外,还可以为列表框添加位图背景。本实例实现的是位图背景的列表框控件,运行结果如图2.13所示。

技术要点

本实例可以使用GetItemRect方法、GetTopIndex方法和GetText方法来实现。

(1)GetItemRect方法。GetItemRect方法用于获得列表项区域,语法如下:

int GetItemRect( int nIndex, LPRECT lpRect ) const;

参数说明:

● nIndex:确定项的基于零的索引。

● lpRect:指定指向RECT结构的长型指针,接收项的列表框客户区坐标。

(2)GetTopIndex方法。GetTopIndex方法用于获得列表框中第一个可见项的基于零的索引,语法如下:

int GetTopIndex( ) const;

(3)GetText方法。GetText方法用于获得指定列表项的显示文本,语法如下:

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

参数说明:

● nIndex:指定获取的字符串的基于零的索引。

● lpszBuffer:指向接收字符串的缓冲区的指针。缓冲区必须有足够的空间来存储字符串和终止字符。字符串大小可以通过调用GetTextLen成员函数提前指定。

● rString:CString对象。

实现过程

(1)新建一个基于对话框的应用程序。

(2)以CListBox类为基类派生一个CListBmp类。

(3)在对话框中添加一个列表框控件,为控件添加CListBmp类的成员变量m_List,向工程中导入一个位图资源。

(4)在CListBmp类中添加OnPaint方法绘制列表框控件的背景位图,代码如下:

        void CListBmp::OnPaint()
        {
            CPaintDC dc(this);
            CRect rect,clrRC;
            GetClientRect(&rect);                                            //获得控件客户区域
            CBitmap bitmap;
            CDC memdc;
            memdc.CreateCompatibleDC(&dc);                                   //创建兼容的设备上下文
            bitmap.LoadBitmap(IDB_BITMAP1);                                  //加载位图资源
            memdc.SelectObject(&bitmap);                                     //选入位图对象
            dc.BitBlt(0,0,rect.Width(),rect.Height(),&memdc,0,0,SRCCOPY);    //绘制位图背景
            bitmap.DeleteObject();
            ReleaseDC(&memdc);
            for(int i=0;i<rect.Height()/GetItemHeight(0);i++)
            {
                  GetItemRect(i,clrRC);                                      //获得列表项区域
                  CString str;
                  GetText(i+GetTopIndex(),str);                              //获得列表项文本
                  dc.SetBkMode(TRANSPARENT);                                 //设置背景透明
                  dc.TextOut(0,i*GetItemHeight(i),str);                      //绘制文本
            }
        }

(5)在CListBmp类中重写DrawItem虚函数,根据列表项状态绘制列表项,代码如下:

            void CListBmp::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
            {
            CDC dc;
            dc.Attach(lpDrawItemStruct->hDC);
            int nIndex=lpDrawItemStruct->itemID;                      //获取当前项目索引
            //判断项目状态
            int nState = lpDrawItemStruct->itemState;
            CRect rect,clrRC;
            GetClientRect(&rect);
            CBitmap bitmap;
            CDC memdc;
            memdc.CreateCompatibleDC(&dc);
            bitmap.LoadBitmap(IDB_BITMAP1);                          //加载位图资源
            memdc.SelectObject(&bitmap);
            GetItemRect(nIndex,clrRC);                               //获得列表项区域
            m_pFont=GetFont();                                       //获得字体
            dc.SelectObject(m_pFont);
            if(nState&ODS_SELECTED)                                         //处于选中状态
            {
                dc.SetTextColor(RGB(200,0,0));                              //设置选中状态文本颜色
                dc.FillSolidRect(&clrRC,RGB(0,0,200));                      //填充项目区域为高亮效果
            }
            else
            {
                int nCurSel=nIndex-GetTopIndex();                            //设置当前索引基于可见项的位置
                dc.BitBlt(0,nCurSel*clrRC.Height(),clrRC.Width(),clrRC.Height()
                    ,&memdc,0,nCurSel*clrRC.Height(),SRCCOPY);              //绘制列表项背景
                dc.SetTextColor(RGB(0,0,0));                                //设置文本颜色
            }
            if(nIndex != -1)
            {
                CString str;
                GetText(nIndex,str);                                        //获得控件文本
                dc.SetBkMode(TRANSPARENT);                                  //设置背景透明
                dc.TextOut(0,(nIndex-GetTopIndex())*clrRC.Height(),str);    //绘制列表项文本
            }
            m_pFont->DeleteObject();
            bitmap.DeleteObject();
            ReleaseDC(&memdc);
            dc.DeleteDC();
        }

(6)在CListBmp类中添加OnVScroll方法,在拖动滚动条时重绘控件,代码如下:

        void CListBmp::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
        {
            Invalidate();
            CListBox::OnVScroll(nSBCode, nPos, pScrollBar);
        }

举一反三

根据本实例,读者可以:

设置其他控件的字体颜色;

设置控件的背景颜色。