Re: Custom drawing CListCtrl problem (with picture!)
 
I'd like to add that if in the OnPaint method instead of only showing
visible items I draw every item (visible or not) by doing something
like
for(int i = 0; i < GetItemCount(); i++)
It works fine. There is no artifact at all, I've tried extending the
range that its drawing a bit doing something like this:
int iStart = GetTopIndex()-2;
    int iEnd = iStart + GetCountPerPage()+2;
    if(iStart < 0)
        iStart = 0;
    if(iEnd > GetItemCount())
        iEnd = GetItemCount();
    for(int i = iStart; i < iEnd; i++) {
With no success.
aelaguiz@gmail.com wrote:
I've got a CListCtrl that uses the custom data style to handle a
massive amount of data, and I'm having wierd artifacts during custom
drawing.
I've tried several methods of drawing. The first I tried was completely
overriding OnPaint:
int iStart = GetTopIndex();
    int iEnd = iStart + GetCountPerPage();
    cprintf("Drawing range %d to %d (%d)\n", iStart, iEnd, iEnd-iStart);
    for(int i = iStart; i < iEnd; i++) {
        bSelected = GetItemState(i, LVIS_SELECTED) & LVIS_SELECTED;
        if(bSelected) {
            GetItemRect(i, &rItem, NULL);
            rItem.right = rClient.right;
            dc.FillSolidRect(&rItem, RGB(243, 242, 240));
        }
        for(int j = 0; j < 1; j++) {
            // CHANGED 1.07 LVIR_BOUNDS to LVIR_LABEL
            if(GetSubItemRect(i, j, LVIR_LABEL, rItem)) {
                sText = GetItemText(i, j);
                if(m_bHyperlink[j]) {
                    dc.SelectObject(&m_cHyperFont);
                    dc.SetTextColor( RGB(0, 0, 255) );
                }
                else {
                    dc.SelectObject(&m_cFont);
                    dc.SetTextColor( RGB(85, 85, 85) );
                    if(bSelected) {
                        dc.SetTextColor(RGB(108, 132, 145));
                    }
                }
                rItem.left += 5;
                if(j ==0) {
                    cprintf("Drawing Item: %s %d %d %d %d height = %d width = %d\n",
sText, rItem.left,
                        rItem.top, rItem.right, rItem.bottom, rItem.Height(),
rItem.Width());
                }
                // CHANGED 1.07 to fix column text overflop problem
                DrawItemText(&dc, sText, rItem, rItem.Width(), LVCFMT_LEFT);
            }
        }
    }
The second I tried was using the NM_CUSTOMDRAW handlers:
NMLVCUSTOMDRAW *pNMCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    *pResult = 0;
    if(pNMCD->nmcd.dwDrawStage == CDDS_PREPAINT) {
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if(pNMCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {
        CRect rc;
        GetSubItemRect(pNMCD->nmcd.dwItemSpec, pNMCD->iSubItem, LVIR_LABEL,
rc);
        CDC dc;
        dc.Attach(pNMCD->nmcd.hdc);
        //CMemDC dc(&cdc, rc);
        CString sText;
        sText = GetItemText(pNMCD->nmcd.dwItemSpec, pNMCD->iSubItem);
        cprintf("Drawing item %s height = %d width = %d item = %d sub =
%d\n", sText,
            rc.Height(), rc.Width(), pNMCD->nmcd.dwItemSpec, pNMCD->iSubItem);
        dc.DrawText(sText, &rc, NULL);
        *pResult = CDRF_SKIPDEFAULT;
    }
Both ways I am getting strange artifacts when scrolling. The problem is
MUCH more pronounced when using the NM_CUSTOMDRAW method. When using
the OnPaint method it only appears when scrolling down - but not
scrolling up. It appears that something is erasing part of the control
once drawn. You can see what is happening at
http://www.fifthstreetdevelopment.com/mole/drawing_problem.jpg
The top part is what the list box looks like before I scroll, the
bottom part is what is happening on scroll.
Any tips would be appreciated! Thanks.