環境
VC++.NET 2003 Windows フォームアプリケーション(マネージ)プロジェクト
表題の通りなのですが、
アイコンファイルをリソースの「Icon」にインポートし、IDを
「IDI_ICON_DATA」と任意に指定したのですが、
リソース上のアイコンデータ(IDI_ICON_DATA)をプログラムから
読み込む方法が分かりません。
LoadIconで強引にやってもエラーになり、おそらく
.NET Frameworkのクラスで操作出来るのではないかと思い質問しました。
どなたかおわかりになりましたらご教授よろしくお願いします。
あっ、すいません、アイコンデータはピクチャーボックスに
表示しようとしてます。よろしくお願いします。
1.windows.h,resource.h をインクルード,user32.libをリンクします。
2.インスタンスハンドルを取得します。
3.LoadIcon関数で、リソースからアイコンハンドルを取得します。
4.System::Drawing::Icon::FromHandleメソッドでIconオブジェクトを作成します。
5.IconオブジェクトのToBitmapメソッドでPictureBoxのImageプロパティに設定しま
す。
といった手順でしょうか。
VC.NET はもっていないので VS2005で確認したソースです。
IDI_ICON1をロードする例)
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
// インスタンスハンドルを取得
Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
HINSTANCE hInst= ( HINSTANCE )Marshal::GetHINSTANCE( m ).ToPointer();
// リソースから読み込み
HICON hIcon = ::LoadIcon( hInst, MAKEINTRESOURCE( IDI_ICON1 ) );
// アイコンオブジェクトの作成
Drawing::Icon^ myIcon = Drawing::Icon::FromHandle( IntPtr( hIcon ) );
// ピクチャボックスに設定
this->pictureBox1->Image = myIcon->ToBitmap();
// アイコンハンドルを破棄
::DestroyIcon( hIcon );
上記のコードをMC++(VC.NET用)にするには ^ を * にするだけでいいと思う。
ちなみに上の方法はWin32リソースの場合。
> アイコンファイルをリソースの「Icon」にインポートし、IDを
> 「IDI_ICON_DATA」と任意に指定したのですが、
から Win32リソースだと予想しました。
アセンブリリソースのやり方というか、どうやってプロジェクトにアセンブリリソース
を埋め込むのか良くわからない。orz
プロジェクトツリーで項目の追加から「アセンブリ リソース ファイル」(resx)を追加
して、Icon1.icoを入れて、下記のソースをForm1_Loadに書いてコンパイルしているので
すが、
// 現在のコードを実行しているAssemblyを取得
Assembly^ myAssembly = Assembly::GetExecutingAssembly();
// このアセンブリの全てのリソース名を取得する
array< String^ >^ resources = myAssembly->GetManifestResourceNames();
// リソース名を一つずつ表示する
for each (String^ resource in resources)
MessageBox::Show(resource);
Icon1.ico のリソースが見つからない、、、
なにか作業が足りないっぽい。(プロジェクトの設定等良くわからない)
参考)
画像やテキストファイルを実行ファイルに埋め込む
http://dobon.net/vb/dotnet/programing/bitmapresource.html
>// インスタンスハンドルを取得
>Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
>HINSTANCE hInst= ( HINSTANCE )Marshal::GetHINSTANCE( m ).ToPointer();
>// リソースから読み込み
>HICON hIcon = ::LoadIcon( hInst, MAKEINTRESOURCE( IDI_ICON1 ) );
>// アイコンオブジェクトの作成
>Drawing::Icon^ myIcon = Drawing::Icon::FromHandle( IntPtr( hIcon ) );
>// ピクチャボックスに設定
>this->pictureBox1->Image = myIcon->ToBitmap();
>// アイコンハンドルを破棄
>::DestroyIcon( hIcon );
Blueさんどうもありがとうございます。
おかげさまで出来ました。大変勉強になります。
ただ、Windowsコントロールライブラリのプロジェクトで
作成したdllでは上記コードではインスタンスがNULLになってしまいます。
これはdllでWindowsフォームを作成しているからでしょうか?
(dll内のWindowsフォームにピクチャーボックスを貼り付けて
そこにアイコンを表示しようとしている→このdllは各プロジェクト共通で
使用するフォームです)
その場合はどのような処理に変更すれば宜しいのでしょうか?
度々すみませんがご教授よろしくお願いします。
> 作成したdllでは上記コードではインスタンスがNULLになってしまいます。
どこがNULLになりますか?HINSTANCE?HINSTANCE?
予想としては、
> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
がまずいかも。
(DLLの場合、実行しているのはDLLではなくDLLを呼んでいるアプリになるので、
0番目ではないんじゃないかな?)
ただいま、VS2005すらないので、何も試すことができません。
ですので、まともな回答はつけれません。
夜(もしくは明日の夜以降)であれば、試して見ることはできます。
(気分によるので期待はしないでください)
# C#やVBで作った Windows コントロール ライブラリ だったら
# (Win32リソースではなくマネージドリソースなので)簡単にできるのかも。
## よって、マネージドリソースをMC++(C++/CLI)で使う方法がわかれば簡単かも。
訂正)
>どこがNULLになりますか?HINSTANCE?HINSTANCE?
どこがNULLになりますか?HINSTANCE?HICON?
Blueさん、レスありがとうございます。
>どこがNULLになりますか?HINSTANCE?HICON?
HICONです。
>予想としては、
>> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
>がまずいかも。
と言うヒントを頂き、ちょっといろいろ試してみた結果、
うまくいきました!!
Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
を
Module^ m = Assembly::GetExecutingAssembly()->GetModules()[ 0 ];
に変えたらDLL内のフォームのアイコン描画が出来ました。
(果たしてこれでよいのかは不安ですが→たまたま動いているだけかも・・・・)
よって一応解決とさせて頂きます。
どうもありがとうございました。
> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
> を
> Module^ m = Assembly::GetExecutingAssembly()->GetModules()[ 0 ];
> に変えたらDLL内のフォームのアイコン描画が出来ました。
フム。
それで正解っぽいですね。
Assembly.GetExecutingAssembly メソッド
http://msdn2.microsoft.com/ja-
jp/library/system.reflection.assembly.getexecutingassembly.aspx
> 現在実行中のコードを格納しているアセンブリを取得します。
→ DLL内では、DLLのアセンブリ
Assembly.GetEntryAssembly メソッド
http://msdn2.microsoft.com/ja-
JP/library/system.reflection.assembly.getentryassembly.aspx
> 既定のアプリケーション ドメインで実行できるプロセスを取得します。
→ DLLを呼んでいる実行できるアプリのアセンブリ
なかなか勉強になりました。
よく確認してみたら、
> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
は転記ミスでした。
「インスタンスハンドルを取得する」例はほとんど GetExecutingAssembly を使ってい
ますね。
多分、寝ぼけてて、あんまり確認しないで実行できたからそのままのせたっぽいです。
ですので、今回のように自分自身がリソースを持っている場合、インスタンスハンドル
を取得するのは GetExecutingAssembly で取得すべきですね。