Alpha icons in listbox

G

Guest

Ok, didn't see anything in existing threads, so here goes

I have an ImageList loaded with 32-bit Alpha Icons

When I display the icons in either a TreeView or ListView, the Alpha is lost and replaced with BLACK. (actually, you can see the black in the ImageList as well)

How might I get around this? (I tried the fix posted on msdn, but it only fixes icons on a button, and doesn't deal with ImageList etc.

Thank you.
 
H

Herfried K. Wagner [MVP]

* "=?Utf-8?B?d29sZmU=?= said:
I have an ImageList loaded with 32-bit Alpha Icons.

When I display the icons in either a TreeView or ListView, the Alpha
is lost and replaced with BLACK. (actually, you can see the black in
the ImageList as well).

Did you try this (.NET 1.1):

\\\
Application.EnableVisualStyles()
Application.DoEvents()
///

.... before showing the 1st form?
 
S

Stu Smith

Unfortunately the solution I've found is somewhat complicated. I'll describe
ListView; TreeView is similar (but you'll need to respond to different
messages). If anyone knows a better method then please let me know; I'd love
to hack this out of my application!

The following code won't compile, but it should be enough to get you
started. I'll leave you to look up the constants in commctrl.h. I've
borrowed bits of this code from somewhere on CodeProject, and some is my own
creation.

1) Override ListView with your own custom class.

public class MyListView : ListView
{
public MyListView()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.AllPaintingInWmPaint, true);
}
}

2) Override WndProc.

protected override void WndProc(ref Message message)
{
base.WndProc(ref message);

switch(message.Msg)
{
case (int)ReflectedMessages.OCM_NOTIFY:
NMHDR nm = (NMHDR) message.GetLParam(typeof(NMHDR));
switch (nm.code)
{
case (int)NotificationMessages.NM_CUSTOMDRAW:
NotifyListCustomDraw(ref message);
break;
}
break;
}
}

3) Do the custom drawing. In my code, I do different drawing for details
view, so I've left that out, but I'm sure you can sort that out:

bool NotifyListCustomDraw(ref Message m)
{
m.Result = (IntPtr)CustomDrawReturnFlags.CDRF_DODEFAULT;
NMCUSTOMDRAW nmcd = (NMCUSTOMDRAW)m.GetLParam(typeof(NMCUSTOMDRAW));

if(nmcd.hdr.hwndFrom != Handle)
{
return false;
}
switch (nmcd.dwDrawStage)
{
case (int)(Win32.CustomDrawDrawStateFlags.CDDS_PREPAINT):
m.Result = (IntPtr)(Win32.CustomDrawReturnFlags.CDRF_NOTIFYITEMDRAW);
break;
case (int)(Win32.CustomDrawDrawStateFlags.CDDS_PREPAINT |
Win32.CustomDrawDrawStateFlags.CDDS_SUBITEM):
m.Result = (IntPtr)(Win32.CustomDrawReturnFlags.CDRF_NOTIFYSUBITEMDRAW
| Win32.CustomDrawReturnFlags.CDRF_NOTIFYPOSTPAINT);
break;
case (int)(Win32.CustomDrawDrawStateFlags.CDDS_PREPAINT |
Win32.CustomDrawDrawStateFlags.CDDS_ITEM):
m.Result = (IntPtr)(Win32.CustomDrawReturnFlags.CDRF_NOTIFYITEMDRAW |
Win32.CustomDrawReturnFlags.CDRF_NOTIFYPOSTPAINT);
break;
case (int)(Win32.CustomDrawDrawStateFlags.CDDS_POSTPAINT |
Win32.CustomDrawDrawStateFlags.CDDS_SUBITEM):
m.Result = (IntPtr)(Win32.CustomDrawReturnFlags.CDRF_SKIPDEFAULT);
break;
default:
{
switch(this.View)
{
case View.LargeIcon:
DoLargeIconCustomDrawing(ref m);
break;
case View.SmallIcon:
DoSmallIconCustomDrawing(ref m);
break;
}
break;
}
}

return false;
}

4) Actual icon drawing. I'll just do large here.

private void DrawLargeSmall(int row, HorizontalAlignment textAlign,
ImageList imageList, bool wrap)
{
using(Graphics g = this.CreateGraphics())
{
Rectangle entireRect = GetItemRect(row, ItemBoundsPortion.Entire);
ListViewItem item = Items[row];

if(entireRect.IntersectsWith(new Rectangle(0, 0, Width, Height)))
{
if(item.ImageIndex >= 0)
{
Rectangle iconRect = this.GetItemRect(row, ItemBoundsPortion.Icon);
int iconX = iconRect.Left + (iconRect.Width -
imageList.ImageSize.Width) / 2;
int iconY = iconRect.Top + (iconRect.Height -
imageList.ImageSize.Height) / 2;

imageList.Draw(g, iconX, iconY, item.ImageIndex);
}
}
}
}

void DoLargeIconCustomDrawing(ref Message m)
{
NMLVCUSTOMDRAW lvcd =
(NMLVCUSTOMDRAW)m.GetLParam(typeof(NMLVCUSTOMDRAW));
int row = (int)lvcd.nmcd.dwItemSpec;

DrawLargeSmall(row, HorizontalAlignment.Center, LargeImageList, true);

Marshal.StructureToPtr(lvcd, m.LParam, true);
m.Result = (IntPtr)CustomDrawReturnFlags.CDRF_SKIPDEFAULT;
}


You'll notice I use the Draw method of ImageList, rather than extracting the
image and passing to DrawImage or similar. This is because extracting the
image converts the icon to a bitmap, losing the alpha in the process.

Hope that helps,

Stu


wolfe said:
Ok, didn't see anything in existing threads, so here goes.

I have an ImageList loaded with 32-bit Alpha Icons.

When I display the icons in either a TreeView or ListView, the Alpha is
lost and replaced with BLACK. (actually, you can see the black in the
ImageList as well).
How might I get around this? (I tried the fix posted on msdn, but it only
fixes icons on a button, and doesn't deal with ImageList etc.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top