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); }
举一反三
根据本实例,读者可以:
设置其他控件的字体颜色;
设置控件的背景颜色。