public static ResIconDir FromFile(Boolean isIcon, Stream stream, UInt16 lang, ResourceSource source) { ResIconDir retval = new ResIconDir(isIcon, lang, source); FromFile(stream, lang, source, retval); return(retval); }
public static ResIconDir FromResource(ResourceLang lang, Byte[] rawBytes) { Int32 sizeOfIconDir = Marshal.SizeOf(typeof(IconDirectory)); Int32 sizeOfDirEntr = Marshal.SizeOf(typeof(ResIconDirectoryEntry)); // the data in here is an ICONDIR structure IntPtr p = Marshal.AllocHGlobal(rawBytes.Length); Marshal.Copy(rawBytes, 0, p, rawBytes.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 && dir.wType != 2) { throw new InvalidOperationException("Provided rawData is not an icon or cursor"); } 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(rawBytes, byteOffset, p, sizeOfDirEntr); ResIconDirectoryEntry img = (ResIconDirectoryEntry)Marshal.PtrToStructure(p, typeof(ResIconDirectoryEntry)); subImages[i] = img; } ResIconDir retval = new ResIconDir(dir.wType == 1, lang.LanguageId, lang.Name.Type.Source); // then we might be able to get the resourcedata for the subimages to include in the directory // find the Icon Image resource type ResourceType imageType = null; Win32ResourceType desired = dir.wType == 1 ? Win32ResourceType.IconImage : Win32ResourceType.CursorImage; foreach (ResourceType type in lang.Name.Type.Source.AllTypes) { if (type.Identifier.KnownType == desired) { imageType = type; break; } } if (imageType != null) { foreach (ResIconDirectoryEntry img in subImages) { IconCursorImageResourceData rd = GetDataFromWid(imageType, lang, img.wId); Size dimensions = new Size(img.bWidth == 0 ? 256 : img.bWidth, img.bHeight == 0 ? 256 : img.bHeight); // cursors might have Height == 0, so it should copy the width rather than being set to 256 retval.Members.Add(new IconDirectoryMember(rd, dimensions, img.bColorCount, img.bReserved, img.wPlanes, img.wBitCount, img.dwBytesInRes)); } } return(retval); }
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); } }