Transparent images in ImageLists for ListViews

此生再无相见时 提交于 2019-11-30 19:09:13

问题


Here is a picture of my program:

As you can see, the icons aren't transparent, simply white. This is problematic, because I've coded the list-view to alternate colors and the white looks very ugly on grey.

Right now, I'm using a bitmap with a pink background for the icons, and using the pink color as a mask. Here's the code for my 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); 

Here is the code for the list-view's Custom Draw (the alternating colors)

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; } 

Quite frankly, I'm completely lost as to how to approach this. Does anyone have any ideas?


回答1:


I found a bit of a hack around this problem. If you set the background image to a blank white bitmap using ListView_SetBkImage it will force the icons to draw transparently. Unfortunately, doing this causes NM_CUSTOMDRAW to ignore the background color set with CDRF_NEWFONT. To get around it, call FillRect to fill background of the item in CDDS_ITEMPREPAINT and return CDRF_DODEFAULT or CDRF_NEWFONT if you are changing the foreground color as well.




回答2:


I was faced with this problem as well. I've solved it by adding SetBkColor(RGB(...)) where RGB(...) alternates from foreground color to background one in the custom draw procedure. I use 16x16 4b BMP with white background. Instead of using FillRect(), I set clrTextBk too. The last works for texts. As I see from my experiments with CListCtrl, function SetBkColor() sets background color for icons only and does not for text (I found nothing about this in docs).

All this works only for non-empty items. To draw empty rows with this style, I override OnEraseBkgnd() notification function. For fully empty list, simple rectangles are drawn.

I hope this will help

Olexiy



来源:https://stackoverflow.com/questions/6893351/transparent-images-in-imagelists-for-listviews

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!