Прозрачные изображения в ImageLists для ListViews - PullRequest
2 голосов
/ 01 августа 2011

Вот изображение моей программы:

WhiteFlag

Как видите, значки не прозрачные, просто белые.Это проблематично, потому что я закодировал представление списка чередующимися цветами, а белый на сером выглядит очень некрасиво.

Сейчас я использую растровое изображение с розовым фоном для значков и использования розового цвета в качестве маски.Вот код для моего HIMAGELIST:

hImageList = ImageList_Create(16, 16,  ILC_COLOR32 | ILC_MASK, ICON_COUNT, 0);
if (hImageList != NULL)
{
  HBITMAP hBitmap = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_ICONS));
  if (hBitmap != NULL)
  {
    ImageList_AddMasked(hImageList, hBitmap, RGB(0xFF, 0, 0xFF)); // pink mask
    DeleteObject(hBitmap);
  }

  ImageList_SetBkColor(hImageList, CLR_NONE);
}
ListView_SetImageList(hWnd, hImageList, LVSIL_SMALL);

Вот код для пользовательского рисования представления списка (чередующиеся цвета)

LRESULT WhiteFlagUI::PaintListView(__in HWND hwndListView, __in LPARAM lParam)
{
  LPNMLVCUSTOMDRAW lpListDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);

  switch (lpListDraw->nmcd.dwDrawStage)
  {
    case CDDS_PREPAINT:
      return (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYSUBITEMDRAW);
      break;

    case (CDDS_PREPAINT | CDDS_ITEM):
      {
        RECT rect;

        if (ListView_GetSubItemRect(hwndListView, lpListDraw->nmcd.dwItemSpec, lpListDraw->iSubItem, LVIR_BOUNDS, &rect))
        {
          COLORREF color;

          // determine color
          if (lpListDraw->nmcd.uItemState & CDIS_SELECTED)
            color = RGB(157, 173, 215);
          else if (lpListDraw->nmcd.dwItemSpec % 2)
            color = RGB(240, 240, 240);
          else
            color = RGB(255, 255, 255);

          // paint
          HBRUSH hBrush = CreateSolidBrush(color);
          if (hBrush != NULL)
          {
            FillRect(lpListDraw->nmcd.hdc, &rect, hBrush);
            DeleteObject(hBrush);
          }

          // return color info
          lpListDraw->clrTextBk = color;
          return CDRF_NEWFONT;
        }
      }
      break;
  }
  return CDRF_DODEFAULT;
}

Откровенно говоря, я совершенно потерянкак подойти к этому.У кого-нибудь есть идеи?

Ответы [ 2 ]

0 голосов
/ 29 августа 2013

Я тоже столкнулся с этой проблемой. Я решил это, добавив SetBkColor (RGB (...)), где RGB (...) чередуется от цвета переднего плана к цвету фона в пользовательской процедуре рисования. Я использую 16x16 4B BMP с белым фоном. Вместо того, чтобы использовать FillRect (), я также установил clrTextBk. Последнее работает для текстов. Как я вижу из своих экспериментов с CListCtrl, функция SetBkColor () устанавливает цвет фона только для значков, а не для текста (я ничего не нашел в документации).

Все это работает только для непустых предметов. Чтобы рисовать пустые строки с этим стилем, я переопределяю функцию уведомления OnEraseBkgnd (). Для полностью пустого списка нарисованы простые прямоугольники.

Надеюсь, это поможет

Olexiy

0 голосов
/ 15 декабря 2012

Я нашел что-то вроде взлома вокруг этой проблемы.Если вы установите фоновое изображение в пустое белое растровое изображение с помощью ListView_SetBkImage, оно заставит иконки прозрачно рисовать.К сожалению, выполнение этого заставляет NM_CUSTOMDRAW игнорировать цвет фона, установленный с помощью CDRF_NEWFONT.Чтобы обойти это, вызовите FillRect, чтобы заполнить фон элемента в CDDS_ITEMPREPAINT и вернуть CDRF_DODEFAULT или CDRF_NEWFONT, если вы также меняете цвет переднего плана.

...