Элемент списка с NM_CUSTOMDRAW мигает

Каждый.

У меня есть такой редактор цветов в виде списка, каждый элемент представляет отдельный цвет. Таким образом, пользователь нажимает на подэлемент COLOR_CODE, палитра цветов обновляется до выбранного значения HSV, а затем пользователь перетаскивает курсор палитры цветов на поддоне, а подэлемент COLOR_CODE должен обновляться в режиме реального времени, а также в тексте идентификатора цвета. В большинстве случаев обновление выполняется хорошо и плавно, но иногда оно просто мерцает - ---- Это происходит по-настоящему мерцающим образом, как будто не было времени быстро его нарисовать.

Я начал свой поиск и нашел много постов, которые привели к двойной буферизации. Хорошо, в моем представлении списка включена функция DOUBLE BUFFERING

case WM_INITDIALOG:
ListView_SetExtendedListViewStyle(GetDlgItem(hDlg,id_listview),LVS_EX_DOUBLEBUFFER);

тоже пробовал так

SendDlgItemMessage(hWnd,id_listview,LVM_SETEXTENDEDLISTVIEWSTYLE,NULL,(LPARAM)LVS_EX_DOUBLEBUFFER);

Но это не помогло. Вот моя пользовательская процедура отрисовки. В основном она берет любую строку, записанную в ID subItem - например, 0xffb400, и преобразует ее в COLORREF, а затем устанавливает BG-цвет подэлемента 2 в результирующий цвет;

case WM_NOTIFY:
if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW)
        {
            SetWindowLong(hDlg, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam,hDlg));
            return TRUE;
        }
        break;

LRESULT colorEditor::ProcessCustomDraw (LPARAM lParam,HWND hDlg)
{
    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;

    switch(lplvcd->nmcd.dwDrawStage) 
    {
        case CDDS_PREPAINT:
            return CDRF_NOTIFYITEMDRAW;
        case CDDS_ITEMPREPAINT: 
            return CDRF_NOTIFYSUBITEMDRAW;
        case CDDS_ITEMPREPAINT|CDDS_SUBITEM: //Before an item is drawn//
            if (lplvcd->iSubItem==2)
            {
                item_redraw.iItem=lplvcd->nmcd.dwItemSpec;
                SendDlgItemMessageA(hWnd,id_listview,LVM_GETITEM,0,(LPARAM)&item_redraw);
                lplvcd->clrTextBk = colorrefFromString(item_redraw.pszText);
            }
            return CDRF_NEWFONT;
    }
    return CDRF_DODEFAULT;
}

На всякий случай, если вы думаете, что colorrefFromString - это тот случай, который я предоставляю, это перечисление:

COLORREF colorEditor::colorrefFromString(wchar_t *color)
{
    COLORREF res_color;
    unsigned short i=0,di=0;
    int digits[6];
    int h_digits[3];
    if (color[i]=='0'&&(color[i+1]=='x'||color[i+1]=='X')) i=2;
    int ix=0;

    while (color[(ix++)+i]!='\0'){}
    if (--ix!=5) while((ix++)<5)
        digits[di++]=0;

    while (color[i]!='\0')
    {
        if (color[i]>47&&color[i]<58) digits[di++]=color[i]-48;
        else if (color[i]>64&&color[i]<71) digits[di++]=color[i]-65+10;
        else if (color[i]>96&&color[i]<103) digits[di++]=color[i]-97+10;
        i++;
    }
    h_digits[0]=digits[0]*16+digits[1];
    h_digits[1]=digits[2]*16+digits[3];
    h_digits[2]=digits[4]*16+digits[5];
    res_color=0x00000000|(h_digits[2]<<16)|(h_digits[1]<<8)|h_digits[0];
    return res_color;
}

А теперь ВОПРОС: Почему у меня мерцание?

1 ответ

На первый взгляд я не вижу никакой реальной причины мерцания.

Но попробуйте сделать все рисование здесь самостоятельно. Может быть, это работает.

Просто посчитайте цвет. Вызовите FillRect для прямоугольника элемента с заданным постоянным током и верните CDRF_SKIPDEFAULT.

Другие вопросы по тегам