简体   繁体   中英

MFC Custom Control draw

I have some question.
I made custom controller inner radio button.
but that is not clear draw every time ( blink or overlapped ).

so, question is this
how are you draw customctrl inner controller?
draw use CDC? or inner controller redraw()? ( i'm used redraw() )

second is listctrl frequently covered inner radio button.
how can i draw inner radio button above listctrl every time.

here is my code :
vfcxxx : xxx same

void CCheckListCtrl::DrawItem(_In_ LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    int cnt = lpDrawItemStruct->itemID;
    static int rownumber = 0;

    VfcLong tmpnum = -1;
    LONG prev_left = lpDrawItemStruct->rcItem.left;

    LV_COLUMN column_data;
    memset(&column_data, 0, sizeof(LV_COLUMN));
    column_data.mask = LVCF_WIDTH | LVCF_FMT;

    for(int column_index = 0; GetColumn(column_index, &column_data); column_index++)
    {
        RECT tempRC;
        {
            tempRC.top  = lpDrawItemStruct->rcItem.top;
            tempRC.bottom = lpDrawItemStruct->rcItem.bottom;
            tempRC.left  = (prev_left);
            tempRC.right = (prev_left += column_data.cx);
        }

        if (column_index > 1) break;

        LV_ITEM tempLI;
        wchar_t buffer[256];
        {
            tempLI.mask   = LVIF_TEXT | LVIF_PARAM;
            tempLI.iItem  = lpDrawItemStruct->itemID;
            tempLI.iSubItem  = column_index;
            tempLI.pszText  = buffer;
            tempLI.cchTextMax = sizeof(buffer);
            VERIFY(GetItem(&tempLI));
        }

        CString tmpChk = buffer;
        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

        if( (tmpnum = isInsert(defaultGroup, cnt)) != -1)
        {
            pDC->FillSolidRect(&tempRC, RGB(255, 255, 255));
            pDC->SetTextColor(RGB(0, 0, 0));
            tempRC.left += 2;
            pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
        }
        else if( (tmpnum = isInsert(radioGroup, cnt)) != -1)
        {
            radioCell cell = radioGroup[tmpnum];
            pDC->FillSolidRect(&tempRC, RGB(cell.color[0], cell.color[1], cell.color[2]));
            pDC->SetTextColor(RGB(125, 125, 125));
            tempRC.left += 2;
            pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
        }
        else 
        {
            pDC->FillSolidRect(&tempRC, RGB(255, 255, 255));
            pDC->SetTextColor(RGB(0, 0, 0));
            tempRC.left += 2;
            pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
        }
    }
    setVisibleRowNumber();
    setVisibleAttrRadioButton(prev_left - column_data.cx/2);
}

VfcVoid CCheckListCtrl::setVisibleRowNumber()
{
    visibleMinRow = GetScrollPos(SB_VERT);
    visibleMaxRow = visibleMinRow + 12;
}

VfcVoid CCheckListCtrl::setVisibleAttrRadioButton(VfcLong left)
{
    VfcLong row;
    radioCell cell;
    for(int i = 0; i < radioGroup.size(); i++)
    {
        row = radioGroup[i].row;
        cell = radioGroup[i];

        if( row >= visibleMinRow && row <= visibleMaxRow)
        {
            cell.btn->SetWindowPos(NULL, left - 6, (row - visibleMinRow + 1) * 19 + 4, 0, 0, SWP_NOSIZE);
            cell.btn->ShowWindow(SW_SHOW);
            cell.btn->RedrawWindow();
        }
        else
        {
            cell.btn->ShowWindow(SW_HIDE);
        }
    }
}

Don't use controls inside a control such. You will never reduce all flickering that is caused by the overlapping of windows.

Draw the button yourself. Also CListCtrl has its own check box style. Here is one sample .

And even adding multiple checkboxes to a CListCtrl has already been answered .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM