View All Icon Sizes With 100% Managed Code

by JasonRShaver 30. July 2007 16:37

I had a situation recently where I needed to add icons to a .NET context menu (attached to a system tray icon). Each icon had 20+ “images” inside it for the different resolutions and color depths. This class will allow you to view each of the inner icons for each icon in an icon (how is that for confusing).

Let me mention that the basis for this code was written by Matthew Hazlett (http://www.codeproject.com/dotnet/MultiIcon.asp) but has been modified to improve its structure. (No more storing MemoryStreams globally and now fits my coding standards for nameing for example.)

Code:

using System;

using System.IO;

using System.Collections.Generic;

using System.Drawing;

namespace ProductNamespace

{

class IconManager

{

private IconHeader _IconHeader;

private List<IconEntry> _InnerIcons;

private byte[] _IconData;

///

/// Gets all the icon information entries.

///

/// The icons.

public IconEntry[] Icons

{

get { return _InnerIcons.ToArray(); }

}

///

/// Gets the count of icon entries.

///

/// The count.

public int Count

{

get { return _InnerIcons.Count; }

}

///

/// Initializes a new instance of the class.

///

///

 

The filename of the icon to load.

 

 

public IconManager(string filename)

: this ()

{

using (FileStream IconFile = new FileStream(filename, FileMode.Open, FileAccess.Read))

{

_IconData = new byte[IconFile.Length];

IconFile.Read(_IconData, 0, (int)IconFile.Length);

}

LoadIcon(_IconData);

}

///

/// Initializes a new instance of the class.

///

///

 

The source icon to load.

 

 

public IconManager(Icon sourceIcon)

: this ()

{

using (MemoryStream IconStream = new MemoryStream())

{

sourceIcon.Save(IconStream);

_IconData = new byte[IconStream.Length];

IconStream.Position = 0;

IconStream.Read(_IconData, 0, (int)IconStream.Length);

}

LoadIcon(_IconData);

}

///

/// Initializes a new instance of the class.

///

private IconManager()

{

_InnerIcons = new List<IconEntry>();

_IconData = new byte[0];

}

///

/// Builds the icon.

///

///

 

The index.

 

 

///

public Icon BuildIcon(int index)

{

IconEntry thisIcon = _InnerIcons[index];

using (MemoryStream NewIconStream = new MemoryStream())

{

BinaryWriter writer = new BinaryWriter(NewIconStream);

// New Values

Int16 newNumber = 1;

Int32 newOffset = 22;

// Write it

writer.Write(_IconHeader.Reserved);

writer.Write(_IconHeader.Type);

writer.Write(newNumber);

writer.Write(thisIcon.Width);

writer.Write(thisIcon.Height);

writer.Write(thisIcon.ColorCount);

writer.Write(thisIcon.Reserved);

writer.Write(thisIcon.Planes);

writer.Write(thisIcon.BitCount);

writer.Write(thisIcon.BytesInRes);

writer.Write(newOffset);

// Grab the icon

byte[] tmpBuffer = new byte[thisIcon.BytesInRes];

using (MemoryStream IconStream = new MemoryStream(_IconData))

{

IconStream.Position = thisIcon.ImageOffset;

IconStream.Read(tmpBuffer, 0, thisIcon.BytesInRes);

}

writer.Write(tmpBuffer);

// Finish up

writer.Flush();

NewIconStream.Position = 0;

Icon NewIcon = new Icon(NewIconStream, thisIcon.Width, thisIcon.Height);

}

return NewIcon;

}

///

/// Finds the icon.

///

///

 

The width.

 

 

///

 

The height.

 

 

///

public Icon FindIcon(int width, int height)

{

int BestIconIndex = -1;

int BestIconColorDepth = 0;

for (int x = 0; x < _InnerIcons.Count; x++)

{

if (_InnerIcons[x].Width == width && _InnerIcons[x].Height == height)

{

if (BestIconColorDepth < _InnerIcons[x].BitCount)

{

BestIconIndex = x;

BestIconColorDepth = _InnerIcons[x].BitCount;

}

}

}

if (BestIconIndex == -1)

return null;

else

return BuildIcon(BestIconIndex);

}

///

/// Finds the icon.

///

///

 

The width.

 

 

///

 

The height.

 

 

///

 

The color depth.

 

 

///

public Icon FindIcon(int width, int height, int colorDepth)

{

for (int x = 0; x < _InnerIcons.Count; x++)

{

if (_InnerIcons[x].Width == width && _InnerIcons[x].Height == height)

{

if (colorDepth == _InnerIcons[x].BitCount)

return BuildIcon(x);

}

}

return null;

}

private void LoadIcon(byte[] iconData)

{

_IconData = iconData;

using (MemoryStream IconStream = new MemoryStream(_IconData))

{

_IconHeader = new IconHeader(IconStream);

// Read the icons

for (int counter = 0; counter < _IconHeader.Count; counter++)

{

IconEntry entry = new IconEntry(IconStream);

_InnerIcons.Add(entry);

}

}

}

#region Internal Classes

///

/// Stores the headers of the ICO

///

private class IconHeader

{

public Int16 Reserved;

public Int16 Type;

public Int16 Count;

///

/// Initializes a new instance of the class.

///

///

 

The ico stream.

 

 

public IconHeader(MemoryStream icoStream)

{

BinaryReader icoFile = new BinaryReader(icoStream);

Reserved = icoFile.ReadInt16();

Type = icoFile.ReadInt16();

Count = icoFile.ReadInt16();

}

}

///

/// Each icon if the file has its own header. This is where I read

/// the info for each icon.

///

public class IconEntry

{

public byte Width;

public byte Height;

public byte ColorCount;

public byte Reserved;

public Int16 Planes;

public Int16 BitCount;

public Int32 BytesInRes;

public Int32 ImageOffset;

///

/// Initializes a new instance of the class.

///

///

 

The ico stream.

 

 

public IconEntry(MemoryStream icoStream)

{

BinaryReader icoFile = new BinaryReader(icoStream);

Width = icoFile.ReadByte();

Height = icoFile.ReadByte();

ColorCount = icoFile.ReadByte();

Reserved = icoFile.ReadByte();

Planes = icoFile.ReadInt16();

BitCount = icoFile.ReadInt16();

BytesInRes = icoFile.ReadInt32();

ImageOffset = icoFile.ReadInt32();

}

}

#endregion

}

}

Tags:

Blog

'CSC1.tmp is not a valid Win32 resource file'

by JasonRShaver 25. July 2007 16:37

 I got an error like this while building a .NET project on Windows XP box with Visual Studio 2005.  This same project has been building on my Vista (also VS2005) box for weeks now so I could not Identify the issue. 

It turns out that this issue is related to having compressed 256x256 PNG images for the Application Icon in the project properties.  Now the standard Vista icon has the following settings:

256x256 - XP (RGB/A) (PNG Compressed)
256x256 – 256 colors (PNG Compressed)
256x256 – 16 colors (PNG Compressed)
48x48 - XP (RGB/A)
48x48 – 256 colors
48x48 – 16 colors
32x32 - XP (RGB/A)
32x32 – 256 colors
32x32 – 16 colors
16x16 - XP (RGB/A)
16x16 – 256 colors
16x16 – 16 colors

 That does not include the icons that XP likes (128x128 for Dock-Bars) and the native Vista desktop size of 96x96.

There are two solutions to the ‘CSCx.tmp is not a valid Win32 resource file’ error:
1) Remove the 256x256 sizes from your icons, making them readable on your XP build machine.
or
2) Upgrade your build and/or development machines to Vista.

