예제 #1
0
        private IconDirectoryMember FindMember(IconDirectoryMember newMember)
        {
            foreach (IconDirectoryMember member in _members)
            {
                if (member.CompareTo(newMember) == 0)
                {
                    return(member);
                }
            }

            return(null);
        }
예제 #2
0
        ///////////////////////////////////

        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
        }
예제 #3
0
        public void RemoveMemberImage(IconDirectoryMember member)
        {
            if (_members.IndexOf(member) == -1)
            {
                return;
            }

            ResourceLang lang = member.ResourceData.Lang;

            _members.Remove(member);

            Source.Remove(lang);
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        ///////////////////////////////////

        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);
        }
예제 #6
0
        /// <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;
        }
예제 #7
0
 internal void UnderlyingAdd(IconDirectoryMember existingMember)
 {
     _members.Add(existingMember);
 }