又是垃圾,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);
}; <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->GetItemData(nItem);
pData->clrItemTextColor = clrText;
return clr;
}</P><P>COLORREF CListCtrlEx::GetItemTextColor(int nItem) const
{
ItemDataEx *pData = (ItemDataEx*)pThis->GetItemData(nItem);
return pData->clrItemTextColor;
}</P><P>COLORREF CListCtrlEx::SetItemBackColor(int nItem, COLORREF clrBack)
{
COLORREF clr = GetItemBackColor(nItem);
ItemDataEx *pData = (ItemDataEx*)pThis->GetItemData(nItem);
pData->clrItemBackColor = clrBack;
return clr;
}</P><P>COLORREF CListCtrlEx::GetItemBackColor(int nItem) const
{
ItemDataEx *pData = (ItemDataEx*)pThis->GetItemData(nItem);
return pData->clrItemBackColor;
}
DWORD_PTR CListCtrlEx::GetItemData (int nItem) const
{
if (nItem >= GetItemCount())
{
return 0;
}
CListCtrl* pThis = (CListCtrl*)this;
DWORD_PTR Data = pThis->GetItemData(nItem);
return ((ItemDataEx*)Data)->SrclParam;
}
BOOL CListCtrlEx::SetItemData (int nItem, DWORD_PTR dwData)
{
if (nItem >= GetItemCount())
{
return 0;
}
CListCtrl* pThis = (CListCtrl*)this;
DWORD_PTR Data = pThis->GetItemData(nItem);
ASSERT(Data);
((ItemDataEx*)Data)->SrclParam = dwData;
return 1;
}
int CListCtrlEx::InsertItem (const LVITEM* pItem)
{
int nReturn = pThis->InsertItem(pItem);
ItemDataEx *pData = new ItemDataEx;
// 设置默认颜色
pData->clrItemBackColor = 0xFFFFFF;//pThis->GetTextBkColor();
pData->clrItemTextColor = 0x000000;//pThis->GetTextColor();
pData->SrclParam = pItem->lParam;
pThis->SetItemData(pItem->iItem,(DWORD_PTR)pData);
return nReturn;
}
int CListCtrlEx::InsertItem (int nItem, LPCTSTR lpszItem)
{
LVITEM Item;
memset(&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(&Item);
delete Item.pszText;
return bReturn;
}
int CListCtrlEx::InsertItem (int nItem, LPCTSTR lpszItem, int nImage)
{
LVITEM Item;
memset(&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(&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(&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(&Item);
delete Item.pszText;
return bReturn;
}
BOOL CListCtrlEx::DeleteItem (int nItem)
{
void* pDataEx = (void*)pThis->GetItemData(nItem);
if(pDataEx != NULL)
{
delete pDataEx;
}
return pThis->DeleteItem(nItem);
}
BOOL CListCtrlEx::DeleteAllItems ()
{
int nCount = GetItemCount();
for (int i = 0;i<nCount;i++)
{
if(!DeleteItem(0))
{
return 0;
}
}
return 1;
}
BOOL CListCtrlEx::GetItem(LVITEM* pItem)
{
BOOL bReturn = pThis->GetItem(pItem);
if (pItem->lParam)
{
pItem->lParam = ((ItemDataEx*)pItem->lParam)->SrclParam;
}</P><P> return bReturn;
}
void CListCtrlEx::OnDestroy()
{
// 关键是清除申请的内存空间
DeleteAllItems();
CListCtrl::OnDestroy();
}</P><P>BOOL CListCtrlEx::SwitchItem(int nItem1, int nItem2)
{
if (nItem1 == nItem2 || nItem1 >= GetItemCount() || nItem2 >= GetItemCount() || nItem1 < 0 || nItem2 < 0)
{
return 0;
}
LVITEM ItemData1,ItemData2;
int ItemLength1 = pThis->GetItemText(nItem1,0).GetLength();
int ItemLength2 = pThis->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->GetItem(&ItemData1);
pThis->GetItem(&ItemData2);
// 交换数据
ItemData1.iItem = nItem2;
ItemData2.iItem = nItem1;
pThis->SetItem(&ItemData1);
pThis->SetItem(&ItemData2);</P><P> delete ItemData1.pszText;
delete ItemData2.pszText;
// 得到报表模式的列数
int nColCount = pThis->GetHeaderCtrl()->GetItemCount();
CString strBuffer;
for (int iSubItem = 1;iSubItem < nColCount;iSubItem++)
{
strBuffer = pThis->GetItemText(nItem1,iSubItem);
pThis->SetItemText(nItem1,iSubItem,pThis->GetItemText(nItem2,iSubItem));
pThis->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& 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> <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->GetItem(&ItemData);
return ItemData.iImage;
}</P><P>BOOL CListCtrlEx::MoveItemUp(int nItem)
{
if (nItem < 1 || nItem >= GetItemCount())
{
return 0;
}
return SwitchItem(nItem,nItem - 1);
}</P><P>BOOL CListCtrlEx::MoveItemDown(int nItem)
{
if (nItem < 0 || nItem >= GetItemCount() - 1)
{
return 0;
}
return SwitchItem(nItem,nItem + 1);
}</P><P>void CListCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);</P><P> *pResult = CDRF_DODEFAULT;</P><P> if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
{</P><P> int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
if (nSubItem != 0)
{
// 全部绘制过程在nSubItem == 0 时完成
// 分布完成会有小问题,我无法解决
*pResult = CDRF_SKIPDEFAULT;
return;
}
CDC *pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
int nColCount = pThis->GetHeaderCtrl()->GetItemCount();
CRect rectSubItem;
CString strItemText;
pDC->SetTextColor(((ItemDataEx*)pThis->GetItemData(nItem))->clrItemTextColor);
pDC->SetBkMode(TRANSPARENT);
// 相当于橡皮
CBrush brEraser(GetItemBackColor(nItem));</P><P> // int nFirstWidth = GetColumnWidth(0);</P><P>
for (int i = 0;i < nColCount;i++)
{
strItemText = GetItemText(nItem,i);</P><P> if (i == 0)
{
pThis->GetSubItemRect(nItem,i,LVIR_BOUNDS,rectSubItem);
// 擦掉原来的图形
pDC->FillRect(rectSubItem,&brEraser);
if (GetExtendedStyle() & 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->Draw3dRect(rectCheckBox,0x81521D,0x81521D);
//rectCheckBox += CRect(3,3,3,3);
if (GetCheck(nItem))
{
// 绘制一个CHECKBOX
CPen penCheck(PS_SOLID, 1, 0x0021A221);
CPen *pOldpen = pDC->SelectObject(&penCheck);
for (int j = 3; j < 10; j++)
{
pDC->MoveTo(rectCheckBox.left + j, rectCheckBox.top + rectCheckBox.Height() /2 - 3 + ((j < 6) ? j - 1 : (9 - j)));
pDC->LineTo(rectCheckBox.left + j, rectCheckBox.top + rectCheckBox.Height() /2 - 3 + ((j < 6) ? j + 2 : (12 - j)));
}
pDC->SelectObject(pOldpen);
}
}
// 根据需要画选中框
if ( (GetFocus() == this || GetStyle() & LVS_SHOWSELALWAYS)&&(GetItemState(nItem,LVIS_SELECTED) == LVIS_SELECTED))
{
if (GetExtendedStyle() & LVS_EX_CHECKBOXES)
{// 存在检查框风格的时候需要对左坐标进行修正
CRect rectLeft;
GetItemRect(nItem,rectLeft,LVIR_ICON);
rectSubItem.left = rectLeft.left;
}
if (!(GetExtendedStyle() & 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->SelectObject(&brHighLight);
CPen *ppenHighLightEdge = pDC->SelectObject(&penHighLightEdge);
pDC->Rectangle(rectSubItem);
pDC->SelectObject(ppenHighLightEdge);
pDC->SelectObject(pbrOld);
}
}
pThis->GetSubItemRect(nItem,i,LVIR_LABEL,rectSubItem);
UINT uFormat = DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS;
HDITEM hdi;
hdi.mask = HDI_FORMAT;
pThis->GetHeaderCtrl()->GetItem(i,&hdi);
if (hdi.fmt & LVCFMT_RIGHT)
{
uFormat |= DT_RIGHT;
}
else if (hdi.fmt & LVCFMT_CENTER)
{
uFormat |= DT_CENTER;
}
pDC->DrawText(strItemText,rectSubItem,uFormat);</P><P> CImageList *pImageList = pThis->GetImageList(LVSIL_SMALL);
if (pImageList)
{
CRect rectIcon;
GetItemRect(nItem,rectIcon,LVIR_ICON);
pDC->DrawIcon(rectIcon.left,rectIcon.top,pImageList->ExtractIcon(GetItemImage(nItem)));
}
}
*pResult = CDRF_SKIPDEFAULT;
}</P><P>}</P> 太长了,不看。代码不是这么看的。用VC环境来看代码比较方便。
页:
[1]