Click to See Complete Forum and Search --> : Strange Serialization Problem (icons)
KBirger
December 5th, 2004, 11:11 AM
First off, i'm writing a launcher program. It's going to have a context menu with all the apps that the user added (and their respective icons).
Considering that someone might put in 40 apps, that might take a while to cache EVERY icon EVERY time the program starts.
My solution was to add all the icons to an Arraylist and SERIALIZE the arraylist into a .dat file (just plaintext).
Problem: The icon that i add to the arraylist is 256/true-color with alpha transparency. The icon that comes out when i deserialize it is invariably 16 colors with no transparency/regular transparency.
i did some tests, this has nothing to do with the limitations of the icon class. (i displayed the before/after icon for myself). Also, i tested and it has nothing to do with how i'm storing the ArrayList of icons in a .dat file.
does anyone know what is going on or another way i could cache the icons without putting them into separate files?
Norfy
December 5th, 2004, 12:06 PM
This is a known problem with ImageLists but I have not known this to happen with images in general.
Do you have a small code sample that shows the problem?
KBirger
December 5th, 2004, 12:18 PM
ImageLists are not serializable and they are sealed ontop of it all.
public static ArrayList GetIcos(string FileName) //Deserializes a file and returns an arraylist containing Icons.
{
FileStream fs2 = new FileStream(FileName, FileMode.Open);
ArrayList a2;
BinaryFormatter formatter = new BinaryFormatter();
try
{
a2 = (ArrayList)formatter.Deserialize(fs2);
}
catch (Exception ex)
{
Console.WriteLine("Failed to deserialize. Reason: " + ex.Message);
throw;
}
finally
{
fs2.Close();
}
return a2;
}
public static void CacheIcos(ArrayList Files, string FileName)
{
ArrayList icoList = new ArrayList();
foreach(string sFile in Files)
{
API.ShellFileInfo SFInfo = new API.ShellFileInfo();
API.SHGetFileInfoA(sFile, 0, ref SFInfo, Marshal.SizeOf(SFInfo), SHGFI.Icon |SHGFI.SmallIcon);
Icon ico = System.Drawing.Icon.FromHandle(SFInfo.hIcon);
icoList.Add(ico);
}
FileStream fs2 = new FileStream(FileName, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs2, icoList);
}
catch (Exception ex)
{
Console.WriteLine("Failed to serialize. Reason: " + ex.Message);
throw;
}
finally
{
fs2.Close();
}
}
That is my methods class, to test it i just have a form with this code:
API.CacheIcos(exeFiles,"DataFile.dat");
arIcons = API.GetIcos("DataFile.dat");
this.Icon = (Icon)arIcons[0];
sorry i realize this is a bit messy, but thats what happens after hours of experimenting:D
Norfy
December 6th, 2004, 04:35 AM
Sorry I have no idea what the problem is. I took a collection of icons each with multiple images, used your code to serialize and deserialize and basically got back what I put in.
The only thing I can think of is that .NET itself does not particularly use icons. All controls know how to display a single bitmap. The icon property on a Form seems to be the only place where an Icon can be set. How the Form selects a particular image from the Icon I do not know.
KBirger
December 6th, 2004, 01:51 PM
did you pull the icons from exes? did the icons have alpha-transparency?
i managed to get it to show me 16 bit / 32 bit colors and transparency, but the alphatransparency doesn't work.
Norfy
December 7th, 2004, 07:59 AM
No I didn't pull the icons from an exe I don't have any code to do so.
In the attachment is an icons.dat file containing one icon with multiple images with alpha transparency.
The only way I could verify this was with a third party icon viewer. Visual Studio doesn't appear to be handle it very well. So this could be your problem.
KBirger
December 7th, 2004, 01:17 PM
yes norfy, i have come to the same conclusion. thank you very much for your help, it helped me clear a few things up.
the problem has to do with the .net classes, they aren't very adaptive i guess... you'd expect more from microsoft seeing as how they released the alphatransparency control library in the first place, but oh well.
Norfy
December 7th, 2004, 01:35 PM
If you are able to extract a single bitmap from the icon with its alpha transparency intact then it will be displayed correctly.
The must be a way of doing this using the windows API but I have no experience in that area.
I'm currently having "fun" with alpha transparency at the moment :(
KBirger
December 8th, 2004, 07:05 AM
you have to use either IconList.draw or the drawImage (i believe) api
Norfy
December 8th, 2004, 07:23 AM
you have to use either IconList.draw or the drawImage (i believe) apiTo do what? The .NET API or Windows API via PInvoke?
Both APIs can display an Image with alpha transparency correctly.
If you add an Image to an ImageList the alpha channel is corrupted.
Displaying an Image is not the problem. The problem is getting an Image in the first place from an Icon (with the alpha transparency intact).
Norfy
December 8th, 2004, 08:58 AM
KBirger,
Just found this - Forum (http://www.devhood.com/messages/message_view-2.aspx?thread_id=71859)
Seems someone else has done something similar to your requirements.
KBirger
December 8th, 2004, 01:12 PM
i saw that. his problem has to do with the classes he uses. if i look at the icon before serializing it, it will be (possibly) 32bit with alpha. it's the serializing that messes it up.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.