リソースに組み込んだファイルの参照方法

[戻る]
紅' 2010/12/21(火) 09:51:56
VC でリソースとして実行ファイルに組み込んだファイルの
参照方法について教えてください。
※ 2ch で同様の質問をしましたが答えを見つけられなかったため、
 こちらでも質問をさせていただきます。マルチですみません。

環境は WindowsXP + VC2008(Win32API) です。

・プログラムの実行に必要となるバイナリファイルがある
 このファイルは常に固定であるため、
 実行ファイルに含めてしまいたいと考える
・.rc ファイルを編集して以下のような行を追加した
  IDR_DATA DATA_TABLE "data.bin"
・上記のリソースはリソースエディタ?上で見えている
・API を以下のように実行した
  handle = ::FindResource( NULL, "DATA_TABLE", "IDR_DATA" )
・前項の handle が NULL だった

念のため、::FindResource の第2/3パラメータを逆転させたり、
resource.h に ID を登録して MAKEINTRESOURCE() で変換した値を
渡してみたりしても結果は変わりませんでした。

ネットで検索した結果では .rc に設定した値
(上の例では IDR_DATA と DATA_TABLE )をそのまま文字列として
渡していたのでそのように記述したり、MAKEINTRESOURCE() を
使ってパラメータを設定する方法も試してみました。

.rc の定義名も "" で囲ってみたりしたのですが、試した組み合わせでは
すべて結果が同じでした。

どのようにするとプログラム中で参照できるようになるのでしょうか。
ご教示いただければ幸いです。

えーと 2010/12/21(火) 10:25:41
> IDR_DATA DATA_TABLE "data.bin"
> handle = ::FindResource( NULL, "DATA_TABLE", "IDR_DATA" )

UNICODEプロジェクトになってませんか?。
たぶん
handle = ::FindResource( NULL, _T("DATA_TABLE"), MAKEINTRESOURCE( IDR_DATA ) );

でいけるかと思います。
私は、
handle = ::FindRecource( AfxGetResourceHandle(), .... );
にしています。
リソース切り替えにも対応できるので..

紅' 2010/12/21(火) 11:32:14
えーとさん、返信をありがとうございました。

試してみたのですが、残念ながら失敗しました。
プロジェクトを作り直して、ほんとうに先に記述したとおりの
環境にしたつもりなのですが、そちらでも同様でした。

いただいた情報から ::FindRecource() の第一パラメータを
調べなおしたところ、以下のような記述があります。

>NULL を指定すると、(中略)イメージファイルに関連付けられた(後略)

これが原因かもしれません。
ただ、作り直したプロジェクトの設定を MFC にして、::AfxGetResourceHandle() を
第一パラメータに与えたところ、結果は同じでした。
このパラメータについてネットでも調べてみたのですが、情報が少ないようです。

このような現象は自分だけでしょうか。
最悪、起動後に読み込めばいいのですが、なにか負けたような気がして悔しいです。w

お心当たりがございましたら、ご示唆をお願いします。

仲澤@失業者 2010/12/21(火) 12:39:32
>handle = ::FindResource( NULL, "DATA_TABLE", "IDR_DATA" )
手元のマニュアルによると
HRSRC FindResource(
  HMODULE hModule, // モジュールのハンドル
  LPCTSTR lpName,  // リソース名
  LPCTSTR lpType   // リソースタイプ
);

とありますね。従って

HRSRC h = FindResource(
  0x00400000,        // モジュールのハンドル(保存してあるならそれを使う)
  MAKEINTRESOURCE( IDR_DATA),  // リソース名
  RT_RCDATA);   // リソースタイプ

と考えるのが普通ですよね。

仲澤@失業者 2010/12/21(火) 13:01:15
ごめん間違った orz

HRSRC h = FindResource(
  0x00400000,        // モジュールのハンドル(保存してあるならそれを使う)
  MAKEINTRESOURCE( IDR_DATA),  // リソース名
  MAKEINTRESOURCE( DATA_TABLE));   // リソースタイプ

ただし、*.rcがインクルードされるヘッダー(通常Resource.h)に

#define DATA_TABLE   50 // 24以下は使えない

などと定義してあること。
これでもだめな場合は、*rc内の当該の定義を

IDR_DATA 50 "data.bin"

とし、

HRSRC h = FindResource(
  0x00400000,        // モジュールのハンドル(保存してあるならそれを使う)
  MAKEINTRESOURCE( IDR_DATA),  // リソース名
  MAKEINTRESOURCE( 50));   // リソースタイプ

で、呼んでみてください。
これでもハンドルがとれない場合は、そもそもそのファイルの
サイズが0等の、根本的な問題があるように思います。

subaru 2010/12/21(火) 13:15:05
>ネットで検索した結果では .rc に設定した値
>(上の例では IDR_DATA と DATA_TABLE )をそのまま文字列として
>渡していたのでそのように記述したり、MAKEINTRESOURCE() を
>使ってパラメータを設定する方法も試してみました。

IDR_DATAとDATA_TABLEは#defineで定数としてマクロ定義していれば
MAKEINTRESOURCEを使います。
マクロの定義がない場合は文字列として扱われます。

紅' 2010/12/21(火) 13:40:26
[[解決]]
仲澤@失業者さん、subaruさん、返信をありがとうございます。

仲澤@失業者さんに教えていただいた方法で試したところ、
以下のような結果になりました。

・もともとのプロジェクトでは失敗した
・新規に起こしたプロジェクト(MFCとWinAPIのふたつ)では成功した

もともとのプロジェクトには新規に起こしたプロジェクトの該当部分を
そのままコピーして、ID などにも重複がないことを確認しているので、
不思議です。

おそらくプロジェクトファイルの設定のどこかに誤り?があるのではないかと
思われるので‥‥最悪の場合、本命のプロジェクトを作り直せば
うまくいきそうな気配ではあります。

環境?に依存していそうであるため、自分でもうちょっとプロジェクト同士を
比較して調べてみようと思います。
一応、本件には解決チェックと入れさせていただきます。

みなさま、どうもありがとうございました。

古いスレッドには追加発言できません。