ListView CustomDraw отрисовка иконок

Тема в разделе "WASM.BEGINNERS", создана пользователем RamMerLabs, 28 мар 2018.

  1. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    Доброго дня, господа!
    Прошу помочь со следующей ситуацией. Есть ListView (LVS_REPORT) (на WinAPI, без фреймворков), в нём нужно динамически менять иконки у строк. Вариант с ImageList работает, но создаётся много не совсем красивого кода для учёта соответствия номера иконки в ImageList конкретной строке в LV (строки в LV часто добавляются/удаляются в большом количестве). HICON для каждой иконки известен и легкодоступен. Посему обратил внимание на CustomDraw в следующем виде:
    Код (ASM):
    1.  
    2.  mov edi, lParam
    3.  assume edi: ptr NMLVCUSTOMDRAW60
    4.  
    5.  .if [edi].nmcd.dwDrawStage == CDDS_PREPAINT
    6.   mov dwMsgResult, CDRF_NOTIFYITEMDRAW
    7.  
    8.  .elseif [edi].nmcd.dwDrawStage == CDDS_ITEMPREPAINT
    9.   mov dwMsgResult, CDRF_NOTIFYPOSTPAINT
    10.  
    11.  .elseif [edi].nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT
    12.   mov esi, [edi].nmcd.lItemlParam
    13.   .if esi
    14.    .if RL_LVINFOLIST_HEADER.hIcon[esi] && RL_LVINFOLIST_HEADER.hIcon[esi] != INVALID_HANDLE_VALUE
    15.     mov rcIcon.left, LVIR_BOUNDS
    16.     lea eax, rcIcon
    17.     push eax
    18.     push [edi].nmcd.dwItemSpec
    19.     push LVM_GETITEMRECT
    20.     invoke WindowFromDC, [edi].nmcd.hdc
    21.     push eax
    22.     call SendMessageW
    23.     invoke DrawIconEx, [edi].nmcd.hdc, rcIcon.left, rcIcon.top, RL_LVINFOLIST_HEADER.hIcon[esi], 16, 16, 0, 0, DI_NORMAL
    24.    .endif
    25.   .endif
    26.   mov dwMsgResult, CDRF_SKIPDEFAULT
    27.  .else
    28.   mov dwMsgResult, CDRF_DODEFAULT
    29.  .endif
    30.  
    31.  .if dwMsgResult
    32.   invoke SetWindowLongW, hWnd, DWL_MSGRESULT, dwMsgResult
    33.   xor eax, eax
    34.   inc eax
    35.  .else
    36.   xor eax, eax
    37.  .endif
    38.  assume edi:nothing
    39.  
    В lItemlParam к каждой строке лежит указатель на структуру с данными для этой строки.
    dwMsgResult возвращается через SetWindowLong, т.к. это диалоговое окно.

    Иконки отрисовываются только при наведении курсора на строку и исчезают при следующем цикле обновления инфы в ListView (даже если обновляются только SubItem'ы).
    Понимаю, что скорее всего нужно обрабатывать и WM_PAINT с аналогичными действиями, но тогда получается ещё больше кода, чем с ImageList.
    Примеры с CustomDraw на codeproject и msdn делают всё тоже самое, что в куске кода выше, но проблем с отображением иконок (или иной графики, вроде самодельного прогрессбара в SubItem) не наблюдается.
    Что я упускаю из виду? Спасибо.
     
    Последнее редактирование: 29 мар 2018