If anyone else finds a better option, let me know, but at this point it seems that the only way to build an app with a ‘Vista’ application icon is to build it on a Vista machine.

 

Tags:

Blog

SQL Server 2005 Replication - The schema script [...] could not be propagated to the subscriber

by JasonRShaver 14. July 2007 16:37

  I got this error while setting up a SQL Server 2005 Merge Replication system.

 

The schema script '[UNC PATH]\Appointments_2.sch' could not be propagated to the subscriber. (Source: MSSQL_REPL, Error number: MSSQL_REPL-2147023570)
Get help: http://help/MSSQL_REPL-2147023570
 

The merge process was unable to deliver the snapshot to the Subscriber. If using Web synchronization, the merge process may have been unable to create or write to the message file. When troubleshooting, restart the synchronization with verbose history logging and specify an output file to which to write. (Source: MSSQL_REPL, Error number: MSSQL_REPL-2147201001)
Get help: http://help/MSSQL_REPL-2147201001

I saw a few people who had permissions issue or where not using a share for the snapshot folder.  In my case, after alot of troubleshooting, it came down to a much simpler issue.  There are 2 "Server Tools" installer for 2005, one for "Compact Edition" [1.4meg] and one for "Mobile Edition" [3.3meg] and they both have the same filename.  

Here is a link where you can download them.  If you are having issues with propagating to the subscriber, uninstall the server tool you are using and install the other and see how it goes.

 

Tags:

Blog

About the author

I am a software developer working for Microsoft in Redmond, WA.  In addition, my wife and I own TTXOnline, what is likely the 3rd largest table tennis store in the US.

Month List

Page List