コード例 #1
0
        private static IconCursorImageResourceData GetDataFromWid(ResourceType type, ResourceLang thisLang, ushort wId)
        {
            ResourceName name = null;

            foreach (ResourceName nom in type.Names)
            {
                if (nom.Identifier.IntegerId == wId)
                {
                    name = nom; break;
                }
            }

            if (name == null)
            {
                return(null);
            }

            ResourceLang lang = null;

            foreach (ResourceLang lan in name.Langs)
            {
                if (lan.LanguageId == thisLang.LanguageId)
                {
                    lang = lan; break;
                }                                                                                // because a ResourceName can have multiple languages associated with it. I'm after the ResourceLang's resource data related to this Directory's lang
            }

            IconCursorImageResourceData data = lang.Data as IconCursorImageResourceData;

            return(data);
        }
コード例 #2
0
        public static Boolean TryCreate(Boolean isIcon, ResourceLang lang, Byte[] rawData, out IconCursorImageResourceData typed)
        {
            // rawData is an ICONIMAGE structure OR a PNG image

            // if it's a PNG image it's easy enough:
            if (PngImageResourceData.HasPngSignature(rawData))
            {
                Image image;
                if (!ImageResourceData.TryCreateImage(rawData, out image))
                {
                    typed = null; return(false);
                }

                typed = new IconCursorImageResourceData(image, lang, rawData)
                {
                    IsIcon = isIcon
                };
                return(true);
            }

            typed = new IconCursorImageResourceData(lang, rawData)
            {
                IsIcon = isIcon
            };
            return(true);
        }
コード例 #3
0
        public IconCursorImageResourceData FromFileData(ResourceLang lang, Byte[] data, Boolean isIcon)
        {
            IconCursorImageResourceData rd;

            if (IconCursorImageResourceData.TryCreate(isIcon, lang, data, out rd))
            {
                return(rd);
            }

            return(null);
        }
コード例 #4
0
        public static Boolean TryCreate(Boolean isIcon, ResourceLang lang, Byte[] rawData, out String message, out IconCursorImageResourceData typed)
        {
            message = null;

            // rawData is an ICONIMAGE structure OR a PNG image

            // if it's a PNG image it's easy enough:
            if (PngImageResourceData.HasPngSignature(rawData))
            {
                Image image;
                if (!ImageResourceData.TryCreateImage(rawData, out image))
                {
                    typed = null; return(false);
                }

                typed = new IconCursorImageResourceData(IntPtr.Zero, image, lang, rawData)
                {
                    Size = image.Size
                };
                return(true);
            }

            // "Almost" cheating; this uses Win32's icon function, but in a nice way that doesn't break my conceptual model

            // and to think I'd need to manually process the DIB information to extract and recreate Bitmaps

            // although I might want to do that in future if I wanted to display the AND and XOR masks separately

            IntPtr p = Marshal.AllocHGlobal(rawData.Length);

            Marshal.Copy(rawData, 0, p, rawData.Length);

            IntPtr hIcon = NativeMethods.CreateIconFromResource(p, (uint)rawData.Length, isIcon);

            if (hIcon == IntPtr.Zero)
            {
                message = NativeMethods.GetLastErrorString();
                typed   = null;
                return(false);
            }

            Icon icon = Icon.FromHandle(hIcon);

            // because the Icon is born out of unmanaged data I cannot free the handle here; do it in the finaliser
            // on Windows XP x86 this doesn't cause a problem by freeing it here, but on Windows Server 2008 x64 it causes the Icon to fail

            // UPDATE: okay, apparently not. Even after moving that free instruction it still fails on WS2008x64

            typed = new IconCursorImageResourceData(p, icon, lang, rawData);
            return(true);
        }
コード例 #5
0
        public override ResourceData FromResource(ResourceLang lang, Byte[] data)
        {
            IconCursorImageResourceData rd;
            String message;

            if (IconCursorImageResourceData.TryCreate(false, lang, data, out message, out rd))
            {
                return(rd);
            }

            LastErrorMessage = message;

            return(null);
        }
