读书人

在孤单的和弦网友的可编辑listctrl源码

发布时间: 2013-12-16 23:49:16 作者: rapoo

在孤独的和弦网友的可编辑listctrl源码发现CPaintDc和CClientDC的区别

void CMyListCtrl::OnPaint()
{
//CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CListCtrl::OnPaint()
if ( m_iSubItem >= 0 && m_edtItemEdit.m_hWnd )
{
CRect rect;
CRect rcEdit;
m_edtItemEdit.GetWindowRect(rcEdit);
ScreenToClient(rcEdit);

GetSubItemRect(m_iItem, m_iSubItem, LVIR_LABEL, rect);

// 当文本编辑框缩小时,擦除露出的项文本高亮部分
if ( rcEdit.right < rect.right )
{
rect.left = rcEdit.right;
CClientDC dc(this);
dc.FillRect(rect, &CBrush(::GetSysColor(COLOR_WINDOW)));
ValidateRect(rect);
}
}

CListCtrl::OnPaint();
}


下载连接:

http://download.csdn.net/download/ftd2013/5991065


原理:作者在lvn_beginlableedit 里子类化一个它自己实现的edit类和lvn_endlableedit里反子类化,通过这个机制来实现可编辑功能。

我的问题是 为什么作者可以在 onpaint里使用CClientDC,而不是CPaintDC ?

问题2:

为什么作者不把onpaint里的代码放到 nm_customdraw里 ?

以下是 nm_customdraw里的代码:
void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW* pNMLVCustomDraw = (NMLVCUSTOMDRAW*)pNMHDR;
// TODO: 在此添加控件通知处理程序代码
*pResult = CDRF_DODEFAULT;

if ( pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT )
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if ( pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT )
{
*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 == "" )
{
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;
}
}



[解决办法]
第一点:如果不考虑闪烁问题,先执行CListCtrl::OnPaint再fillrect(color_window)应该也可以的,只要搞对要填充的区域应该没问题

第二点:因为ValidateRect了,所以不怕后执行的CListCtrl::OnPaint覆盖,也就是说CListCtrl::OnPaint不会在有效区域绘制出东西来。

读书人网 >VC/MFC

热点推荐