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); }
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); }
public IconCursorImageResourceData FromFileData(ResourceLang lang, Byte[] data, Boolean isIcon) { IconCursorImageResourceData rd; if (IconCursorImageResourceData.TryCreate(isIcon, lang, data, out rd)) { return(rd); } return(null); }
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); }
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); }
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); }
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); }
internal IconDirectoryMember(String description, IconCursorImageResourceData data) { Description = description; ResourceData = data; }
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); }