游侠无极限 发表于 2005-2-23 21:29:00

又是垃圾,CListCtrlEx Base CListCtrl

// ---------------------------------------------
// ListCtrlEx.h
// ---------------------------------------------
#pragma once

// CListCtrlEx
class CListCtrlEx : public CListCtrl
{
    DECLARE_DYNAMIC(CListCtrlEx)
public:
    CListCtrlEx();
    virtual ~CListCtrlEx();
protected:
    DECLARE_MESSAGE_MAP()
    CListCtrl* pThis;
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
private:
    struct ItemDataEx {
      LPARAM SrclParam;
      COLORREF clrItemTextColor;
      COLORREF clrItemBackColor;
    };
    COLORREF m_clrHighLight;
    COLORREF m_clrHighLightEdge;
public:
    // 新增方法
    COLORREF SetItemTextColor(int nItem,COLORREF clrText);
    COLORREF GetItemTextColor(int nItem) const;
    COLORREF SetItemBackColor(int nItem, COLORREF clrBack);
    COLORREF GetItemBackColor(int nItem) const;
    COLORREF SetHighLightColor(COLORREF clrHighLight);
    COLORREF SetHighLightEdgeColor(COLORREF clrHighLightEdge);
    COLORREF GetHighLightColor(void) const;
    COLORREF GetHighLightEdgeColor(void) const;
    int GetItemImage(int nItem);
    BOOL SwitchItem(int nItem1, int nItem2);
    BOOL MoveItemUp(int nItem);
    BOOL MoveItemDown(int nItem);
    // 重写原来的方法
    DWORD_PTR GetItemData (int nItem) const;
    BOOL SetItemData (int nItem, DWORD_PTR dwData);
    int InsertItem (const LVITEM* pItem);
    int InsertItem (int nItem, LPCTSTR lpszItem);
    int InsertItem (int nItem, LPCTSTR lpszItem, int nImage);
    int InsertItem (UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam);
    BOOL DeleteItem (int nItem);
    BOOL DeleteAllItems ();
    BOOL GetItem(LVITEM* pItem);
    afx_msg void OnDestroy();
    afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
};

游侠无极限 发表于 2005-2-23 21:30:00

