Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 public ResourceValue[] GetValues(ResourceType type)
 {
     ResourceValue[] result = new ResourceValue[0];
     if (this.cache.ContainsKey(type))
     {
         result = this.cache[type].ToArray();
     }
     return(result);
 }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }