private IconDirectoryMember FindMember(IconDirectoryMember newMember) { foreach (IconDirectoryMember member in _members) { if (member.CompareTo(newMember) == 0) { return(member); } } return(null); }
/////////////////////////////////// public void Save(Stream stream) { BinaryWriter wtr = new BinaryWriter(stream); // Write IconHeader ( IconDirectory ) wtr.Write((UInt16)0); // wReserved wtr.Write((UInt16)(IsIcon ? 1 : 2)); // wType wtr.Write((UInt16)this._members.Count); // wCount // Write out the array of directory entries, calculating the offsets first UInt32[] offsets = new UInt32[_members.Count]; UInt32 offsetFromEndOfDirectory = (UInt32)stream.Position + (UInt32)(_members.Count * Marshal.SizeOf(typeof(FileIconDirectoryEntry))); for (int i = 0; i < _members.Count; i++) { IconDirectoryMember m = _members[i] as IconDirectoryMember; // Offset is from the start of the file offsets[i] = offsetFromEndOfDirectory; offsetFromEndOfDirectory += m.Size; } for (int i = 0; i < _members.Count; i++) { IconDirectoryMember member = _members[i] as IconDirectoryMember; wtr.Write((Byte)member.Dimensions.Width); wtr.Write((Byte)member.Dimensions.Height); wtr.Write(member.ColorCount); wtr.Write(member.Reserved); wtr.Write(member.Planes); wtr.Write(member.BitCount); wtr.Write(member.Size); wtr.Write(offsets[i]); } // Write out the actual images for (int i = 0; i < _members.Count; i++) { IconDirectoryMember m = _members[i] as IconDirectoryMember; wtr.Write(m.ResourceData.RawData); } // and we're done }
public void RemoveMemberImage(IconDirectoryMember member) { if (_members.IndexOf(member) == -1) { return; } ResourceLang lang = member.ResourceData.Lang; _members.Remove(member); Source.Remove(lang); }
public static void FromFile(Stream stream, UInt16 lang, ResourceSource source, ResIconDir resDir) { if (stream.Length < Marshal.SizeOf(typeof(IconDirectory))) { return; } BinaryReader rdr = new BinaryReader(stream); IconDirectory?tDir = ReadIcoHeader(rdr); if (tDir == null) { return; } IconDirectory dir = tDir.Value; /////////////////////////////// // rdr is now at the beginning of the array of FileIconDirectoryMembers FileIconDirectoryEntry[] subImages = new FileIconDirectoryEntry[dir.wCount]; for (int i = 0; i < dir.wCount; i++) { subImages[i] = ReadFileDirMember(rdr); } ///////////////////////////// // now for image data itself IconImageResourceDataFactory factory = GetIconImageFactory(); for (int i = 0; i < dir.wCount; i++) { FileIconDirectoryEntry img = subImages[i]; stream.Seek(img.dwImageOffset, SeekOrigin.Begin); Byte[] data = new Byte[img.dwBytesInRes]; stream.Read(data, 0, (int)img.dwBytesInRes); Size dimensions = new Size(img.bWidth == 0 ? 256 : img.bWidth, img.bHeight == 0 ? 256 : img.bHeight); IconCursorImageResourceData memberImageData = factory.FromResource(null, data) as IconCursorImageResourceData; IconDirectoryMember member = new IconDirectoryMember(memberImageData, dimensions, img.bColorCount, img.bReserved, img.wPlanes, img.wBitCount, img.dwBytesInRes); resDir.AddUpdateMemberImage(member); } }
/////////////////////////////////// public IconDirectoryMember GetIconForSize(Size size) { // search for an identical or larger match (larger results can be scaled down) // sorted by size, then color depth; so the first dimensions match will be of the highest color depth IconDirectoryMember[] sortedIcons = new IconDirectoryMember[_members.Count]; _members.CopyTo(sortedIcons, 0); Array.Sort <IconDirectoryMember>(sortedIcons, delegate(IconDirectoryMember x, IconDirectoryMember y) { // compare y to x because we want it in descending order Int32 sizeComparison = y.Dimensions.Width.CompareTo(x.Dimensions.Width); return(sizeComparison == 0 ? y.BitCount.CompareTo(x.BitCount) : sizeComparison); }); IconDirectoryMember bestMatch = null; foreach (IconDirectoryMember member in sortedIcons) { if (member.Dimensions == size) { return(member); } if (bestMatch == null) { bestMatch = member; } if (member.Dimensions.Width > size.Width) { if (bestMatch == null) { bestMatch = member; } else { if (member.Dimensions.Width < bestMatch.Dimensions.Width) { bestMatch = member; } } } } return(bestMatch); }
/// <summary>Adds or Updates (replaces) a member image. DO NOT USE to add an entry that already exists as part of a resource</summary> public void AddUpdateMemberImage(IconDirectoryMember newMember) { // it is important to maintain order: color depth ascending then size descending. // I've implemented this in IconDirectoryMember.CompareTo and called in GetRawData() // first off, check if it's an add or an update by seeing if the specified member already exists IconDirectoryMember orig = null; if ((orig = FindMember(newMember)) != null) { // it already exists, so just update the associated ResourceLang ResourceLang lang = orig.ResourceData.Lang; lang.SwapData(newMember.ResourceData); _members.Add(newMember); _members.Remove(orig); } else { // it's new, so add it if (IsIcon) { Source.Add(_iconImageTypeId, Source.GetUnusedName(_iconImageTypeId), Lang, newMember.ResourceData); } else { Source.Add(_cursorImageTypeId, Source.GetUnusedName(_iconImageTypeId), Lang, newMember.ResourceData); } _members.Add(newMember); } _updated = true; }
internal void UnderlyingAdd(IconDirectoryMember existingMember) { _members.Add(existingMember); }