<P>// ---------------------------------------------
// ListCtrlEx.cpp
// ---------------------------------------------
// ListCtrlEx.cpp : 实现文件
//</P><P>#include "stdafx.h"
#include "CreateNewClass.h"
#include "ListCtrlEx.h"
#include ".\listctrlex.h"</P><P>
// CListCtrlEx</P><P>IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl)
CListCtrlEx::CListCtrlEx()
{
    // 用于调用基本的方法
    pThis = (CListCtrl*)this;
    // 默认的选中框颜色
    m_clrHighLight = 0xF1DACC;
    m_clrHighLightEdge = 0xC56A31;
}</P><P>CListCtrlEx::~CListCtrlEx()
{</P><P>}</P><P>
BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
    ON_WM_DESTROY()
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
END_MESSAGE_MAP()</P><P>// CListCtrlEx 消息处理程序</P><P>
COLORREF CListCtrlEx::SetItemTextColor(int nItem,COLORREF clrText)
{
    COLORREF clr = GetItemTextColor(nItem);
    ItemDataEx *pData = (ItemDataEx*)pThis-&gt;GetItemData(nItem);
    pData-&gt;clrItemTextColor = clrText;
    return clr;
}</P><P>COLORREF CListCtrlEx::GetItemTextColor(int nItem) const
{
    ItemDataEx *pData = (ItemDataEx*)pThis-&gt;GetItemData(nItem);
    return pData-&gt;clrItemTextColor;
}</P><P>COLORREF CListCtrlEx::SetItemBackColor(int nItem, COLORREF clrBack)
{
    COLORREF clr = GetItemBackColor(nItem);
    ItemDataEx *pData = (ItemDataEx*)pThis-&gt;GetItemData(nItem);
    pData-&gt;clrItemBackColor = clrBack;
    return clr;
}</P><P>COLORREF CListCtrlEx::GetItemBackColor(int nItem) const
{
    ItemDataEx *pData = (ItemDataEx*)pThis-&gt;GetItemData(nItem);
    return pData-&gt;clrItemBackColor;
}
DWORD_PTR CListCtrlEx::GetItemData (int nItem) const
{
    if (nItem &gt;= GetItemCount())
    {
      return 0;
    }
    CListCtrl* pThis = (CListCtrl*)this;
    DWORD_PTR Data = pThis-&gt;GetItemData(nItem);
    return ((ItemDataEx*)Data)-&gt;SrclParam;
}
BOOL CListCtrlEx::SetItemData (int nItem, DWORD_PTR dwData)
{
    if (nItem &gt;= GetItemCount())
    {
      return 0;
    }
    CListCtrl* pThis = (CListCtrl*)this;
    DWORD_PTR Data = pThis-&gt;GetItemData(nItem);
    ASSERT(Data);
    ((ItemDataEx*)Data)-&gt;SrclParam = dwData;
    return 1;
}
int CListCtrlEx::InsertItem (const LVITEM* pItem)
{
    int nReturn = pThis-&gt;InsertItem(pItem);
    ItemDataEx *pData = new ItemDataEx;
    // 设置默认颜色
    pData-&gt;clrItemBackColor = 0xFFFFFF;//pThis-&gt;GetTextBkColor();
    pData-&gt;clrItemTextColor = 0x000000;//pThis-&gt;GetTextColor();
    pData-&gt;SrclParam = pItem-&gt;lParam;
    pThis-&gt;SetItemData(pItem-&gt;iItem,(DWORD_PTR)pData);
    return nReturn;
}
int CListCtrlEx::InsertItem (int nItem, LPCTSTR lpszItem)
{
    LVITEM Item;
    memset(&amp;Item,0,sizeof(LVITEM));
    Item.pszText = new TCHAR;
    strcpy(Item.pszText,lpszItem);
    Item.iItem = nItem;
    Item.lParam = 0;
    Item.mask = LVIF_TEXT |LVIF_PARAM;
    BOOL bReturn = InsertItem(&amp;Item);
    delete Item.pszText;
    return bReturn;
}
int CListCtrlEx::InsertItem (int nItem, LPCTSTR lpszItem, int nImage)
{
    LVITEM Item;
    memset(&amp;Item,0,sizeof(LVITEM));
    Item.pszText = new TCHAR;
    strcpy(Item.pszText,lpszItem);
    Item.iItem = nItem;
    Item.lParam = 0;
    Item.iImage = nImage;
    Item.mask = LVIF_TEXT |LVIF_PARAM|LVIF_IMAGE;
    BOOL bReturn = InsertItem(&amp;Item);
    delete Item.pszText;
    return bReturn;
}
int CListCtrlEx::InsertItem (UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam)
{
    LVITEM Item;
    memset(&amp;Item,0,sizeof(LVITEM));
    Item.pszText = new TCHAR;
    strcpy(Item.pszText,lpszItem);
    Item.state = nState;
    Item.stateMask = nStateMask;
    Item.iItem = nItem;
    Item.lParam = lParam;
    Item.iImage = nImage;
    Item.mask = nMask;
    BOOL bReturn = InsertItem(&amp;Item);
    delete Item.pszText;
    return bReturn;
}
BOOL CListCtrlEx::DeleteItem (int nItem)
{
    void* pDataEx = (void*)pThis-&gt;GetItemData(nItem);
    if(pDataEx != NULL)
    {
      delete pDataEx;
    }
    return pThis-&gt;DeleteItem(nItem);
}
BOOL CListCtrlEx::DeleteAllItems ()
{
    int nCount = GetItemCount();
    for (int i = 0;i&lt;nCount;i++)
    {
      if(!DeleteItem(0))
      {
            return 0;
      }
    }
    return 1;
}
BOOL CListCtrlEx::GetItem(LVITEM* pItem)
{
    BOOL bReturn = pThis-&gt;GetItem(pItem);
    if (pItem-&gt;lParam)
    {
      pItem-&gt;lParam = ((ItemDataEx*)pItem-&gt;lParam)-&gt;SrclParam;
    }</P><P>    return bReturn;
}
void CListCtrlEx::OnDestroy()
{
    // 关键是清除申请的内存空间
    DeleteAllItems();
    CListCtrl::OnDestroy();
}</P><P>BOOL CListCtrlEx::SwitchItem(int nItem1, int nItem2)
{
    if (nItem1 == nItem2 || nItem1 &gt;= GetItemCount() || nItem2 &gt;= GetItemCount() || nItem1 &lt; 0 || nItem2 &lt; 0)
    {
      return 0;
    }
    LVITEM ItemData1,ItemData2;
    int ItemLength1 = pThis-&gt;GetItemText(nItem1,0).GetLength();
    int ItemLength2 = pThis-&gt;GetItemText(nItem2,0).GetLength();
    ItemData1.pszText = new TCHAR;
    ItemData2.pszText = new TCHAR;
    ItemData1.cchTextMax = ItemLength1+1;
    ItemData2.cchTextMax = ItemLength2+1;
    ItemData1.iItem = nItem1;
    ItemData2.iItem = nItem2;
    ItemData1.iSubItem = ItemData2.iSubItem = 0;
    ItemData1.mask = ItemData2.mask = LVIF_TEXT |LVIF_PARAM|LVIF_IMAGE|LVIF_STATE;</P><P>    pThis-&gt;GetItem(&amp;ItemData1);
    pThis-&gt;GetItem(&amp;ItemData2);
    // 交换数据
    ItemData1.iItem = nItem2;
    ItemData2.iItem = nItem1;
    pThis-&gt;SetItem(&amp;ItemData1);
    pThis-&gt;SetItem(&amp;ItemData2);</P><P>    delete ItemData1.pszText;
    delete ItemData2.pszText;
    // 得到报表模式的列数
    int nColCount = pThis-&gt;GetHeaderCtrl()-&gt;GetItemCount();
    CString strBuffer;
    for (int iSubItem = 1;iSubItem &lt; nColCount;iSubItem++)
    {
      strBuffer = pThis-&gt;GetItemText(nItem1,iSubItem);
      pThis-&gt;SetItemText(nItem1,iSubItem,pThis-&gt;GetItemText(nItem2,iSubItem));
      pThis-&gt;SetItemText(nItem2,iSubItem,strBuffer);
    }
    // 把原来的选中状态也转移过去
    // 不知道为什么这个属性没有体现在LVITEM结构中……
    bool bItemSelected1 = GetItemState(nItem1,LVIS_SELECTED) == LVIS_SELECTED;
    bool bItemSelected2 = GetItemState(nItem2,LVIS_SELECTED) == LVIS_SELECTED;</P><P>    SetItemState(nItem1,bItemSelected2?LVIS_SELECTED:0,LVIS_SELECTED);
    SetItemState(nItem2,bItemSelected1?LVIS_SELECTED:0,LVIS_SELECTED);
    return 1;
}</P><P>BOOL CListCtrlEx::PreCreateWindow(CREATESTRUCT&amp; cs)
{
    // 本类报表模式专用
    cs.style |= LVS_REPORT ;
    // cs.dwExStyle |= LVS_EX_FULLROWSELECT;
    return CListCtrl::PreCreateWindow(cs);
}</P><P>
COLORREF CListCtrlEx::SetHighLightColor(COLORREF clrHighLight)
{
    COLORREF clr = GetHighLightColor();
    m_clrHighLight = clrHighLight;
    return clr;
}</P><P>COLORREF CListCtrlEx::SetHighLightEdgeColor(COLORREF clrHighLightEdge)
{
    COLORREF clr = GetHighLightEdgeColor();
    m_clrHighLightEdge = clrHighLightEdge;
    return clr;
}</P>

