Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

247 lines
6.0 KiB
C++

#include "StdAfx.h"
#include "CXLSListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CXLSListCtrl::CXLSListCtrl()
{
m_nCurItem = -1;
m_nCurSubItem = -1;
m_nPadding = 5;
m_crHightLightOut = RGB(0, 0, 0);
m_crHighLight = RGB(0,255,255);
m_crGreen = RGB(0, 255, 0);
m_crRed = RGB(255, 0, 0);
m_crWindow = ::GetSysColor(COLOR_WINDOW);
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
}
CXLSListCtrl::~CXLSListCtrl()
{
}
BEGIN_MESSAGE_MAP(CXLSListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CXLSListCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CXLSListCtrl::OnNMCustomdraw)
ON_NOTIFY_REFLECT_EX(NM_CLICK, &CXLSListCtrl::OnNMClick)
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CXLSListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW *pLVCD = reinterpret_cast<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 (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->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 (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
{
// This is the prepaint stage for a subitem. Here's where we set the
// item's text and background colors. Our return value will tell
// Windows to draw the subitem itself, but it will use the new colors
// we set here.
int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
EquHolder *pHolder = (EquHolder *)GetItemData(nItem);
COLORREF crText = m_crWindowText;
COLORREF crBkgnd = m_crWindow;
if (pHolder)
{
crBkgnd = m_crGreen;//绿色
}
// store the colors back in the NMLVCUSTOMDRAW struct
pLVCD->clrText = crText;
pLVCD->clrTextBk = crBkgnd;
CDC *pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
CRect rect;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pHolder);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
}
void CXLSListCtrl::DrawText(int nItem,int nSubItem,CDC *pDC,
COLORREF crText,COLORREF crBkgnd,
CRect &rect,
EquHolder *pHolder)
{
ASSERT(pDC);
if (rect.IsRectEmpty())
{
return;
}
if (pHolder != NULL)
{
if (pHolder->nFrCol == nSubItem)
{
if (_tcslen(pHolder->szFrEqu) > 0)
crBkgnd = m_crGreen;//绿色
else
crBkgnd = m_crRed;
pDC->FillSolidRect(&rect, crBkgnd);
}
else if (pHolder->nToCol == nSubItem)
{
if (_tcslen(pHolder->szToEqu) > 0)
crBkgnd = m_crGreen;//绿色
else
crBkgnd = m_crRed;
pDC->FillSolidRect(&rect, crBkgnd);
}
else
{
crBkgnd = m_crWindow;
}
}
//绘制外框
if (m_nCurItem == nItem && m_nCurSubItem == nSubItem)
{
//黑色-靛蓝-黑色 三个矩形框
CRect rcHit = rect;
pDC->Draw3dRect(rcHit, m_crHightLightOut, m_crHightLightOut);
rcHit.DeflateRect(1,1);
pDC->Draw3dRect(rcHit, m_crHighLight, m_crHighLight);
rcHit.DeflateRect(1, 1);
pDC->Draw3dRect(rcHit, m_crHightLightOut, m_crHightLightOut);
}
CString str;
str = GetItemText(nItem, nSubItem);
if (!str.IsEmpty())
{
UINT nFormat = DT_VCENTER | DT_SINGLELINE | DT_LEFT;
CFont *pOldFont = NULL;
CFont boldfont;
// check if bold specified for subitem
if (pHolder != NULL)
{
CFont *font = pDC->GetCurrentFont();
if (font)
{
LOGFONT lf;
font->GetLogFont(&lf);
lf.lfWeight = FW_BOLD;
boldfont.CreateFontIndirect(&lf);
pOldFont = pDC->SelectObject(&boldfont);
}
}
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(crText);
pDC->SetBkColor(crBkgnd);
rect.DeflateRect(m_nPadding, 0);
pDC->DrawText(str, &rect, nFormat);
rect.InflateRect(m_nPadding, 0);
if (pOldFont)
pDC->SelectObject(pOldFont);
}
}
BOOL CXLSListCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
CRect rcLast,rcThis;
GetItemRect(m_nCurItem, rcLast, LVIR_BOUNDS);
InvalidateRect(rcLast);
m_nCurItem = pNMItemActivate->iItem;
m_nCurSubItem = pNMItemActivate->iSubItem;
GetItemRect(m_nCurItem, rcThis, LVIR_BOUNDS);
InvalidateRect(rcThis);
RedrawWindow(rcLast);
RedrawWindow(rcThis);
*pResult = 0;
return FALSE; // return FALSE to send message to parent also -
// NOTE: MSDN documentation is incorrect
}
BOOL CXLSListCtrl::OnEraseBkgnd(CDC *pDC)
{
return CListCtrl::OnEraseBkgnd(pDC);
/*CRect rectClip, rectTop, rectBottom, rectRight;
int nItemCount = GetItemCount();
if (!nItemCount) // Empty XListCtrl, nothing to do, CListCtrl will
return CListCtrl::OnEraseBkgnd(pDC); // erase the Background
if (pDC->GetClipBox(&rectClip) == ERROR)
{
ASSERT(false);
return CListCtrl::OnEraseBkgnd(pDC);
}
int nFirstRow = GetTopIndex();
int nLastRow = nFirstRow + GetCountPerPage();
nLastRow = min(nLastRow, nItemCount - 1); // Last Item displayed in Ctrl
CListCtrl::GetSubItemRect(nFirstRow, 0, LVIR_BOUNDS, rectTop);
CListCtrl::GetSubItemRect(nLastRow, 0, LVIR_BOUNDS, rectBottom);
CRect rectEraseTop = rectClip;
rectEraseTop.bottom = rectTop.top;
pDC->FillSolidRect(rectEraseTop, m_crWindow);
CRect rectEraseBottom = rectClip;
rectEraseBottom.top = rectBottom.bottom;
pDC->FillSolidRect(rectEraseBottom, m_crWindow);
CRect rectEraseRight = rectClip;
rectEraseRight.top = rectTop.top;
rectEraseRight.bottom = rectBottom.bottom;
rectEraseRight.left = rectTop.right;
pDC->FillSolidRect(rectEraseRight, m_crWindow);
return TRUE;*/
}
void CXLSListCtrl::OnDestroy()
{
int n = GetItemCount();
for (int i = 0; i < n; i++)
{
EquHolder *pHolder = (EquHolder *)GetItemData(i);
if (pHolder != NULL)
delete pHolder;
CListCtrl::SetItemData(i, 0);
}
CListCtrl::OnDestroy();
}