EDN Admin
Well-known member
I use custom draw in one column of a CListCtrl with LVS_REPORT style. To avoid drawing into the next column I use SelectCliRgn(). This worked fine until I also needed to use LVS_EX_DOUBLEBUFFER (because of SetWindowTheme()).
I am not able to make SelectClipRgn() work with LVS_EX_DOUBLEBUFFER. How can I come around this?
The code below works fine, but if you comment in LVS_EX_DOUBLEBUFFER without removing SelectClipRgn() it will not draw correctly:
<div style="background-color:white; color:black
<pre><span style="color:blue void CTest1Dlg:oDataExchange(CDataExchange* pDX)
{
CDialogEx:oDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_List);
}
BEGIN_MESSAGE_MAP(CTest1Dlg, CDialogEx)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, &CTest1Dlg::OnCustomdrawList1)
END_MESSAGE_MAP()
BOOL CTest1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_List.ModifyStyle( 0, LVS_REPORT );
m_List.SetExtendedStyle( LVS_EX_FULLROWSELECT <span style="color:green /*| LVS_EX_DOUBLEBUFFER*/ );
<span style="color:green //VERIFY:SetWindowTheme( m_List, L"explorer", 0)==S_OK);<br/>
m_List.InsertColumn(0, _T(<span style="color:#a31515 "A:Text"));
m_List.InsertColumn(1, _T(<span style="color:#a31515 "Braw"));
m_List.InsertColumn(2, _T(<span style="color:#a31515 "C:Text"));<br/>
<span style="color:blue for( <span style="color:blue int iRow=0; iRow<30; iRow++ ) {
<span style="color:blue int ixInsertedRow = m_List.InsertItem( iRow, _T(<span style="color:#a31515 "dummy") );
<span style="color:blue for( <span style="color:blue int iCol=0; iCol<3; iCol++ ) {
CString sCell; sCell.Format(_T(<span style="color:#a31515 "Row %d, Col %d"), iRow, iCol );
m_List.SetItem( ixInsertedRow, iCol, LVIF_TEXT, sCell, 0,0,0, 0 );
}
}
m_List.SetColumnWidth(0, LVSCW_AUTOSIZE);
m_List.SetColumnWidth(1, LVSCW_AUTOSIZE);
m_List.SetColumnWidth(2, LVSCW_AUTOSIZE);
<span style="color:blue return TRUE; <span style="color:green // return TRUE unless you set the focus to a control
}
<span style="color:blue void PaintCell( CDC *pDC, CRect rect )
{
CRgn rgnClip; VERIFY(rgnClip.CreateRectRgnIndirect(rect));
pDC->SelectClipRgn( &rgnClip ); <span style="color:green // Wrong clipping with LVS_EX_DOUBLEBUFFER :-(
<span style="color:green //CRect rect2 = rect; rect2.InflateRect(20,20,20,20);
<span style="color:green //pDC->FillSolidRect( &rect2, RGB(255,0,0) ); // Red should be clipped away
pDC->FillSolidRect( &rect, RGB(0,255,0) );
pDC->MoveTo( rect.BottomRight());
pDC->LineTo( rect.TopLeft() );
pDC->SelectClipRgn( NULL );
}
<span style="color:blue void CTest1Dlg::OnCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW *pLVCD = <span style="color:blue reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = CDRF_DODEFAULT;
<span style="color:blue switch( pLVCD->nmcd.dwDrawStage ) {
<span style="color:blue case CDDS_PREPAINT : *pResult = CDRF_NOTIFYITEMDRAW; <span style="color:blue break;
<span style="color:blue case CDDS_ITEMPREPAINT : *pResult = CDRF_NOTIFYSUBITEMDRAW; <span style="color:blue break;
<span style="color:blue case CDDS_ITEMPREPAINT | CDDS_SUBITEM :
<span style="color:blue if( pLVCD->iSubItem == 1 ) { <span style="color:green // Special drawing:
CListCtrl *pWndListCtrl = (CListCtrl *) CWnd::FromHandle( pLVCD->nmcd.hdr.hwndFrom );
CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
<span style="color:blue int iItem = (<span style="color:blue int)pLVCD->nmcd.dwItemSpec;
CRect rectCell;
pWndListCtrl->GetSubItemRect( iItem, pLVCD->iSubItem, LVIR_LABEL, rectCell);
PaintCell( pDC, rectCell );
*pResult = CDRF_SKIPDEFAULT; <span style="color:green // Weve painted everything.
}
}
}
[/code]
View the full article
I am not able to make SelectClipRgn() work with LVS_EX_DOUBLEBUFFER. How can I come around this?
The code below works fine, but if you comment in LVS_EX_DOUBLEBUFFER without removing SelectClipRgn() it will not draw correctly:
<div style="background-color:white; color:black
<pre><span style="color:blue void CTest1Dlg:oDataExchange(CDataExchange* pDX)
{
CDialogEx:oDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_List);
}
BEGIN_MESSAGE_MAP(CTest1Dlg, CDialogEx)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, &CTest1Dlg::OnCustomdrawList1)
END_MESSAGE_MAP()
BOOL CTest1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_List.ModifyStyle( 0, LVS_REPORT );
m_List.SetExtendedStyle( LVS_EX_FULLROWSELECT <span style="color:green /*| LVS_EX_DOUBLEBUFFER*/ );
<span style="color:green //VERIFY:SetWindowTheme( m_List, L"explorer", 0)==S_OK);<br/>
m_List.InsertColumn(0, _T(<span style="color:#a31515 "A:Text"));
m_List.InsertColumn(1, _T(<span style="color:#a31515 "Braw"));
m_List.InsertColumn(2, _T(<span style="color:#a31515 "C:Text"));<br/>
<span style="color:blue for( <span style="color:blue int iRow=0; iRow<30; iRow++ ) {
<span style="color:blue int ixInsertedRow = m_List.InsertItem( iRow, _T(<span style="color:#a31515 "dummy") );
<span style="color:blue for( <span style="color:blue int iCol=0; iCol<3; iCol++ ) {
CString sCell; sCell.Format(_T(<span style="color:#a31515 "Row %d, Col %d"), iRow, iCol );
m_List.SetItem( ixInsertedRow, iCol, LVIF_TEXT, sCell, 0,0,0, 0 );
}
}
m_List.SetColumnWidth(0, LVSCW_AUTOSIZE);
m_List.SetColumnWidth(1, LVSCW_AUTOSIZE);
m_List.SetColumnWidth(2, LVSCW_AUTOSIZE);
<span style="color:blue return TRUE; <span style="color:green // return TRUE unless you set the focus to a control
}
<span style="color:blue void PaintCell( CDC *pDC, CRect rect )
{
CRgn rgnClip; VERIFY(rgnClip.CreateRectRgnIndirect(rect));
pDC->SelectClipRgn( &rgnClip ); <span style="color:green // Wrong clipping with LVS_EX_DOUBLEBUFFER :-(
<span style="color:green //CRect rect2 = rect; rect2.InflateRect(20,20,20,20);
<span style="color:green //pDC->FillSolidRect( &rect2, RGB(255,0,0) ); // Red should be clipped away
pDC->FillSolidRect( &rect, RGB(0,255,0) );
pDC->MoveTo( rect.BottomRight());
pDC->LineTo( rect.TopLeft() );
pDC->SelectClipRgn( NULL );
}
<span style="color:blue void CTest1Dlg::OnCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW *pLVCD = <span style="color:blue reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = CDRF_DODEFAULT;
<span style="color:blue switch( pLVCD->nmcd.dwDrawStage ) {
<span style="color:blue case CDDS_PREPAINT : *pResult = CDRF_NOTIFYITEMDRAW; <span style="color:blue break;
<span style="color:blue case CDDS_ITEMPREPAINT : *pResult = CDRF_NOTIFYSUBITEMDRAW; <span style="color:blue break;
<span style="color:blue case CDDS_ITEMPREPAINT | CDDS_SUBITEM :
<span style="color:blue if( pLVCD->iSubItem == 1 ) { <span style="color:green // Special drawing:
CListCtrl *pWndListCtrl = (CListCtrl *) CWnd::FromHandle( pLVCD->nmcd.hdr.hwndFrom );
CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
<span style="color:blue int iItem = (<span style="color:blue int)pLVCD->nmcd.dwItemSpec;
CRect rectCell;
pWndListCtrl->GetSubItemRect( iItem, pLVCD->iSubItem, LVIR_LABEL, rectCell);
PaintCell( pDC, rectCell );
*pResult = CDRF_SKIPDEFAULT; <span style="color:green // Weve painted everything.
}
}
}
[/code]
View the full article