リソースからのアイコン表示方法 – プログラミング – Home

リソースからのアイコン表示方法
 
通知
すべてクリア

[解決済] リソースからのアイコン表示方法


モーヲタ
 モーヲタ
(@モーヲタ)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

環境
VC++.NET 2003 Windows フォームアプリケーション(マネージ)プロジェクト

表題の通りなのですが、
アイコンファイルをリソースの「Icon」にインポートし、IDを
「IDI_ICON_DATA」と任意に指定したのですが、
リソース上のアイコンデータ(IDI_ICON_DATA)をプログラムから
読み込む方法が分かりません。
LoadIconで強引にやってもエラーになり、おそらく
.NET Frameworkのクラスで操作出来るのではないかと思い質問しました。

どなたかおわかりになりましたらご教授よろしくお願いします。


引用未解決
トピックタグ
モーヲタ
 モーヲタ
(@モーヲタ)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

あっ、すいません、アイコンデータはピクチャーボックスに
表示しようとしてます。よろしくお願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

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用)にするには ^ を * にするだけでいいと思う。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

ちなみに上の方法は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


返信引用
モーヲタ
 モーヲタ
(@モーヲタ)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

>// インスタンスハンドルを取得
>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は各プロジェクト共通で
使用するフォームです)
その場合はどのような処理に変更すれば宜しいのでしょうか?
度々すみませんがご教授よろしくお願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 作成したdllでは上記コードではインスタンスがNULLになってしまいます。
どこがNULLになりますか?HINSTANCE?HINSTANCE?

予想としては、
> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
がまずいかも。
(DLLの場合、実行しているのはDLLではなくDLLを呼んでいるアプリになるので、
0番目ではないんじゃないかな?)

ただいま、VS2005すらないので、何も試すことができません。
ですので、まともな回答はつけれません。
夜(もしくは明日の夜以降)であれば、試して見ることはできます。
(気分によるので期待はしないでください)

# C#やVBで作った Windows コントロール ライブラリ だったら
# (Win32リソースではなくマネージドリソースなので)簡単にできるのかも。
## よって、マネージドリソースをMC++(C++/CLI)で使う方法がわかれば簡単かも。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

訂正)
>どこがNULLになりますか?HINSTANCE?HINSTANCE?
どこがNULLになりますか?HINSTANCE?HICON?


返信引用
モーヲタ
 モーヲタ
(@モーヲタ)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

Blueさん、レスありがとうございます。

>どこがNULLになりますか?HINSTANCE?HICON?
HICONです。

>予想としては、
>> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
>がまずいかも。

と言うヒントを頂き、ちょっといろいろ試してみた結果、
うまくいきました!!

Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];

Module^ m = Assembly::GetExecutingAssembly()->GetModules()[ 0 ];
に変えたらDLL内のフォームのアイコン描画が出来ました。
(果たしてこれでよいのかは不安ですが→たまたま動いているだけかも・・・・)

よって一応解決とさせて頂きます。
どうもありがとうございました。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 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を呼んでいる実行できるアプリのアセンブリ

なかなか勉強になりました。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

よく確認してみたら、
> Module^ m = Assembly::GetEntryAssembly()->GetModules()[ 0 ];
は転記ミスでした。
「インスタンスハンドルを取得する」例はほとんど GetExecutingAssembly を使ってい
ますね。
多分、寝ぼけてて、あんまり確認しないで実行できたからそのままのせたっぽいです。

ですので、今回のように自分自身がリソースを持っている場合、インスタンスハンドル
を取得するのは GetExecutingAssembly で取得すべきですね。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました