Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
740 views
in Technique[技术] by (71.8m points)

windows - ImageList Transparency on Listviews?

EDIT: I've offered a bounty, since I doubt I'll be getting any answers otherwise.

Lately I've been working with listviews and I've decided to add an icon for each item indicating whether it's input or output. The icons add fine, but they're not transparent:

Example of icon not being transparent

As can be seen, the icons are clearly not transparent. I'm currently doing something like this load the icons:

  hImageList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 2);
  if (hImageList != NULL)
  {
    iIN  = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(101)));
    iOUT = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(102)));
  }

I've tried messing with the flags for ImageList_Create & LoadIcon/LoadImage but have had no luck and to be honest I've run out of ideas.

Any help would be very appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First up, ImageList_ReplaceIcon copies the icon data when adding it to an image list. So the HICON needs to be released afterwards.

Next, imagelists are natively bitmaps, not icons. And the way you are creating your imagelist makes the conversion of icon to bitmap very ambiguous. ILC_COLOR32 implies the imagelist should be created as a 32bit dib section, which typically contain transparency information via an embedded alpha channel. ILC_MASK instead implies that the internal bitmaps are DDB bitmaps, with the transparency information stored as a 1bpp mask bitmap.

The quickest solution to your problem - take your two icons:

  • Merge them into a single bitmap resource thats 32 pels wide by 16 high. Fill the background with a mask color :- purple or something.
  • Create the bitmap using ILC_COLOR|ILC_MASK
  • Load the bitmap being sure NOT to use LR_TRANSPARENT.
  • Add the bitmap using ImageList_AddMasked passing in a COLORREF that represents the mask color.

OR, for a better visual effect...

  • export your PNG data as a 32x16 32bpp bitmap file containing pre-multiplied alpha channel data.
  • Create the imagelist using the ILC_COLOR32 value.
  • LoadImage() with LR_CREATEDIBSECTION to load the bitmap as a 32bpp dib section.
  • Add the image using ImageList_Add()

(the last option is kind of tricky as the number of tools that support writing out 32bit bmp files with properly pre multiplied alpha channels is rather low).


Edited to add the following code sample. Using a 4bpp bitmap created in the dev environment this works just great :-

HWND hwndCtl = CreateWindowEx(0,WC_LISTVIEW,TEXT("ListView1"),WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,0,0,cx,cy,hWnd,(HMENU)101,hModule,NULL);
HBITMAP hbm = (HBITMAP)LoadImage(hModule,MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,0);
COLORREF crMask=RGB(255,0,255);
HIMAGELIST himl = ImageList_Create(16,16,ILC_COLOR|ILC_MASK,2,0);
ImageList_AddMasked(himl,hbm,crMask);
ListView_SetImageList(hwndCtl,himl,LVSIL_NORMAL);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...