如何实现由列表控件控制的属性表

http://tech.ddvip.com   2008年01月14日    社区交流

内容摘要:很多MFC的程序都用到了属性表和属性页来实现选项设置的界面,但是MFC本身提供的属性表页功能有限,界面也很原始,一些新软件都实现了自己定义的更为美观的属性页。MFC原始的属性页是通过CTabCtrl进行切换控制的,本文给出了一种现在较为常见的用CListCtrl进行页面切换的属性页的方法,并且对对列表控件进行了重绘。

  SetSepratorColor,SetCaptionColor与SetSelectedColor都接受一个类型为COLORREF的参数,分别用以设置列表分隔线,属性页标题以及列表选择项背景的颜色。

  SetListFont设置列表的字体。

  读者也可以根据自己的需要对其进行扩充。

  二、实现逻辑

  MFC原来的属性页是由TabCtrl控制的,而且属性页的大小已经与属性表按比例设置好,因此,要实现如图一所示的属性页,我们有如下几步工作需要做:

  1. 对属性页原来的TabCtrl进行隐藏。

  2. 调整属性表的大小,将属性页移至属性表右侧,以容纳列表控件。

  3. 获得TabCtrl的矩形,根据该矩形画属性页标题。

  4. 初始化列表控件内容,调整列表项高度。

  5. 响应列表的NM_CLICK事件,根据得到的点击项ID进行属性页的切换。

  其中调整尺寸的工作必须在OnInitDialog函数中进行。

BOOL CMyPropertySheet::OnInitDialog()
{
  
  BOOL bResult = CPropertySheet::OnInitDialog();  
  //计算属性页的矩形,扩大属性表并将属性页其移至右侧
  CRect rect, rectPage, rectTab;
  GetPage(0)->GetWindowRect(&rectPage);
  
  GetWindowRect(&rect);
  rect.right += 150;
  
  int nWidth = rectPage.Width();
  rectPage.right = rect.right - 20;
  rectPage.left = rect.right - nWidth;
  ScreenToClient(&rectPage);
  m_rectPage = rectPage;
  MoveWindow(&rect);
  GetPage(0)->MoveWindow(&rectPage);
  
  //隐藏属性页原来的TabControl
  CTabCtrl *pTab = GetTabControl() ;
  pTab->GetWindowRect(&rectTab);
  ScreenToClient(&rectTab);
  if(!pTab->ShowWindow(SW_HIDE))
    return FALSE;  
 
  //创建列表控件并用一个CImageList对象与之关联
  if(!m_wndList.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_NOCOLUMNHEADER ,
              CRect(10 ,rectTab.top,150,rectPage.bottom ),this,0xFFFF))
    return FALSE;
  m_wndList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
  m_wndList.SetImageList(&m_imgList, LVSIL_SMALL);
  
  InitList();
  //设置行高度
  CFont font;
  font.CreatePointFont(240,_T("宋体"));
  m_wndList.SetFont(&font);
  
  CString strCaption;
  GetPage(0)->GetWindowText(strCaption);  
  _tcscpy(m_szCaption, strCaption.GetBuffer(strCaption.GetLength()));  
  return bResult;
}
属性页的切换:void CMyPropertySheet::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
  LPNMITEMACTIVATE lpItem = reinterpret_cast(pNMHDR);
  m_nSelectedItem = lpItem->iItem ;
  if (lpItem->iItem >= 0 && lpItem->iItem < m_wndList.GetItemCount())
  {
    m_nSelectedItem = lpItem->iItem;
    CString strCaption = m_wndList.GetItemText(lpItem->iItem,0);
   _tcscpy(m_szCaption, strCaption);  
  SetActivePage(m_nSelectedItem);
  
  Invalidate();  
  
  GetPage(m_nSelectedItem)->MoveWindow(&m_rectPage);
  m_wndList.SetFocus();
  }
  
}
三、总结

  关于列表控件自绘的问题在这里不做详细讨论,可以参考源代码里面OnNMCustomDraw的部分以及MSDN上的相关资料。对属性页的修改还有很多种方法和很多种方式,比如还可以用树型控件进行控制,这里提供的方法也可以做一般意义上的推广 ,并不难实现其它方式的控制。程序在Visual C++ 2005 下编译通过。

来源:vckbase    作者:赵科进    责编:豆豆技术应用

正在加载评论...