- PR -

Win32リソースについて

投稿者投稿内容
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-17 20:54
こんばんは。

引用:

笊頭刹那さんの書き込み (2005-11-17 19:52) より:

ずばり、RT_GROUP_ICONの値は14です。
#私は、C#とVC++を併用しているので、こういうのはすぐに確認できます。
これが、速攻でわかったのは頭に入っていたから、じゃないですよねいくらなんでも(汗。どうやって調べたのかよろしければ教えていただけませんか?VC++も持っているので(というかVS.netなので)こういうのを自分で調べられると非常に楽なので。



頭には入ってないですよ、さすがにそれは(*^_^*)
やり方は…

VC++のソースコード内で、適当に"RT_GROUP_ICON"と打って、ブラウズすれば定義位置へ移動します。
#私の場合、キーボードスキームがVisul C++ 6になっているのでF12キーを押せば、ブラウズしてくれます。
「ファイル内の検索」をつかって「Visual C++ インクルード ディレクトリ」を検索してもいいでしょう。
#grepツールで、"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Vc7\\PlatformSDK\\Include"ディレクトリ配下を検索しても同じです。

引用:

いろいろありがとうございました、できたorヘ(x_x;)ヘ おてあげ。。。 の状態になったらまたレスします。



私も時間があれば、チャレンジしてみましょうかね。
ズルしてC++を使って(~_~;) こういうのはC++が有利ですから。
私も(もし)できましたらレスしたいと思います。

引用:

# というかオーストラリアにいるんだから英語ぜんぜん大丈夫ですっていえなきゃ駄目だよな…orz


いいですねぇ、オーストラリアかぁ。今頃はもう夏なのかなぁ。
こちら(日本)は寒いです(ブルブル
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-18 05:53
お手上げです、っつーか足まで上げてますorz

教えていただいたリンク先などを読んでいると、どうもリソースとして追加できない理由がリソースデーター構造とファイルデータ構造が微妙に違うからではないか?という結論にたどり着きました(はっきりいってひとつの可能性としてその場合が考えられるという程度です、これが本当に原因かどうかはわかりません)

僕の解釈がただしければこれがアイコンファイルの構造です
参考: http://www5.ocn.ne.jp/~minute/article/vb/a1.html
コード:
1, ICONDIR構造体
2, ICONDIRENTRY構造体 * アイコンの枚数
3, BITMAPINFOHEADER構造体+RGBQUAD構造体
4, 画像データ
5, 透過データ



こっちがリソースデータの構造です
参考: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp
コード:
1, GRPICONDIR構造体
2, GRPICONDIRENTRY構造体 * アイコンの枚数
3, BITMAPINFOHEADER構造体+RGBQUAD構造体
4, 画像データ
5, 透過データ




そこで、Cコードを参考にしながら下記のような構造体を作りました。

※ この構造体の変換が正しいかも僕には分かりませんorz
コード:
	[StructLayout(LayoutKind.Sequential)]
	public struct ICONDIR
	{
		public ushort			idReserved;
		public ushort			idType;
		public ushort			idCount;
		public ICONDIRENTRY	idEntries;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct ICONDIRENTRY
	{
		public byte		bWidth;
		public byte		bHeight;
		public byte		bColorCount;
		public byte		bReserved;
		public ushort		wPlanes;
		public ushort		wBitCount;
		public uint		dwBytesInRes;
		public uint		dwImageOffset;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct BITMAPINFOHEADER
	{
		public uint		biSize;
		public int			biWidth;
		public int			biHeight;
		public ushort		biPlanes;
		public ushort		biBitCount;
		public uint		biCompression;
		public uint		biSizeImage;
		public int			biXPelsPerMeter;
		public int			biYPelsPerMeter;
		public uint		biClrUsed;
		public uint		biClrImportant;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct RGBQUAD
	{
		public byte Blue;
		public byte Green;
		public byte Red;
		public byte Reserved;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct ICONIMAGE
	{
		public BITMAPINFOHEADER		icHeader;
		public RGBQUAD					icColors;
		public byte					icXOR;
		public byte					icAND;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct GRPICONDIR
	{
		public ushort		idReserved;
		public ushort		idType;
		public ushort		idCount;
		public GRPICONDIRENTRY		idEntries;
	}
	[StructLayout(LayoutKind.Sequential)]
	public struct GRPICONDIRENTRY
	{
		public byte		bWidth;
		public byte		bHeight;
		public byte		bColorCount;
		public byte		bReserved;
		public ushort	wPlanes;
		public ushort	wBitCount;
		public uint		dwBytesInRes;
		public ushort	nID;
	}


参考:
http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp

で、ここでストップしてしまったんです。以下の理由から先に進むことができません。


  • 構造体を利用してバイナリファイルを読む方法が分からない。
    VBのころのように構造体を利用してバイナリファイルを読む方法が分かりません、これはシリアライズとは似ていますが多少違います。イメージとして
    コード:
    StructA a;
    StructB b;
    StructC c;
    File.open("sample.bin")
    a=File.Read();
    b=File.Read();
    c=File.Read();
    close()
    


    のようにバイナリファイルから構造体を順番に読み込む方法が分かりません。

  • バイナリ配列を構造体などのデータに変換する方法が分からない。
    byte[]型のデータを独自の構造体などに変換する方法がわかりません、これが分かれば上記の方法がわかるかもしれません(いまは分からないので試せないからなんともいえないが)イメージとしては
    コード:
    byte[] buf = file.ReadBytes(hogehogehoge...);
    StructA = (StructA)buf;
    



  • 独自構造体をバイナリ配列に変換する方法が分からない
    上記の逆版です。APIにデータを渡すときに方法が分からないというやつです。

  • APIに独自データを渡す方法が分からない。
    UpdateResourceではそのデータのポインタを渡すようですが
    コード:
    StructA *pt;
    pt = &structA;
    UpdateResource(...pt,sizeof(StructA)...);
    // UpdateResource(...pt,Marshal.SizeOf(StructA)...);
    


    とするとエラーが出て駄目です(Marshal.SizeOfは試していませんが、Iconでやったところエラーでました、ので使えないかなと推測しています)

  • こういうことがC#で可能なのか?
    これが一番問題です、不可能なのにやってたら馬鹿じゃないですか僕orz
    と、いうか一番いいのがC勉強してDLLつくることですよねorz




あと、コードの参考にしたいので、よろしければC++で「アイコンをファイルから読み込み、そのアイコンをUpdateResourceを使って指定Exeファイルに101で追加する」場合の処理をどなたか書いていただけないでしょうか?C#で開発とはいえC++のコードでも時として非常に参考になることがあるので。

よろしくおねがいします、ここまできたらもう食い下がれないです(笑。
_________________
seed of weed
自作したソフトの公開および刹那が難しい・めんどくさい・覚えられないと思った特殊なC#Tipsを公開しています。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-18 06:58
おはようございます。

あら、笊頭刹那さん行き詰ってしまいましたかぁ…
私はもう、アイコンリソースの追加プログラム(サンプル)ができあがりましたよ(^^)v
C++ですけれど。

これから、ソースファイルをコピペ投下しますので、参考にしてみてください。
それで分からないことがあったら、再度質問してください。

#あらかじめ謝っておきます。汚いコードです。
#エラー処理も入っていません。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-18 07:02
では、投下します。

コード:
// InjectIcon.cpp

#include <windows.h>
#include <assert.h>

//////////// 構造体定義 ////////////

typedef struct
{
    WORD           idReserved;   // Reserved (must be 0)
    WORD           idType;       // Resource Type (1 for icons)
    WORD           idCount;      // How many images?
//    ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
} ICONDIR, *LPICONDIR;

typedef struct
{
    BYTE        bWidth;          // Width, in pixels, of the image
    BYTE        bHeight;         // Height, in pixels, of the image
    BYTE        bColorCount;     // Number of colors in image (0 if >=8bpp)
    BYTE        bReserved;       // Reserved ( must be 0)
    WORD        wPlanes;         // Color Planes
    WORD        wBitCount;       // Bits per pixel
    DWORD       dwBytesInRes;    // How many bytes in this resource?
    DWORD       dwImageOffset;   // Where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY;

#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
   BYTE   bWidth;               // Width, in pixels, of the image
   BYTE   bHeight;              // Height, in pixels, of the image
   BYTE   bColorCount;          // Number of colors in image (0 if >=8bpp)
   BYTE   bReserved;            // Reserved
   WORD   wPlanes;              // Color Planes
   WORD   wBitCount;            // Bits per pixel
   DWORD   dwBytesInRes;         // how many bytes in this resource?
   WORD   nID;                  // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
#pragma pack( pop )

//////////// クラス定義 ////////////

// アイコンファイルクラス
class IconFile
{
private:
	ICONDIR			_iconDir;			// アイコンディレクトリ
	ICONDIRENTRY*	_iconEntry;			// アイコンディレクトリエントリ
	BYTE**			_iconImage;			// イメージデータの配列
	BYTE*			_iconGroupData;		// イメージグループデータ

public:

	// コンストラクタ
	IconFile()
	{
		memset(&_iconDir, 0, sizeof(_iconDir));
		_iconEntry = NULL;
		_iconImage = NULL;
		_iconGroupData = NULL;
	}

	// デストラクタ
	~IconFile()
	{
		if (_iconImage)
		{
			for (int i = 0; i < _iconDir.idCount; i++)
			{
				delete _iconImage[i];
			}
		}
		delete _iconImage;
		delete _iconEntry;
		delete _iconGroupData;
	}

	// アイコンの持つイメージの数を取得する
	int GetImageCount() const
	{
		return _iconDir.idCount;
	}

	// index番目のイメージデータを取得する
	BYTE* GetImageData(int index) const
	{
		assert(0 <= index && index < GetImageCount());
		assert(_iconImage != NULL);
		return _iconImage[index];
	}

	// index番目のイメージサイズを取得する
	DWORD GetImageSize(int index) const
	{
		assert(0 <= index && index < GetImageCount());
		assert(_iconEntry != NULL);
		return _iconEntry[index].dwBytesInRes;
	}

	// アイコンファイルをロードする
	void Load(LPCTSTR pszFileName)
	{
		// アイコンファイルのオープン
		HANDLE hFile = ::CreateFile(pszFileName, GENERIC_READ,
			0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		assert(hFile != INVALID_HANDLE_VALUE);

		DWORD dwRead;

		// ICONDIR部分の読み込み
		assert(
			::ReadFile(hFile, &_iconDir, sizeof(ICONDIR), &dwRead, NULL) != FALSE
		);

		// ICONDIRの内容確認
		assert(_iconDir.idReserved == 0);
		assert(_iconDir.idType == 1);
		assert(_iconDir.idCount > 0);

		// ICONDIRENTRYの読み込み
		_iconEntry = new ICONDIRENTRY[_iconDir.idCount];
		for (int i = 0; i < _iconDir.idCount; i++)
		{
			assert(
				::ReadFile(hFile, &(_iconEntry[i]), sizeof(ICONDIRENTRY), &dwRead, NULL)
					!= FALSE
			);
		}

		// イメージデータの読み込み
		_iconImage = new BYTE*[_iconDir.idCount];
		for (i = 0; i < _iconDir.idCount; i++)
		{
			::SetFilePointer(hFile, _iconEntry[i].dwImageOffset, NULL, FILE_BEGIN);

			_iconImage[i] = new BYTE[_iconEntry[i].dwBytesInRes];
			assert(
				::ReadFile(hFile, _iconImage[i], _iconEntry[i].dwBytesInRes, &dwRead, NULL)
					 != FALSE
			);
		}

		::CloseHandle(hFile);
	}

	// アイコングループデータのサイズ取得
	int SizeOfIconGroupData() const
	{
		return sizeof(ICONDIR) + sizeof(GRPICONDIRENTRY) * GetImageCount();
	}

	// アイコングループデータの作成(nBaseIDはRT_ICONの基底インデックス番号)
	BYTE* CreateIconGroupData(int nBaseID)
	{
		delete _iconGroupData;

		// アイコングループデータの領域確保
		_iconGroupData = new BYTE[SizeOfIconGroupData()];

		// アイコングループディレクトリを書き込む
		memcpy(_iconGroupData, &_iconDir, sizeof(ICONDIR));

		int offset = sizeof(ICONDIR);
		for (int i = 0; i < GetImageCount(); i++) {

			GRPICONDIRENTRY grpEntry;

			// イメージデータからBITMAPINFOHEADER取得
			BITMAPINFOHEADER bitmapheader;
			memcpy(&bitmapheader, GetImageData(i), sizeof(BITMAPINFOHEADER));

			// アイコングループエントリ作成
			grpEntry.bWidth			= _iconEntry[i].bWidth;
			grpEntry.bHeight		= _iconEntry[i].bHeight;
			grpEntry.bColorCount	= _iconEntry[i].bColorCount;
			grpEntry.bReserved		= _iconEntry[i].bReserved;
			grpEntry.wPlanes		= bitmapheader.biPlanes;
			grpEntry.wBitCount		= bitmapheader.biBitCount;
			grpEntry.dwBytesInRes	= _iconEntry[i].dwBytesInRes;
			grpEntry.nID			= nBaseID + i;

			// アイコングループエントリを書き込む
			memcpy(_iconGroupData + offset, &grpEntry, sizeof(GRPICONDIRENTRY));

			offset += sizeof(GRPICONDIRENTRY);
		}

		return _iconGroupData;
	}
};


//////////// 関数定義 ////////////

// アイコンリソースを実行可能ファイルへ追加する
void InjectIcon(LPCTSTR pszExecutableFile, LPCTSTR pszIconFile,
	 UINT nIconGroupID, UINT nIconBaseID)
{
	// アイコンファイルの読み込み
	IconFile iconFile;
	iconFile.Load(pszIconFile);

	// リソースの更新開始
	HANDLE hUpdate = ::BeginUpdateResource(pszExecutableFile, FALSE);
	assert(hUpdate != NULL);

	// RT_GROUP_ICON 書き込み
	assert(
		::UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(nIconGroupID), 0,
			iconFile.CreateIconGroupData(nIconBaseID), iconFile.SizeOfIconGroupData())
		 != FALSE
	);

	// RT_ICON書き込み
	for (int i = 0; i < iconFile.GetImageCount(); i++) {
		assert(
			::UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(nIconBaseID+i), 0,
				iconFile.GetImageData(i), iconFile.GetImageSize(i))
			 != FALSE
		);
	}

	// リソースの更新終了
	::EndUpdateResource(hUpdate, FALSE);
}

void main()
{
	// アイコンの追加

	// TODO: 環境に合わせてパラメータを変更してください。
	InjectIcon("c:\\\\hoge\\\\hoge.exe", "c:\\\\hoge\\\\icon1.ico", 1000, 1000);
}


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-18 07:06
ついでに、ReadMeもつけちゃいます。

引用:

InjectIconサンプルプログラムについて

【コンパイラ】
Visual C++.NET 2003

【ビルド方法】
1.[プロジェクトの作成]-[Visual C++プロジェクト]-[Win32 コンソールプロジェクト]
  で、コンソールアプリケーションを作成します。
2.[ソリューションエクスプローラ]の「ソースファイル」「ヘッダファイル」を全て削除します。
3.[既存項目の追加]で"InjectIcon.cpp"をプロジェクトに追加します。
4.[ソリューションエクスプローラ]で"InjectIcon.cpp"を選択し[プロパティ]を表示します。
  [プリコンパイル済みヘッダ]-[プリコンパイル済みヘッダの作成/使用]で「使用しない」を設定します。
5.[ソリューションのビルド]で、プロジェクトをビルドします。

【InjectIcon.cppファイルの編集】
main関数内で呼んでいるInjectIcon関数のパラメータを、ご自身のPC環境に合わせて変更します。
具体的には、「実行可能ファイルパス」や「アイコンファイルパス」を変更します。

【注意事項】
このプログラムはサンプルのため、正常系でのみの動作です。
(エラー処理を加えると、コード量が増えてしまいますので)
一応、異常が発生するとアサーションメッセージが表示されるようになっております。


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-18 11:58
笊頭刹那、こんにちは。

今朝のC++コードをC#に移植しました!
.NET(C#)素人には、しんどかったぁ〜(>_<)

#醜いコードですがよろしかった、見てみてください。

では、全ソースコード投下します。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-18 12:05
では、投下です。

*** アイコンリソース追加 サンプルプログラム ***

【コンパイラ】
Visual C# 2003

【ビルド方法】
下記のソースファイルを、"/unsafe"オプションをつけてビルドしてください。
IconInjector.cs
IconFile.cs


コード:
// IconInjector.cs

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace TestApp
{

	/// <summary>
	/// IconInjectorクラスの定義
	/// </summary>
	class IconInjector
	{

		[DllImport("kernel32.dll", SetLastError=true)]
			//static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
		static extern int UpdateResource(IntPtr hUpdate, uint lpType, uint lpName, ushort wLanguage, byte[] lpData, uint cbData);

		[DllImport("kernel32.dll", SetLastError=true)]
		static extern IntPtr BeginUpdateResource(string pFileName,
			[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);

		[DllImport("kernel32.dll", SetLastError=true)]
		static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);

		/// <summary>
		/// アプリケーションのメイン エントリ ポイントです。
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{

			// アイコンの追加

			// TODO: 環境に合わせてパラメータを変更してください。
			InjectIcon("c:\\\\\\\\hoge\\\\\\\\hoge.exe", "c:\\\\\\\\hoge\\\\\\\\icon1.ico", 1000, 1000);
		}

		static void InjectIcon(string execFileName, string iconFileName, uint iconGroupID, uint iconBaseID)
		{
			const uint RT_ICON = 3;
			const uint RT_GROUP_ICON = 14;

			// アイコンファイルの読み込み
			IconFile iconFile = new IconFile();
			iconFile.Load(iconFileName);

			// リソースの更新開始
			IntPtr hUpdate = BeginUpdateResource(execFileName, false);
			Debug.Assert(hUpdate != IntPtr.Zero);

			// RT_GROUP_ICON 書き込み
			byte[] data = iconFile.CreateIconGroupData(iconBaseID);
			UpdateResource(hUpdate, RT_GROUP_ICON, iconGroupID, 0, data, (uint)data.Length);

			// RT_ICON書き込み
			for (int i = 0; i < iconFile.GetImageCount(); i++) 
			{
				byte[] image = iconFile.GetImageData(i);
				UpdateResource(hUpdate, RT_ICON, (uint)(iconBaseID+i), 0, image, (uint)image.Length);
			}

			// リソースの更新終了
			EndUpdateResource(hUpdate, false);

		}
	}
}




コード:
// IconFile.cs

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;

namespace TestApp
{
	[StructLayout(LayoutKind.Sequential)]
	public struct ICONDIR
	{
		public ushort			idReserved;
		public ushort			idType;
		public ushort			idCount;
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct ICONDIRENTRY
	{
		public byte		bWidth;
		public byte		bHeight;
		public byte		bColorCount;
		public byte		bReserved;
		public ushort	wPlanes;
		public ushort	wBitCount;
		public uint		dwBytesInRes;
		public uint		dwImageOffset;
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct BITMAPINFOHEADER
	{
		public uint		biSize;
		public int		biWidth;
		public int		biHeight;
		public ushort	biPlanes;
		public ushort	biBitCount;
		public uint		biCompression;
		public uint		biSizeImage;
		public int		biXPelsPerMeter;
		public int		biYPelsPerMeter;
		public uint		biClrUsed;
		public uint		biClrImportant;
	}

	[StructLayout(LayoutKind.Sequential, Pack=2)]
	public struct GRPICONDIRENTRY
	{
		public byte		bWidth;
		public byte		bHeight;
		public byte		bColorCount;
		public byte		bReserved;
		public ushort	wPlanes;
		public ushort	wBitCount;
		public uint		dwBytesInRes;
		public ushort	nID;
	}


	/// <summary>
	/// IconFile の概要の説明です。
	/// </summary>
	public class IconFile
	{
		ICONDIR _iconDir = new ICONDIR();
		ArrayList _iconEntry = new ArrayList();		
		ArrayList _iconImage = new ArrayList();

		public IconFile()
		{
		}

		// アイコンの持つイメージの数を取得する
		public int GetImageCount()
		{
			return _iconDir.idCount;
		}

		// index番目のイメージデータを取得する
		public byte[] GetImageData(int index)
		{
			Debug.Assert(0 <= index && index < GetImageCount());
			return (byte[])_iconImage[index];
		}

		// アイコンファイルをロードする
		public unsafe void Load(string fileName)
		{
			FileStream fs = null;
			BinaryReader br = null;
			byte[] buffer = null;
			
			try 
			{
				// アイコンファイルのオープン
				fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
				br = new BinaryReader(fs);

				// ICONDIR部分の読み込み
				buffer = br.ReadBytes(sizeof(ICONDIR));
				fixed (ICONDIR* ptr = &_iconDir) 
				{
					Marshal.Copy(buffer, 0, (IntPtr)ptr, sizeof(ICONDIR));
				}

				// ICONDIRの内容確認
				Debug.Assert(_iconDir.idReserved == 0);
				Debug.Assert(_iconDir.idType == 1);
				Debug.Assert(_iconDir.idCount > 0);


				// ICONDIRENTRYの読み込み
				for (int i = 0; i < _iconDir.idCount; i++) 
				{
					ICONDIRENTRY entry = new ICONDIRENTRY();
					buffer = br.ReadBytes(sizeof(ICONDIRENTRY));
					ICONDIRENTRY* ptr = &entry;
					{
						Marshal.Copy(buffer, 0, (IntPtr)ptr, sizeof(ICONDIRENTRY));
					}

					_iconEntry.Add(entry);
				}

				// イメージデータの読み込み
				for (int i = 0; i < _iconDir.idCount; i++)
				{
					fs.Position = ((ICONDIRENTRY)_iconEntry[i]).dwImageOffset;
					byte[] img = br.ReadBytes((int)((ICONDIRENTRY)_iconEntry[i]).dwBytesInRes);
					_iconImage.Add(img);
				}

				byte[] b = (byte[])_iconImage[0];

			}
			catch (Exception ex)
			{
				Debug.Assert(false);
			}
			finally
			{
				if (br != null) 
				{
					br.Close();
				}
				if (fs != null) 
				{
					fs.Close();
				}
			}
		}

		// アイコングループデータのサイズ取得
		unsafe int SizeOfIconGroupData()
		{
			return sizeof(ICONDIR) + sizeof(GRPICONDIRENTRY) * GetImageCount();
		}

		// アイコングループデータの作成(nBaseIDはRT_ICONの基底インデックス番号)
		public unsafe byte[] CreateIconGroupData(uint nBaseID)
		{
			// アイコングループデータの領域確保
			byte[] data = new byte[SizeOfIconGroupData()];

			// アイコングループディレクトリを書き込む
			fixed (ICONDIR* ptr = &_iconDir) 
			{
				Marshal.Copy((IntPtr)ptr, data, 0, sizeof(ICONDIR));
			}

			int offset = sizeof(ICONDIR);

			for (int i = 0; i < GetImageCount(); i++) 
			{
				GRPICONDIRENTRY grpEntry = new GRPICONDIRENTRY();
				BITMAPINFOHEADER bitmapheader = new BITMAPINFOHEADER();

				// イメージデータからBITMAPINFOHEADER取得
				BITMAPINFOHEADER* ptr = &bitmapheader;
				{
					Marshal.Copy(GetImageData(i), 0, (IntPtr)ptr, sizeof(BITMAPINFOHEADER));
				}

				// アイコングループエントリ作成
				grpEntry.bWidth			= ((ICONDIRENTRY)_iconEntry[i]).bWidth;
				grpEntry.bHeight		= ((ICONDIRENTRY)_iconEntry[i]).bHeight;
				grpEntry.bColorCount	= ((ICONDIRENTRY)_iconEntry[i]).bColorCount;
				grpEntry.bReserved		= ((ICONDIRENTRY)_iconEntry[i]).bReserved;
				grpEntry.wPlanes		= bitmapheader.biPlanes;
				grpEntry.wBitCount		= bitmapheader.biBitCount;
				grpEntry.dwBytesInRes	= ((ICONDIRENTRY)_iconEntry[i]).dwBytesInRes;
				grpEntry.nID			= (ushort)(nBaseID + i);

				// アイコングループエントリを書き込む
				GRPICONDIRENTRY* ptr2 = &grpEntry;
				{
					Marshal.Copy((IntPtr)ptr2, data, offset, Marshal.SizeOf(grpEntry));
				}

				offset += sizeof(GRPICONDIRENTRY);
			}

			return data;
		}

	}
}



笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-18 14:51
うぁぁぁぁぁなんですかあなた、神ですか!?
もう結婚してください(笑。

実験したらうまくいきました、これからやっていることの解析入りたいと思います。

こころの奥底からビッグバーン級の感謝です、ありがとうございました!
_________________
seed of weed
自作したソフトの公開および刹那が難しい・めんどくさい・覚えられないと思った特殊なC#Tipsを公開しています。

スキルアップ/キャリアアップ(JOB@IT)