private MemoryStream GetBitmapResource(ResourceValue name) { // Bitmap resources are saved either as DIB or DDB bitmaps and // therefore it is quite ok to use Win-API function LoadBitmap(). // See also http://support.microsoft.com/kb/67883/de. // TODO: Use GetBinaryResource() instead of LoadBitmap(). // Because the bitmap returned by function LoadBitmap() seems // to be loaded with wrong colors. // REMARK: Using LoadImage() instead produces almost the same result! // And therefore it makes no sense to use this function. MemoryStream result = new MemoryStream(); IntPtr hBitmap = ResourcesLocator.LoadBitmap(this.hModule, name.Value); if (hBitmap != IntPtr.Zero) { Bitmap bitmap = Image.FromHbitmap(hBitmap); if (bitmap != null) { bitmap.Save(result, ImageFormat.Bmp); } ResourcesLocator.DeleteObject(hBitmap); result.Position = 0; } return(result); }
private byte[] GetBinaryResource(ResourceType type, ResourceValue name) { // Writing a general function to handle resource loading based on // functions FindResource(), LoadResource() etc. is not really // easy because of the returned handle HGLOBAL is a pointer to // resource depending structures that contain additional resource // type depending information and not the resource information // directly! For example see loading an icon resource under // http://www.codeproject.com/Tips/62005/Extracting-A-Particular-Icon-From-an-ICO-Resource.aspx // But the code below should work for custom resources like PNG, // XML etc. byte[] result = new byte[0]; IntPtr hInfo = ResourcesLocator.FindResource(this.hModule, name.Value, type.Value); if (hInfo != IntPtr.Zero) { int size = ResourcesLocator.SizeofResource(this.hModule, hInfo); IntPtr hResource = ResourcesLocator.LoadResource(this.hModule, hInfo); if (hResource != IntPtr.Zero) { result = new byte[size]; IntPtr hLock = ResourcesLocator.LockResource(hResource); if (hLock != IntPtr.Zero) { Marshal.Copy(hLock, result, 0, size); } } } return(result); }
public ResourceValue[] GetValues(ResourceType type) { ResourceValue[] result = new ResourceValue[0]; if (this.cache.ContainsKey(type)) { result = this.cache[type].ToArray(); } return(result); }
private MemoryStream GetStringResource(ResourceValue name) { MemoryStream result = new MemoryStream(); ResourceType type = new ResourceType(ResourceTypes.RT_STRING); byte[] buffer = this.GetBinaryResource(type, name); if (buffer.Length > 0) { BinaryWriter writer = new BinaryWriter(result); char[] helper = Encoding.Unicode.GetString(buffer).ToCharArray(); int offset = 0; for (int index = 0; index < 16; index++) { if (helper[offset] != 0) { int length = helper[offset]; // GetWord() // String length in characters offset++; if (length > 0) { int stringID = (name.Value.ToInt32() - 1) * 16 + index; writer.Write(stringID); writer.Write(length); for (int inner = offset; inner < offset + length; inner++) { writer.Write(helper[inner]); } } offset += length; } else { offset++; } } result.Position = 0; } return(result); }
private MemoryStream GetIconResource(ResourceValue name) { // This function is based on code written by Tsuda Kageyu. // Many thanks to him! For more information see code sample // under http://www.codeproject.com/KB/cs/IconExtractor.aspx. const int NEWHEADER = 6; // sizeof(NEWHEADER) const int ICONRESDIR = 16; // sizeof(ICONRESDIR) const int GROUPRESDIR = 14; // sizeof(GROUPRESDIR) ResourceType group = new ResourceType(ResourceTypes.RT_GROUP_ICON); ResourceType entry = new ResourceType(ResourceTypes.RT_ICON); MemoryStream result = new MemoryStream(); byte[] groupBuffer = this.GetBinaryResource(group, name); if (groupBuffer.Length > 0) { BinaryWriter writer = new BinaryWriter(result); int count = BitConverter.ToUInt16(groupBuffer, 4); int offset = NEWHEADER + ICONRESDIR * count; writer.Write(groupBuffer, 0, NEWHEADER); for (int index = 0; index < count; index++) { writer.BaseStream.Seek(NEWHEADER + ICONRESDIR * index, SeekOrigin.Begin); writer.Write(groupBuffer, NEWHEADER + GROUPRESDIR * index, ICONRESDIR - 4); writer.Write(offset); IntPtr iconID = (IntPtr)BitConverter.ToUInt16(groupBuffer, NEWHEADER + GROUPRESDIR * index + 12); byte[] imageBuffer = this.GetBinaryResource(entry, new ResourceValue(iconID)); writer.BaseStream.Seek(offset, SeekOrigin.Begin); writer.Write(imageBuffer, 0, imageBuffer.Length); offset += imageBuffer.Length; } result.Position = 0; } return(result); }
public MemoryStream GetResource(ResourceType type, ResourceValue name) { MemoryStream result = null; if (this.hModule != IntPtr.Zero) { if (type.Type == ResourceTypes.RT_BITMAP) { result = this.GetBitmapResource(name); } else if (type.Type == ResourceTypes.RT_GROUP_ICON || type.Type == ResourceTypes.RT_ICON) { // Resource icons consisting of an icon group on this calling level! result = this.GetIconResource(name); } else if (type.Type == ResourceTypes.RT_GROUP_CURSOR || type.Type == ResourceTypes.RT_CURSOR) { // Resource icons consisting of an icon group on this calling level! result = this.GetCursorResource(name); } else if (type.Type == ResourceTypes.RT_STRING) { result = this.GetStringResource(name); } else if (type.Type == ResourceTypes.RT_VERSION) { // Simply return as binary data. result = new MemoryStream(this.GetBinaryResource(type, name)); } else { result = new MemoryStream(this.GetBinaryResource(type, name)); } } return(result); }
private MemoryStream GetCursorResource(ResourceValue name) { // Implementing this function made a lot pain in the ass! // This is because of that class Cursor does not eat streams // with data comming from a resource! This class only likes // such streams in the cursour file format (file type *.cur). // Not a problem?!? Indeed, it is a problem, because resource // format for cursors differs from cursor file format! Further // but not complete information about cursors can be found // under http://msdn.microsoft.com/en-us/library/ms646975.aspx // Conclusion: It was a very long way! const int NEWHEADER = 6; // sizeof(NEWHEADER) const int CURSORDIR = 16; // sizeof(CURSORDIR) const int LOCALHEADER = 4; // sizeof(LOCALHEADER) ResourceType group = new ResourceType(ResourceTypes.RT_GROUP_CURSOR); ResourceType entry = new ResourceType(ResourceTypes.RT_CURSOR); MemoryStream result = new MemoryStream(); MemoryStream images = new MemoryStream(); // Temporary buffer to hold image data. byte[] groupBuffer = this.GetBinaryResource(group, name); if (groupBuffer.Length > 0) { BinaryWriter groupWriter = new BinaryWriter(result); BinaryReader groupReader = new BinaryReader(new MemoryStream(groupBuffer)); // Read NEWHEADER data. ushort idReserved = groupReader.ReadUInt16(); ushort idType = groupReader.ReadUInt16(); ushort idCount = groupReader.ReadUInt16(); // Data offset within cursor file. ushort offset = (ushort)(NEWHEADER + CURSORDIR * idCount); // Write NEWHEADER data. groupWriter.Write(idReserved); // Must be 0. groupWriter.Write(idType); // Must be 2 for cursors! groupWriter.Write(idCount); // Number of cursor "images". for (int index = 0; index < idCount; index++) { // Read CURSORDIR data. ushort wWidth = groupReader.ReadUInt16(); ushort wHeight = groupReader.ReadUInt16(); ushort wPlanes = groupReader.ReadUInt16(); ushort wBitCount = groupReader.ReadUInt16(); uint dwBytesInRes = groupReader.ReadUInt32(); ushort wImageOffset = groupReader.ReadUInt16(); byte[] imageBuffer = this.GetBinaryResource(entry, new ResourceValue(new IntPtr(wImageOffset))); if (imageBuffer.Length > 0) { BinaryReader imageReader = new BinaryReader(new MemoryStream(imageBuffer)); // Read LOCALHEADER data. ushort wXHotSpot = imageReader.ReadUInt16(); ushort wYHotSpot = imageReader.ReadUInt16(); // Adapt resource data to fit cursor file data needs! byte bWidth = (byte)wWidth; byte bHeight = (byte)(wHeight / 2); // Recalc if odd! byte bColorCount = 0; byte bReserved = 0; ushort wPadding = 0; // Planes and BitCount are used as HotSpot information instead! wPlanes = wXHotSpot; wBitCount = wYHotSpot; // HotSpot information have to be removed from image buffer! dwBytesInRes = dwBytesInRes - LOCALHEADER; // 4 bytes of HotSpot! // Write new CURSORDIR data. groupWriter.Write(bWidth); groupWriter.Write(bHeight); groupWriter.Write(bColorCount); groupWriter.Write(bReserved); groupWriter.Write(wPlanes); groupWriter.Write(wBitCount); groupWriter.Write(dwBytesInRes); groupWriter.Write(offset); groupWriter.Write(wPadding); // Recalculate next offset. offset += (ushort)(dwBytesInRes); // Append current image data at the temporary buffer. images.Write(imageBuffer, LOCALHEADER, (int)dwBytesInRes); } } // Now append all image data at once at the result buffer. groupWriter.Write(images.ToArray(), 0, (int)images.Length); // Return to the result stream's start position. result.Position = 0; } return(result); }