HighTechTalks DotNet Forums  

Icon.FromHandle + ImageList = decreased color depth

Dotnet Framework (WinForms Controls) microsoft.public.dotnet.framework.windowsforms.controls


Discuss Icon.FromHandle + ImageList = decreased color depth in the Dotnet Framework (WinForms Controls) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Alex Blekhman
 
Posts: n/a

Default Icon.FromHandle + ImageList = decreased color depth - 11-30-2007 , 07:52 PM






Hello,

I'm writing Visual Studio add-in in C# (VS 2008, WinXP SP2).
I need to display a list of files in ListView control. In
order to get the file type's associated icon I use
`SHGetFileInfo' API from Shell32.dll (the code is taken
verbatim from here:
http://www.codeproject.com/csharp/iconhandler.asp). Then I
add resulting icons to ImageList control, which is assigned
to `SmallImageList' property of ListView control:

Icon icon = IconFromExtension(extension, SHGFI_SMALLICON);
_imageList.Images.Add(extension, icon);

Everything works, except that icons look ugly. It seems that
color depth is decreased and alpha blending is not applied
at all. Here's screenshot fragment to illustrate the
problem:

[16KB, PNG]
http://farm3.static.flickr.com/2176/...d3176baf_o.png

How can I fix it?

Thanks in advance
Alex


Reply With Quote
  #2  
Old   
Jeff Gaines
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-01-2007 , 08:34 AM






On 01/12/2007 in message <#DAH8Q7MIHA.2000 (AT) TK2MSFTNGP05 (DOT) phx.gbl> Alex
Blekhman wrote:

Quote:
Everything works, except that icons look ugly. It seems that color depth
is decreased and alpha blending is not applied at all. Here's screenshot
fragment to illustrate the problem:
You will get better results associating the ListView directly with the
system image list. You need to call the following at an early stage in
your app but fater the ListView handle is created:

cCommon.SetSmallSystemImageList(listview1);
cCommon.SetLargeSystemImageList(listview1);

Then I have the following in my cCommon class:

public static int SetLargeSystemImageList(ListView lv)
{
const int LVM_FIRST = 0x1000;
const int LVM_SETIMAGELIST = (LVM_FIRST + 3);
const int LVSIL_NORMAL = 0;

IntPtr ipLargeSystemImageList = GetLargeSystemImageList();

// Associate the System image list with the ListView
return SendMessage(lv.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL,
ipLargeSystemImageList);
}

public static int SetSmallSystemImageList(ListView lv)
{
const int LVM_FIRST = 0x1000;
const int LVM_SETIMAGELIST = (LVM_FIRST + 3);
const int LVSIL_SMALL = 1;

IntPtr ipSmallSystemImageList = GetSmallSystemImageList();

// Associate the System image list with the ListView
return SendMessage(lv.Handle, LVM_SETIMAGELIST, LVSIL_SMALL,
ipSmallSystemImageList);
}


public static IntPtr GetLargeSystemImageList()
{
// Get System Image List
const int SHGFI_SYSICONINDEX = 0x000004000;
const int SHGFI_LARGEICON = 0x000000000;
const int SHGFI_USEFILEATTRIBUTES = 0x000000010;

uint uFlags = SHGFI_SYSICONINDEX | SHGFI_LARGEICON |
SHGFI_USEFILEATTRIBUTES;

SHFILEINFO shfi = new SHFILEINFO();

IntPtr ipLargeSystemImageList = SHGetFileInfo(@"c:\Temp\*.txt", 0, out
shfi, Marshal.SizeOf(typeof(SHFILEINFO)), uFlags);

if (shfi.hIcon != IntPtr.Zero)
DestroyIcon(shfi.hIcon);

return ipLargeSystemImageList;
}


public static IntPtr GetSmallSystemImageList()
{
// Get System Image List
const int SHGFI_SYSICONINDEX = 0x000004000;
const int SHGFI_SMALLICON = 0x000000001;
const int SHGFI_USEFILEATTRIBUTES = 0x000000010;

uint uFlags = SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
SHGFI_USEFILEATTRIBUTES;

SHFILEINFO shfi = new SHFILEINFO();

IntPtr ipSmallSystemImageList = SHGetFileInfo(@"c:\Temp\*.txt", 0, out
shfi, Marshal.SizeOf(typeof(SHFILEINFO)), uFlags);

if (shfi.hIcon != IntPtr.Zero)
DestroyIcon(shfi.hIcon);

return ipSmallSystemImageList;
}

It seems a lot of code but I have it in a common library so I only had to
write it once :-)

Since you use the API I guess you can prototype the API calls and
structures, if not come back here.

--
Jeff Gaines


Reply With Quote
  #3  
Old   
Alex Blekhman
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-01-2007 , 02:14 PM



"Jeff Gaines" wrote:
Quote:
Everything works, except that icons look ugly.

You will get better results associating the ListView
directly with the system image list.
Thanks a lot. It worked. Though I obtained system image list
with `SHGetImageList' call, rather than using the return
value of `SHGetFileInfo'.

Quote:
Since you use the API I guess you can prototype the API
calls and structures, if not come back here.
<flame intensity="120%">
Yes, I know how to prototype the API calls. Actually, I
develop native Windows applications in C++ at work. I
decided to make simple VS add-in in C# primarily as an
exercise to learn C# and .NET framework. If I end up with
usefull add-in, then all the better.

