WEB开发网
开发学院软件开发VC 可编辑子项的CListCtrl类 阅读

可编辑子项的CListCtrl类

 2010-07-06 20:43:53 来源:WEB开发网   
核心提示:一、说明大家都知道在MFC中通过给CListCtrl设置LVS_EDITLABELS属性,并且在程序中响应控件的LVN_ENDLABELEDIT消息可以修改列表控件每一行的第一项,可编辑子项的CListCtrl类,也就是主项(Item),代码如下:void CEditListCtrlSampleDlg::OnEndla

一、说明

大家都知道在MFC中通过给CListCtrl设置LVS_EDITLABELS属性,并且在程序中响应控件的LVN_ENDLABELEDIT消息可以修改列表控件每一行的第一项,也就是主项(Item)。代码如下:

void CEditListCtrlSampleDlg::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult)
{
  LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  // TODO: Add your control notification handler code here

  *pResult = TRUE;  //TRUE值表示可以修改主项,FALSE值表示不修改主项
}

但是让人郁闷的是,微软留了一手,CListCtrl不支持直接修改子项(SubItem)。无奈之下只好自力更生,对CListCtrl进行扩展。>_<!!!!

二、原理

通过在浩如烟海的互联网上查找资料(当然包括了大名鼎鼎的VCKBASE),发现现有的实现大都是对子项鼠标单击一次就可以编辑。但本人对CListCtrl的单击一次高亮文本,再单击一次才开始编辑的操作模式感觉比较喜欢,所以就有了这篇文章的诞生。

要想实现高亮文本也就是对文本进行着色处理,这可以通过对NM_CUSTOMDRAW消息进行处理实现,但是类向导中没有这个消息映射只能进行手工添加。

要想编辑文本则可以通过EditLabel(int nItem)成员函数以及对LVN_BEGINLABELEDIT和LVN_ENDLABELEDIT的消息处理实现。

三、实现

本文最终实现的CEditListCtrl扩展类在尽量符合CListCtrl操作步骤的情况下实现对主项及子项的可编辑。

成员变量说明:

int m_iItem; //主项标识符

int m_iSubItem; //子项标识符

BOOL m_bFocus; //是否绘制项文本焦点框

BOOL m_bHighLight; //是否高亮项文本

CItemEdit m_edtItemEdit; //用于子类化EditLabel函数返回的CEdit*指针

列表控件中所有项文本的绘制以及特效(焦点框、高亮)都在NM_CUSTOMDRAW消息处理中实现:

void CEditListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
  NMLVCUSTOMDRAW* pNMLVCustomDraw = (NMLVCUSTOMDRAW*)pNMHDR;

  // Take the default processing unless we set this to something else below.
  *pResult = CDRF_DODEFAULT;

  // First thing - check the draw stage. If it's the control's prepaint
  // stage, then tell Windows we want messages for every item.

  if (pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
  {
    *pResult = CDRF_NOTIFYITEMDRAW;
  }
  else if (pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
  {
    // This is the notification message for an item. We'll request
    // notifications before each subitem's prepaint stage.
    *pResult = CDRF_NOTIFYSUBITEMDRAW;
  }
  else if (pNMLVCustomDraw->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
  {
    //当前要绘制的主项标识符和子项标识符
    int iItem = (int)pNMLVCustomDraw->nmcd.dwItemSpec;
    int iSubItem = pNMLVCustomDraw->iSubItem;

    CDC* pDC = CDC::FromHandle(pNMLVCustomDraw->nmcd.hdc);

    CString strItemText = GetItemText(iItem, iSubItem);
    CRect rcItem, rcText;
    GetSubItemRect(iItem, iSubItem, LVIR_LABEL, rcItem);
    rcText = rcItem;

    CSize size = pDC->GetTextExtent(strItemText);
    if(strItemText == _T(""))
    {
      size.cx = 41;
    }

    //设置文本高亮矩形
    rcText.left += 4;
    rcText.right = rcText.left + size.cx + 6;
      if(rcText.right > rcItem.right)
  {
    rcText.right = rcItem.right;
  }

  COLORREF crOldTextColor = pDC->GetTextColor();
  //绘制项焦点/高亮效果
  if(m_bFocus)
  {
    if((m_iItem == iItem) && (m_iSubItem == iSubItem))
    {
      if(m_bHighLight)
      {
        pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
        pDC->FillSolidRect(&rcText, ::GetSysColor(COLOR_HIGHLIGHT));
      }
      pDC->DrawFocusRect(&rcText);
    }
  }

  //绘制项文本
  rcItem.left += 6;
  pDC->DrawText(strItemText, &rcItem, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP);
  pDC->SetTextColor(crOldTextColor);
  *pResult = CDRF_SKIPDEFAULT;// We've painted everything.
  }
}

1 2  下一页

Tags:编辑 子项 CListCtrl

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接