游侠无极限 发表于 2005-2-23 21:30:00

<P>COLORREF CListCtrlEx::GetHighLightColor(void) const
{
    return m_clrHighLight;
}</P><P>COLORREF CListCtrlEx::GetHighLightEdgeColor(void) const
{
    return m_clrHighLightEdge;
}</P><P>int CListCtrlEx::GetItemImage(int nItem)
{
    LVITEM ItemData;
    ItemData.iItem = nItem;
    ItemData.iSubItem = 0;
    ItemData.mask = LVIF_IMAGE;
    pThis-&gt;GetItem(&amp;ItemData);
    return ItemData.iImage;
}</P><P>BOOL CListCtrlEx::MoveItemUp(int nItem)
{
    if (nItem &lt; 1 || nItem &gt;= GetItemCount())
    {
      return 0;
    }
    return SwitchItem(nItem,nItem - 1);
}</P><P>BOOL CListCtrlEx::MoveItemDown(int nItem)
{
    if (nItem &lt; 0 || nItem &gt;= GetItemCount() - 1)
    {
      return 0;
    }
    return SwitchItem(nItem,nItem + 1);
}</P><P>void CListCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast&lt;NMLVCUSTOMDRAW*&gt;(pNMHDR);</P><P>    *pResult = CDRF_DODEFAULT;</P><P>    if (pLVCD-&gt;nmcd.dwDrawStage == CDDS_PREPAINT)
    {
      *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if (pLVCD-&gt;nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    {
      *pResult = CDRF_NOTIFYSUBITEMDRAW;
    }
    else if (pLVCD-&gt;nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
    {</P><P>      int nItem = static_cast&lt;int&gt; (pLVCD-&gt;nmcd.dwItemSpec);
      int nSubItem = pLVCD-&gt;iSubItem;
      if (nSubItem != 0)
      {
            // 全部绘制过程在nSubItem == 0 时完成
            // 分布完成会有小问题,我无法解决
            *pResult = CDRF_SKIPDEFAULT;
            return;
      }
      CDC *pDC = CDC::FromHandle(pLVCD-&gt;nmcd.hdc);
      int nColCount = pThis-&gt;GetHeaderCtrl()-&gt;GetItemCount();
      CRect rectSubItem;
      CString strItemText;
      pDC-&gt;SetTextColor(((ItemDataEx*)pThis-&gt;GetItemData(nItem))-&gt;clrItemTextColor);
      pDC-&gt;SetBkMode(TRANSPARENT);
      // 相当于橡皮
      CBrush brEraser(GetItemBackColor(nItem));</P><P>      // int nFirstWidth = GetColumnWidth(0);</P><P>
      for (int i = 0;i &lt; nColCount;i++)
      {
            strItemText = GetItemText(nItem,i);</P><P>            if (i == 0)
            {
                pThis-&gt;GetSubItemRect(nItem,i,LVIR_BOUNDS,rectSubItem);
                // 擦掉原来的图形
                pDC-&gt;FillRect(rectSubItem,&amp;brEraser);
                if (GetExtendedStyle() &amp; LVS_EX_CHECKBOXES)
                {
                  CRect rectCheckBox;
                  GetSubItemRect(nItem,0,LVIR_ICON,rectCheckBox);
                  CRect::SwapLeftRight(rectCheckBox);
                  rectCheckBox.left = rectCheckBox.right - rectCheckBox.Height();</P><P>                  rectCheckBox -= CRect(2,2,2,2);
                  pDC-&gt;Draw3dRect(rectCheckBox,0x81521D,0x81521D);
                  //rectCheckBox += CRect(3,3,3,3);
                  if (GetCheck(nItem))
                  {
                        // 绘制一个CHECKBOX
                        CPen penCheck(PS_SOLID, 1, 0x0021A221);
                        CPen *pOldpen = pDC-&gt;SelectObject(&amp;penCheck);
                        for (int j = 3; j &lt; 10; j++)
                        {
                            pDC-&gt;MoveTo(rectCheckBox.left + j, rectCheckBox.top + rectCheckBox.Height() /2 - 3 + ((j &lt; 6) ? j - 1 : (9 - j)));
                            pDC-&gt;LineTo(rectCheckBox.left + j, rectCheckBox.top + rectCheckBox.Height() /2 - 3 + ((j &lt; 6) ? j + 2 : (12 - j)));
                        }
                        
                        pDC-&gt;SelectObject(pOldpen);
                  }
                }
                // 根据需要画选中框
                if ( (GetFocus() == this || GetStyle() &amp; LVS_SHOWSELALWAYS)&amp;&amp;(GetItemState(nItem,LVIS_SELECTED) == LVIS_SELECTED))
                {
                  if (GetExtendedStyle() &amp; LVS_EX_CHECKBOXES)
                  {// 存在检查框风格的时候需要对左坐标进行修正
                        CRect rectLeft;
                        GetItemRect(nItem,rectLeft,LVIR_ICON);
                        rectSubItem.left = rectLeft.left;
                  }
                  if (!(GetExtendedStyle() &amp; LVS_EX_FULLROWSELECT))
                  {// 非全行选择时右坐标需要修正
                        CRect rectRight;
                        GetSubItemRect(nItem,nSubItem,LVIR_LABEL,rectRight);
                        rectSubItem.right = rectRight.right;
                  }
                  CBrush brHighLight;
                  CPen penHighLightEdge;
                  if (GetFocus() == this)
                  {
                        brHighLight.CreateSolidBrush(m_clrHighLight);
                        penHighLightEdge.CreatePen(PS_SOLID,1,m_clrHighLightEdge);
                  }
                  else
                  {
                        // 不是焦点时,颜色70%不透明度
                        COLORREF clrBack = GetItemBackColor(nItem);
                        WORD red =GetRValue(m_clrHighLight)*0.7 + GetRValue(clrBack)*0.3;
                        WORD green = GetGValue(m_clrHighLight)*0.7 + GetGValue(clrBack)*0.3;
                        WORD blue = GetBValue(m_clrHighLight)*0.7 + GetBValue(clrBack)*0.3;
                        brHighLight.CreateSolidBrush(RGB(red,green,blue));
                        red =GetRValue(m_clrHighLightEdge)*0.7 + GetRValue(clrBack)*0.3;
                        green = GetGValue(m_clrHighLightEdge)*0.7 + GetGValue(clrBack)*0.3;
                        blue = GetBValue(m_clrHighLightEdge)*0.7 + GetBValue(clrBack)*0.3;
                        penHighLightEdge.CreatePen(PS_SOLID,1,RGB(red,green,blue));
                  }
                  CBrush *pbrOld = pDC-&gt;SelectObject(&amp;brHighLight);
                  CPen *ppenHighLightEdge = pDC-&gt;SelectObject(&amp;penHighLightEdge);
                  pDC-&gt;Rectangle(rectSubItem);
                  pDC-&gt;SelectObject(ppenHighLightEdge);
                  pDC-&gt;SelectObject(pbrOld);
                }
            }
            pThis-&gt;GetSubItemRect(nItem,i,LVIR_LABEL,rectSubItem);
            UINT uFormat = DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS;
            HDITEM hdi;
            hdi.mask = HDI_FORMAT;
            pThis-&gt;GetHeaderCtrl()-&gt;GetItem(i,&amp;hdi);
            if (hdi.fmt &amp; LVCFMT_RIGHT)
            {
                uFormat |= DT_RIGHT;
            }
            else if (hdi.fmt &amp; LVCFMT_CENTER)
            {
                uFormat |= DT_CENTER;
            }
            pDC-&gt;DrawText(strItemText,rectSubItem,uFormat);</P><P>            CImageList *pImageList = pThis-&gt;GetImageList(LVSIL_SMALL);
            if (pImageList)
            {
                CRect rectIcon;
                GetItemRect(nItem,rectIcon,LVIR_ICON);
                pDC-&gt;DrawIcon(rectIcon.left,rectIcon.top,pImageList-&gt;ExtractIcon(GetItemImage(nItem)));
            }
      }
      *pResult = CDRF_SKIPDEFAULT;
    }</P><P>}</P>

Eagle 发表于 2005-2-24 08:41:00

太长了,不看。代码不是这么看的。用VC环境来看代码比较方便。
页: [1]
查看完整版本: 又是垃圾,CListCtrlEx Base CListCtrl