While I enjoy C# as programming languase so far, I cannot
say the same about "System.Windows.Forms" namespace. I
understand that it tries to embrace the whole universe of
Windows GUI. It's quite challenging task, indeed. However,
the more I deal with it, the more I encounter little
annoyances like the one that started this thread.

To accomplish anything decent I required to hack my way
through the intricacies of Interop and environment doesn't
help me there. I hoped that WinForms will save me some hair
on the head, while making me able to cncentrate on
"interesting" parts. On the contrary. The interesting parts
are finished long ago, while I need to fight the framework
for every damn icon. I could finish this small add-in in C++
with ATL within hours, actually. But with WinForms I already
wasted hours by writing `User32.SendMessage' calls to make
trivial things work. I didn't call `SendMessage' for years
in C++! We have libraries for that, for frak's sake!
</flame>

Alex



Reply With Quote
  #4  
Old   
Jeff Gaines
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-01-2007 , 03:44 PM



On 01/12/2007 in message <udiAD5ENIHA.6108 (AT) TK2MSFTNGP03 (DOT) phx.gbl> Alex
Blekhman wrote:

Quote:
To accomplish anything decent I required to hack my way through the
intricacies of Interop and environment doesn't help me there. I hoped that
WinForms will save me some hair on the head, while making me able to
cncentrate on "interesting" parts. On the contrary.
Absolutely, it's very disappointing to have to use what are essentially
VB6 techniques to access the API. Why MSFT didn't include an API Namespace
I do not know. NET was designed for websites really, there isn't a MSFT
tool for desktop apps. I keep dabbling with Delphi, at least it provides
'grown up' functions.

--
Jeff Gaines


Reply With Quote
  #5  
Old   
Alex Blekhman
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-01-2007 , 05:36 PM



"Jeff Gaines" wrote:
Quote:
Absolutely, it's very disappointing to have to use what
are essentially VB6 techniques to access the API. Why MSFT
didn't include an API Namespace I do not know.
This question has an easy answer, actually. MS didn't make
"Microsoft.Win32.Native" namespace in order to save people
from themselves. All these horrendous API declarations
littered with hardcoded constants and endless casts comprise
the big fat hint that native Interop is strongly
discouraged. I can understand this motive, since resulting
code is very brittle (not to mention it looks like sh*te).

The real question here is how it happened that at the end of
2007 the MS poster boy lacks features so basic as retrieving
an icon for given file type? This is ridiculous that I
doomed to have recourse to the Interop in order to
accomplish such mundane thing. This is even more ridiculous
that I must have recourse to the Interop again to show this
icon in ListView control! At least do fully implement your
own common controls library!

Quote:
I keep dabbling with Delphi, at least it provides 'grown
up' functions.
I never used Delphi myself. Correct me if I wrong, but I
thought that Delphi is inherently incapable of doing Unicode
builds. Is it true?

Alex



Reply With Quote
  #6  
Old   
Jeff Gaines
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-01-2007 , 06:37 PM



On 01/12/2007 in message <uiKT$pGNIHA.3384 (AT) TK2MSFTNGP04 (DOT) phx.gbl> Alex
Blekhman wrote:

Quote:
I never used Delphi myself. Correct me if I wrong, but I thought that
Delphi is inherently incapable of doing Unicode builds. Is it true?
I have no idea :-)

The apps I write work though.

--
Jeff Gaines


Reply With Quote
  #7  
Old   
mike
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-20-2007 , 03:36 PM



On Nov 30, 7:52 pm, "Alex Blekhman" <tkfx.REM... (AT) yahoo (DOT) com> wrote:
Quote:
Hello,

I'm writing Visual Studio add-in in C# (VS 2008, WinXP SP2).
I need to display a list of files in ListView control. In
order to get the file type's associated icon I use
`SHGetFileInfo' API from Shell32.dll (the code is taken
verbatim from here:http://www.codeproject.com/csharp/iconhandler.asp). Then I
add resulting icons to ImageList control, which is assigned
to `SmallImageList' property of ListView control:

Icon icon = IconFromExtension(extension, SHGFI_SMALLICON);
_imageList.Images.Add(extension, icon);

Everything works, except that icons look ugly. It seems that
color depth is decreased and alpha blending is not applied
at all. Here's screenshot fragment to illustrate the
problem:

[16KB, PNG]http://farm3.static.flickr.com/2176/2077118696_43d3176baf_o.png

How can I fix it?

Thanks in advance
Alex
I had the same problem and while debugging i found that the color
depth was set to 8bit by default.
So this fixed that....

imageList.ColorDepth = ColorDepth.Depth32Bit;

Then the alpha color is usually handled through the TransparentColor
property.

imageListLarge.TransparentColor = Color.White;


Reply With Quote
  #8  
Old   
Alex Blekhman
 
Posts: n/a

Default Re: Icon.FromHandle + ImageList = decreased color depth - 12-20-2007 , 05:13 PM



"mike" wrote:
Quote:
I had the same problem and while debugging i found that
the color
depth was set to 8bit by default.
So this fixed that....

imageList.ColorDepth = ColorDepth.Depth32Bit;

Then the alpha color is usually handled through the
TransparentColor
property.

imageListLarge.TransparentColor = Color.White;
Thanks for the tip. I'll keep it in mind next time I need to
handle icons in image list. Currently I solved it as Jeff
Gaines suggested: system image list is directly associated
with ListView control.

Alex




Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.