Re: Using CMemDC in a custom control
hamishd wrote:
Hi. I have have created a listcrtl (derived from CListCtrl) which can
add a progress-bar a cell.
However, the progress control flickers a lot when drawing. I wish to
use CMemDC to reduce flicking (works well on my dialogs etc) but I
can't get it to work right. What do I need to do?
void CMyListCtrl::DrawProgress(int nItem, CDC *pDC, CRect& rect)
{
// fill interior with light gray
pDC->FillSolidRect(rect, RGB(242,242,242));
// draw border
pDC->Draw3dRect(&rect, RGB(0,0,0), RGB(0,0,0));
int nProgressPercent = Group[nItem].PC;
if (nProgressPercent>0){
// draw progress bar
CRect LeftRect;
LeftRect = rect;
LeftRect.left += 1;
LeftRect.top += 1;
LeftRect.bottom -= 1;
int w = (LeftRect.Width() * nProgressPercent) / 100;
LeftRect.right = LeftRect.left + w - 1;
pDC->FillSolidRect(LeftRect, RGB(255,0,0));
}
}
DrawProgress() is called from OnCustomdraw()
void CSizeRatioListCtrl::OnCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
MLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
*pResult = CDRF_DODEFAULT;
int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
CRect rect;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
DrawProgress(nItem, nSubItem, pDC, rect);
*pResult = CDRF_SKIPDEFAULT;
}
I think the problem may be because you're passing the "real" dc to your
drawing function. With a CMemDC (Keith Rules' class, right?) you create
a scope local memdc and pass this to your drawing functions. As the
memdc goes out of scope, it copies the bitmap to the real dc.
pseudocode like this:
OnPaint/Draw
{
CDC* pDC = The DC passed into the drawing code
{
CMemDC mDC(pDC);
DrawThis(mDC);
DrawThat(mDC);
DrawTheOther(mDC);
} // mDC goes out of scope here
}
A good way to see what's going on is to step through the drawign code on
one monitor while the app runs on another monitor, ie not overlapped.
Then you can see the individual elements getting drawn (if you're NOT
using the memdc) otherwise you just see the whole thing update at the end.