a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
785 lines
16 KiB
C#
785 lines
16 KiB
C#
//
|
|
// System.Resources/Win32Resources.cs
|
|
//
|
|
// Author:
|
|
// Zoltan Varga (vargaz@freemail.hu)
|
|
//
|
|
// (C) 2003 Ximian, Inc. http://www.ximian.com
|
|
//
|
|
// An incomplete set of classes for manipulating Win32 resources
|
|
//
|
|
|
|
//
|
|
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace System.Resources {
|
|
|
|
|
|
internal enum Win32ResourceType {
|
|
RT_CURSOR = 1,
|
|
RT_FONT = 8,
|
|
RT_BITMAP = 2,
|
|
RT_ICON = 3,
|
|
RT_MENU = 4,
|
|
RT_DIALOG = 5,
|
|
RT_STRING = 6,
|
|
RT_FONTDIR = 7,
|
|
RT_ACCELERATOR = 9,
|
|
RT_RCDATA = 10,
|
|
RT_MESSAGETABLE = 11,
|
|
RT_GROUP_CURSOR = 12,
|
|
RT_GROUP_ICON = 14,
|
|
RT_VERSION = 16,
|
|
RT_DLGINCLUDE = 17,
|
|
RT_PLUGPLAY = 19,
|
|
RT_VXD = 20,
|
|
RT_ANICURSOR = 21,
|
|
RT_ANIICON = 22,
|
|
RT_HTML = 23,
|
|
}
|
|
|
|
internal class NameOrId {
|
|
string name;
|
|
int id;
|
|
|
|
public NameOrId (string name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public NameOrId (int id) {
|
|
this.id = id;
|
|
}
|
|
|
|
public bool IsName {
|
|
get {
|
|
return name != null;
|
|
}
|
|
}
|
|
|
|
public string Name {
|
|
get {
|
|
return name;
|
|
}
|
|
}
|
|
|
|
public int Id {
|
|
get {
|
|
return id;
|
|
}
|
|
}
|
|
|
|
public override string ToString () {
|
|
if (name != null)
|
|
return "Name(" + name + ")";
|
|
else
|
|
return "Id(" + id + ")";
|
|
}
|
|
}
|
|
|
|
internal abstract class Win32Resource {
|
|
|
|
NameOrId type;
|
|
NameOrId name;
|
|
int language;
|
|
|
|
internal Win32Resource (NameOrId type, NameOrId name, int language) {
|
|
this.type = type;
|
|
this.name = name;
|
|
this.language = language;
|
|
}
|
|
|
|
internal Win32Resource (Win32ResourceType type, int name, int language) {
|
|
this.type = new NameOrId ((int)type);
|
|
this.name = new NameOrId (name);
|
|
this.language = language;
|
|
}
|
|
|
|
public Win32ResourceType ResourceType {
|
|
get {
|
|
if (type.IsName)
|
|
return (Win32ResourceType)(-1);
|
|
else
|
|
return (Win32ResourceType)type.Id;
|
|
}
|
|
}
|
|
|
|
public NameOrId Name {
|
|
get {
|
|
return name;
|
|
}
|
|
}
|
|
|
|
public NameOrId Type {
|
|
get {
|
|
return type;
|
|
}
|
|
}
|
|
|
|
public int Language {
|
|
get {
|
|
return language;
|
|
}
|
|
}
|
|
|
|
public abstract void WriteTo (Stream s);
|
|
|
|
public override string ToString () {
|
|
return "Win32Resource (Kind=" + ResourceType + ", Name=" + name + ")";
|
|
}
|
|
}
|
|
|
|
//
|
|
// This class represents a Win32 resource in encoded format
|
|
//
|
|
internal class Win32EncodedResource : Win32Resource {
|
|
|
|
byte[] data;
|
|
|
|
internal Win32EncodedResource (NameOrId type, NameOrId name, int language, byte[] data) : base (type, name, language) {
|
|
this.data = data;
|
|
}
|
|
|
|
public byte[] Data {
|
|
get {
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public override void WriteTo (Stream s) {
|
|
s.Write (data, 0, data.Length);
|
|
}
|
|
}
|
|
|
|
//
|
|
// This class represents a Win32 ICON resource
|
|
//
|
|
internal class Win32IconResource : Win32Resource {
|
|
|
|
ICONDIRENTRY icon;
|
|
|
|
public Win32IconResource (int id, int language, ICONDIRENTRY icon) : base (Win32ResourceType.RT_ICON, id, language) {
|
|
this.icon = icon;
|
|
}
|
|
|
|
public ICONDIRENTRY Icon {
|
|
get {
|
|
return icon;
|
|
}
|
|
}
|
|
|
|
public override void WriteTo (Stream s) {
|
|
s.Write (icon.image, 0, icon.image.Length);
|
|
}
|
|
}
|
|
|
|
internal class Win32GroupIconResource : Win32Resource {
|
|
|
|
Win32IconResource[] icons;
|
|
|
|
public Win32GroupIconResource (int id, int language, Win32IconResource[] icons) : base (Win32ResourceType.RT_GROUP_ICON, id, language) {
|
|
this.icons = icons;
|
|
}
|
|
|
|
public override void WriteTo (Stream s) {
|
|
using (BinaryWriter w = new BinaryWriter (s)) {
|
|
w.Write ((short)0);
|
|
w.Write ((short)1);
|
|
w.Write ((short)icons.Length);
|
|
for (int i = 0; i < icons.Length; ++i) {
|
|
Win32IconResource icon = icons [i];
|
|
ICONDIRENTRY entry = icon.Icon;
|
|
|
|
w.Write (entry.bWidth);
|
|
w.Write (entry.bHeight);
|
|
w.Write (entry.bColorCount);
|
|
w.Write ((byte)0);
|
|
w.Write (entry.wPlanes);
|
|
w.Write (entry.wBitCount);
|
|
w.Write ((int)entry.image.Length);
|
|
w.Write ((short)icon.Name.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// This class represents a Win32 VERSION resource
|
|
//
|
|
internal class Win32VersionResource : Win32Resource {
|
|
|
|
public string[] WellKnownProperties = {
|
|
"Comments",
|
|
"CompanyName",
|
|
"FileVersion",
|
|
"InternalName",
|
|
"LegalTrademarks",
|
|
"OriginalFilename",
|
|
"ProductName",
|
|
"ProductVersion"
|
|
};
|
|
|
|
long signature;
|
|
int struct_version;
|
|
long file_version;
|
|
long product_version;
|
|
int file_flags_mask;
|
|
int file_flags;
|
|
int file_os;
|
|
int file_type;
|
|
int file_subtype;
|
|
long file_date;
|
|
|
|
int file_lang;
|
|
int file_codepage;
|
|
|
|
Hashtable properties;
|
|
|
|
public Win32VersionResource (int id, int language, bool compilercontext) : base (Win32ResourceType.RT_VERSION, id, language) {
|
|
// Initialize non-public members to the usual values used in
|
|
// resources
|
|
signature = 0xfeef04bd;
|
|
struct_version = 1 << 16; /* 1.0 */
|
|
file_flags_mask = 63;
|
|
file_flags = 0;
|
|
file_os = 4; /* VOS_WIN32 */
|
|
file_type = 2;
|
|
file_subtype = 0;
|
|
file_date = 0;
|
|
|
|
file_lang = compilercontext ? 0x00 : 0x7f;
|
|
file_codepage = 1200;
|
|
|
|
properties = new Hashtable ();
|
|
|
|
string defaultvalue = compilercontext ? string.Empty : " ";
|
|
|
|
// Well known properties
|
|
foreach (string s in WellKnownProperties)
|
|
// The value of properties can't be empty
|
|
properties [s] = defaultvalue;
|
|
|
|
LegalCopyright = " ";
|
|
FileDescription = " ";
|
|
}
|
|
|
|
public string Version {
|
|
get {
|
|
return
|
|
"" + (file_version >> 48) +
|
|
"." + ((file_version >> 32) & 0xffff) +
|
|
"." + ((file_version >> 16) & 0xffff) +
|
|
"." + ((file_version >> 0) & 0xffff);
|
|
}
|
|
|
|
set {
|
|
long[] ver = new long [4] { 0, 0, 0, 0 };
|
|
if (value != null) {
|
|
string[] parts = value.Split ('.');
|
|
|
|
try {
|
|
for (int i = 0; i < parts.Length; ++i) {
|
|
if (i < ver.Length)
|
|
ver [i] = Int32.Parse (parts [i]);
|
|
}
|
|
} catch (FormatException) {
|
|
}
|
|
}
|
|
|
|
file_version = (ver [0] << 48) | (ver [1] << 32) | (ver [2] << 16) + ver [3];
|
|
properties ["FileVersion"] = Version;
|
|
}
|
|
}
|
|
|
|
public virtual string this [string key] {
|
|
set {
|
|
properties [key] = value;
|
|
}
|
|
}
|
|
|
|
// Accessors for well known properties
|
|
|
|
public virtual string Comments {
|
|
get {
|
|
return (string)properties ["Comments"];
|
|
}
|
|
set {
|
|
properties ["Comments"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string CompanyName {
|
|
get {
|
|
return (string)properties ["CompanyName"];
|
|
}
|
|
set {
|
|
properties ["CompanyName"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string LegalCopyright {
|
|
get {
|
|
return (string)properties ["LegalCopyright"];
|
|
}
|
|
set {
|
|
properties ["LegalCopyright"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string LegalTrademarks {
|
|
get {
|
|
return (string)properties ["LegalTrademarks"];
|
|
}
|
|
set {
|
|
properties ["LegalTrademarks"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string OriginalFilename {
|
|
get {
|
|
return (string)properties ["OriginalFilename"];
|
|
}
|
|
set {
|
|
properties ["OriginalFilename"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string ProductName {
|
|
get {
|
|
return (string)properties ["ProductName"];
|
|
}
|
|
set {
|
|
properties ["ProductName"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string ProductVersion {
|
|
get {
|
|
return (string)properties ["ProductVersion"];
|
|
}
|
|
set {
|
|
if (value == null || value.Length == 0)
|
|
value = " ";
|
|
|
|
long [] ver = new long [4] { 0, 0, 0, 0 };
|
|
|
|
string [] parts = value.Split ('.');
|
|
|
|
try {
|
|
for (int i = 0; i < parts.Length; ++i) {
|
|
if (i < ver.Length)
|
|
ver [i] = Int32.Parse (parts [i]);
|
|
}
|
|
} catch (FormatException) {
|
|
}
|
|
|
|
properties ["ProductVersion"] = value;
|
|
product_version = (ver [0] << 48) | (ver [1] << 32) | (ver [2] << 16) + ver [3];
|
|
}
|
|
}
|
|
|
|
public virtual string InternalName {
|
|
get {
|
|
return (string)properties ["InternalName"];
|
|
}
|
|
set {
|
|
properties ["InternalName"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual string FileDescription {
|
|
get {
|
|
return (string)properties ["FileDescription"];
|
|
}
|
|
set {
|
|
properties ["FileDescription"] = value == String.Empty ? " " : value;
|
|
}
|
|
}
|
|
|
|
public virtual int FileLanguage {
|
|
get { return file_lang; }
|
|
set { file_lang = value; }
|
|
}
|
|
|
|
public virtual string FileVersion {
|
|
get {
|
|
return (string)properties ["FileVersion"];
|
|
}
|
|
set {
|
|
if (value == null || value.Length == 0)
|
|
value = " ";
|
|
|
|
long[] ver = new long [4] { 0, 0, 0, 0 };
|
|
string[] parts = value.Split ('.');
|
|
|
|
try {
|
|
for (int i = 0; i < parts.Length; ++i) {
|
|
if (i < ver.Length)
|
|
ver [i] = Int32.Parse (parts [i]);
|
|
}
|
|
} catch (FormatException) {
|
|
}
|
|
|
|
properties ["FileVersion"] = value;
|
|
file_version = (ver [0] << 48) | (ver [1] << 32) | (ver [2] << 16) + ver [3];
|
|
}
|
|
}
|
|
|
|
private void emit_padding (BinaryWriter w) {
|
|
Stream ms = w.BaseStream;
|
|
|
|
if ((ms.Position % 4) != 0)
|
|
w.Write ((short)0);
|
|
}
|
|
|
|
private void patch_length (BinaryWriter w, long len_pos) {
|
|
Stream ms = w.BaseStream;
|
|
|
|
long pos = ms.Position;
|
|
ms.Position = len_pos;
|
|
w.Write ((short)(pos - len_pos));
|
|
ms.Position = pos;
|
|
}
|
|
|
|
public override void WriteTo (Stream ms)
|
|
{
|
|
using (BinaryWriter w = new BinaryWriter (ms, Encoding.Unicode)) {
|
|
//
|
|
// See the documentation for the VS_VERSIONINFO structure and
|
|
// its children on MSDN
|
|
//
|
|
|
|
// VS_VERSIONINFO
|
|
w.Write ((short)0);
|
|
w.Write ((short)0x34);
|
|
w.Write ((short)0);
|
|
w.Write ("VS_VERSION_INFO".ToCharArray ());
|
|
w.Write ((short)0);
|
|
|
|
emit_padding (w);
|
|
|
|
// VS_FIXEDFILEINFO
|
|
w.Write ((uint)signature);
|
|
w.Write ((int)struct_version);
|
|
w.Write ((int)(file_version >> 32));
|
|
w.Write ((int)((file_version & 0xffffffff)));
|
|
|
|
w.Write ((int)(product_version >> 32));
|
|
w.Write ((int)(product_version & 0xffffffff));
|
|
w.Write ((int)file_flags_mask);
|
|
w.Write ((int)file_flags);
|
|
w.Write ((int)file_os);
|
|
w.Write ((int)file_type);
|
|
w.Write ((int)file_subtype);
|
|
w.Write ((int)(file_date >> 32));
|
|
w.Write ((int)(file_date & 0xffffffff));
|
|
|
|
emit_padding (w);
|
|
|
|
// VarFileInfo
|
|
long var_file_info_pos = ms.Position;
|
|
w.Write ((short)0);
|
|
w.Write ((short)0);
|
|
w.Write ((short)1);
|
|
w.Write ("VarFileInfo".ToCharArray ());
|
|
w.Write ((short)0);
|
|
|
|
if ((ms.Position % 4) != 0)
|
|
w.Write ((short)0);
|
|
|
|
// Var
|
|
long var_pos = ms.Position;
|
|
w.Write ((short)0);
|
|
w.Write ((short)4);
|
|
w.Write ((short)0);
|
|
w.Write ("Translation".ToCharArray ());
|
|
w.Write ((short)0);
|
|
|
|
if ((ms.Position % 4) != 0)
|
|
w.Write ((short)0);
|
|
|
|
w.Write ((short)file_lang);
|
|
w.Write ((short)file_codepage);
|
|
|
|
patch_length (w, var_pos);
|
|
|
|
patch_length (w, var_file_info_pos);
|
|
|
|
// StringFileInfo
|
|
long string_file_info_pos = ms.Position;
|
|
w.Write ((short)0);
|
|
w.Write ((short)0);
|
|
w.Write ((short)1);
|
|
w.Write ("StringFileInfo".ToCharArray ());
|
|
|
|
emit_padding (w);
|
|
|
|
// StringTable
|
|
long string_table_pos = ms.Position;
|
|
w.Write ((short)0);
|
|
w.Write ((short)0);
|
|
w.Write ((short)1);
|
|
w.Write (String.Format ("{0:x4}{1:x4}", file_lang, file_codepage).ToCharArray ());
|
|
|
|
emit_padding (w);
|
|
|
|
// Strings
|
|
foreach (string key in properties.Keys) {
|
|
string value = (string)properties [key];
|
|
|
|
long string_pos = ms.Position;
|
|
w.Write ((short)0);
|
|
w.Write ((short)(value.ToCharArray ().Length + 1));
|
|
w.Write ((short)1);
|
|
w.Write (key.ToCharArray ());
|
|
w.Write ((short)0);
|
|
|
|
emit_padding (w);
|
|
|
|
w.Write (value.ToCharArray ());
|
|
w.Write ((short)0);
|
|
|
|
emit_padding (w);
|
|
|
|
patch_length (w, string_pos);
|
|
}
|
|
|
|
patch_length (w, string_table_pos);
|
|
|
|
patch_length (w, string_file_info_pos);
|
|
|
|
patch_length (w, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal class Win32ResFileReader {
|
|
|
|
Stream res_file;
|
|
|
|
public Win32ResFileReader (Stream s) {
|
|
res_file = s;
|
|
}
|
|
|
|
int read_int16 () {
|
|
int b1 = res_file.ReadByte ();
|
|
if (b1 == -1)
|
|
return -1;
|
|
|
|
int b2 = res_file.ReadByte ();
|
|
if (b2 == -1)
|
|
return -1;
|
|
|
|
return b1 | (b2 << 8);
|
|
}
|
|
|
|
int read_int32 () {
|
|
int w1 = read_int16 ();
|
|
if (w1 == -1)
|
|
return -1;
|
|
int w2 = read_int16 ();
|
|
if (w2 == -1)
|
|
return -1;
|
|
|
|
return w1 | (w2 << 16);
|
|
}
|
|
|
|
private bool read_padding () {
|
|
while ((res_file.Position % 4) != 0){
|
|
if (read_int16 () == -1)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
NameOrId read_ordinal () {
|
|
int i = read_int16 ();
|
|
if ((i & 0xffff) != 0) {
|
|
int j = read_int16 ();
|
|
return new NameOrId (j);
|
|
}
|
|
else {
|
|
byte[] chars = new byte [16];
|
|
int pos = 0;
|
|
|
|
while (true) {
|
|
int j = read_int16 ();
|
|
if (j == 0)
|
|
break;
|
|
if (pos == chars.Length) {
|
|
byte[] new_chars = new byte [chars.Length * 2];
|
|
Array.Copy (chars, new_chars, chars.Length);
|
|
chars = new_chars;
|
|
}
|
|
chars [pos] = (byte)(j >> 8);
|
|
chars [pos + 1] = (byte)(j & 0xff);
|
|
pos += 2;
|
|
}
|
|
|
|
return new NameOrId (new String (Encoding.Unicode.GetChars (chars, 0, pos)));
|
|
}
|
|
}
|
|
|
|
public ICollection ReadResources () {
|
|
ArrayList resources = new ArrayList ();
|
|
|
|
/*
|
|
* We can't use a BinaryReader since we have to keep track of the
|
|
* stream position for padding.
|
|
*/
|
|
|
|
while (true) {
|
|
|
|
if (!read_padding ())
|
|
break;
|
|
|
|
int data_size = read_int32 ();
|
|
|
|
if (data_size == -1)
|
|
/* EOF */
|
|
break;
|
|
|
|
//int header_size =
|
|
read_int32 ();
|
|
NameOrId type = read_ordinal ();
|
|
NameOrId name = read_ordinal ();
|
|
|
|
if (!read_padding ())
|
|
break;
|
|
|
|
//int data_version =
|
|
read_int32 ();
|
|
//int memory_flags =
|
|
read_int16 ();
|
|
int language_id = read_int16 ();
|
|
//int version =
|
|
read_int32 ();
|
|
//int characteristics =
|
|
read_int32 ();
|
|
|
|
if (data_size == 0)
|
|
/* Empty resource entry */
|
|
continue;
|
|
|
|
byte[] data = new byte [data_size];
|
|
if (res_file.Read (data, 0, data_size) != data_size)
|
|
break;
|
|
|
|
resources.Add (new Win32EncodedResource (type, name, language_id, data));
|
|
}
|
|
|
|
return resources;
|
|
}
|
|
}
|
|
|
|
//
|
|
// This class represents one icon image in an .ico file
|
|
//
|
|
internal class ICONDIRENTRY {
|
|
|
|
#pragma warning disable 649
|
|
public byte bWidth;
|
|
public byte bHeight;
|
|
public byte bColorCount;
|
|
public byte bReserved;
|
|
public Int16 wPlanes;
|
|
public Int16 wBitCount;
|
|
public Int32 dwBytesInRes;
|
|
public Int32 dwImageOffset;
|
|
#pragma warning restore 649
|
|
public byte[] image;
|
|
|
|
public override string ToString () {
|
|
return "ICONDIRENTRY (" + bWidth + "x" + bHeight + " " + wBitCount + " bpp)";
|
|
}
|
|
}
|
|
|
|
//
|
|
// This class represents a Reader for Win32 .ico files
|
|
//
|
|
internal class Win32IconFileReader {
|
|
|
|
Stream iconFile;
|
|
|
|
public Win32IconFileReader (Stream s) {
|
|
iconFile = s;
|
|
}
|
|
|
|
public ICONDIRENTRY[] ReadIcons () {
|
|
ICONDIRENTRY[] icons = null;
|
|
|
|
using (BinaryReader r = new BinaryReader (iconFile)) {
|
|
int idReserved = r.ReadInt16 ();
|
|
int idType = r.ReadInt16 ();
|
|
if ((idReserved != 0) || (idType != 1))
|
|
throw new Exception ("Invalid .ico file format");
|
|
long nitems = r.ReadInt16 ();
|
|
|
|
icons = new ICONDIRENTRY [nitems];
|
|
|
|
for (int i = 0; i < nitems; ++i) {
|
|
ICONDIRENTRY entry = new ICONDIRENTRY ();
|
|
|
|
entry.bWidth = r.ReadByte ();
|
|
entry.bHeight = r.ReadByte ();
|
|
entry.bColorCount = r.ReadByte ();
|
|
entry.bReserved = r.ReadByte ();
|
|
entry.wPlanes = r.ReadInt16 ();
|
|
entry.wBitCount = r.ReadInt16 ();
|
|
int dwBytesInRes = r.ReadInt32 ();
|
|
int dwImageOffset = r.ReadInt32 ();
|
|
|
|
/* Read image */
|
|
entry.image = new byte [dwBytesInRes];
|
|
|
|
long pos = iconFile.Position;
|
|
iconFile.Position = dwImageOffset;
|
|
iconFile.Read (entry.image, 0, dwBytesInRes);
|
|
iconFile.Position = pos;
|
|
|
|
/*
|
|
* The wPlanes and wBitCount members in the ICONDIRENTRY
|
|
* structure can be 0, so we set them from the BITMAPINFOHEADER
|
|
* structure that follows
|
|
*/
|
|
|
|
if (entry.wPlanes == 0)
|
|
entry.wPlanes = (short)(entry.image [12] | (entry.image [13] << 8));
|
|
if (entry.wBitCount == 0)
|
|
entry.wBitCount = (short)(entry.image [14] | (entry.image [15] << 8));
|
|
|
|
icons [i] = entry;
|
|
}
|
|
|
|
return icons;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|