コード例 #6
0
        public override ResourceData FromResource(ResourceLang lang, Byte[] data)
        {
            if (lang == null)
            {
                throw new ArgumentNullException("lang");
            }

            IconCursorImageResourceData rd;

            Boolean isIcon = lang.Name.Type.Identifier.KnownType == Win32ResourceType.IconImage;

            if (IconCursorImageResourceData.TryCreate(isIcon, lang, data, out rd))
            {
                return(rd);
            }

            return(null);
        }
コード例 #7
0
        public static Boolean TryCreateFromRes(ResourceLang lang, Byte[] rawData, out IconDirectoryResourceData typed)
        {
            Int32 sizeOfIconDir = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfDirEntr = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            // the data in here is an ICONDIR structure

            IntPtr p = Marshal.AllocHGlobal(rawData.Length);

            Marshal.Copy(rawData, 0, p, rawData.Length);

            // this could be vastly simplified by correctly marshaling the member array of IconDirectory
            // but that's a can of worms, I'd rather not
            IconDirectory dir = (IconDirectory)Marshal.PtrToStructure(p, typeof(IconDirectory));

            Marshal.FreeHGlobal(p);

            if (dir.wType != 1)
            {
                throw new InvalidOperationException("Provided rawData was not that of an icon's");
            }

            ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                Int32 byteOffset = sizeOfIconDir + sizeOfDirEntr * i;

                p = Marshal.AllocHGlobal(sizeOfDirEntr);
                Marshal.Copy(rawData, byteOffset, p, sizeOfDirEntr);

                ResIconDirectoryEntry img = (ResIconDirectoryEntry)Marshal.PtrToStructure(p, typeof(ResIconDirectoryEntry));

                subImages[i] = img;
            }

            IconDirectoryResourceData retval = new IconDirectoryResourceData(lang, rawData);

            // then we might be able to get the resourcedata for the subimages to include in the directory

            // find the Icon Image resource type
            ResourceType iconType = null;

            foreach (ResourceType type in lang.Name.Type.Source.Types)
            {
                if (type.Identifier.KnownType == Win32ResourceType.IconImage)
                {
                    iconType = type;
                    break;
                }
            }

            if (iconType != null)
            {
                foreach (ResIconDirectoryEntry img in subImages)
                {
                    IconCursorImageResourceData rd = GetDataFromWid(iconType, lang, img.wId);

                    String description = String.Format(
                        Cult.InvariantCulture,
                        "{0}x{1} {2}-bit",
                        img.bWidth == 0 ? 256 : img.bWidth,
                        img.bHeight == 0 ? 256 : img.bHeight,
                        img.wBitCount
                        );

                    retval.UnderlyingMembers.Add(new IconDirectoryMember(description, rd));
                }
            }

            typed = retval;
            return(true);
        }
コード例 #8
0
 internal IconDirectoryMember(String description, IconCursorImageResourceData data)
 {
     Description  = description;
     ResourceData = data;
 }
コード例 #9
0
        public static Boolean TryCreateFromFile(Stream stream, String extension, ResourceSource source, out IconDirectoryResourceData typed)
        {
            typed = null;

            if (extension != "ico")
            {
                throw MEEx(extension);
            }

            if (stream.Length < Marshal.SizeOf(typeof(IconDirectory)))
            {
                return(false);
            }

            BinaryReader rdr = new BinaryReader(stream);

            IconDirectory?tDir = ReadIcoHeader(rdr);

            if (tDir == null)
            {
                return(false);
            }

            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();

            IconCursorImageResourceData[] images = new IconCursorImageResourceData[dir.wCount];
            String[] descs = new String[dir.wCount];

            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);

                images[i] = factory.FromResource(null, data) as IconCursorImageResourceData;

                String description = String.Format(
                    Cult.InvariantCulture,
                    "{0}x{1} {2}-bit",
                    img.bWidth == 0 ? 256 : img.bWidth,
                    img.bHeight == 0 ? 256 : img.bHeight,
                    img.wBitCount
                    );

                descs[i] = description;
            }

            Byte[] reconstructed = ReconstructRawData(dir, subImages, images, source);

            IconDirectoryResourceData retval = new IconDirectoryResourceData(null, reconstructed);

            for (int i = 0; i < images.Length; i++)
            {
                retval.UnderlyingMembers.Add(new IconDirectoryMember(descs[i], images[i]));
            }


            /////////////////////////////

            typed = retval;

            return(true);
        }