FormatMessage() で文字列取得が出来ない。

[戻る]
ひろ 2002/12/27(金) 19:54:25
リソースの StringTable から ::FormatMessage() を使って
文字列を取得したいのですが、うまくいきません。
::FormatMessage() は以下のような呼び出しをしています。

    //hInstance    アプリケーションのインスタンス
    //uStrId       取得したい文字列リソースのID
    //szMsg        文字列の格納先 (charの配列)
    //uMsgSize     szMsg 配列のサイズ
    ::FormatMessage
      (FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
        hInstance, uStrId, 0, szMsg, uMsgSize, NULL);

これを実行しても、szMsg には何も入らないのです。
hInstance を NULL にしたりなど、
引数もいくつか変えて試したのですが、どれも同じ結果になってしまいました。
::GetLastError() で調べてみたところ 317 が返って来て、エラー文字列を見たら
『メッセージ番号 0x%1 のメッセージ文が %2 のメッセージ ファイルに見つかりません。』
とのことでした。

リソースの StringTable から文字列を取得するのは、
::FormatMessage() では出来ないのでしょうか?
また、出来るとしたら何が間違っているのでしょうか。

宜しくお願いします。


追記。
  ::LoadString() では出来るのですが、
  最後の引数に挿入句を指定して、 %1 や %2 などの書式指定をしたいために
  ::FormatMessage() を使いたいのです。


開発環境
  VisualC++6.0
  OS : WindowsMe

YuO [E-Mail] 2002/12/27(金) 23:49:00
FormatMessageは,メッセージリソースから読み込みます。
ストリングリソースから読み込ませたいなら,
LoadStringで一旦読み込んで,その文字列を処理する必要があります。

ひろ 2002/12/28(土) 11:17:31
どうもありがとうございます。

メッセージリソースっていうのは、StringTable とは違うんですね。
FormatMessage() では出来ないと判ったので、
YuO さんの言うとおり LoadString() で読み込んでから書式指定をすることにします。

それと、もう1つ質問なのですが、
StringTable でないとしたら、メッセージリソースとは何なのでしょうか?
検索などでいろいろ調べたのですが、全く出てこなかったので判りませんでした。

いちおうは解決なのですが、
気になった部分なので、どうか宜しくお願いします。

RAPT 2002/12/28(土) 17:27:09
FormatMessage()は、エラーメッセージとか、デバッグウィンドウに出すメッセージの処理
に使うものだったような気が。使っていないので、間違ってたらすみません。

Windows98/VC++6.0pro/SDK-may2002/ATL3.0/WTL7.0

YuO [E-Mail] 2002/12/28(土) 21:21:24
ローカライズのための特殊な形式です。
http://msdn.microsoft.com/library/en-us/tools/mc_86cy.asp

MC.EXEを使ってコンパイルする必要があったり,結構面倒なリソースです。
NT系のイベントログに出力するのに使われることが多いです。

ひろ 2002/12/29(日) 06:50:57
[[解決]]
エラーメッセージなど、ってことは、
FormatMessage() は普通では使わないような感じなんですね。

メッセージリソースっていうのはVCでは使えないんですね。
さらにページも英語だし、なかなか難しそうで。。。

今回は LoadString() で事足りそうなので、こっちを使うことにします。
(エラーメッセージで使うってことは、
 通常ではFormatMessage() は使わない方がいいのかな・・・?)
やりたいことが出来て、余力があったときに
メッセージリソースにも挑戦してみようと思います。

YuOさん、RAPTさん、どうもありがとうございました!

YuO [E-Mail] 2002/12/29(日) 07:44:37
> エラーメッセージなど、ってことは、
> FormatMessage() は普通では使わないような感じなんですね。

そうではないです。
本来の目的は,国際化のための機構です。
例えば,エラーメッセージの例になってしまいますが,
en : File "bar" is not found at directory "foo".
jp : ディレクトリ"foo"にファイル"bar"が見つかりません。
ということが考えられます。
日本語と英語で引数の順番が異なってしまいますよね。
そこで,
File "%1" is not fund at directory "%2".
ディレクトリ"%2"にファイル"%1"が見つかりません。
というメッセージリソースを用意して,FormatMessageを使うと,それぞれの言語にあった形式で出力される,
というようなものです。


> メッセージリソースっていうのはVCでは使えないんですね。

統合環境から使えないだけで,VCで扱えるリソースです。

ひろ 2002/12/29(日) 08:36:32
なるほど、なるほど。
FormatMessage() は複数の異なった言語などで書式指定などすると便利なんですね。

早朝から判りやすい説明をどうもありがとうございました。

dairygoods 2003/01/06(月) 10:23:31
MFCをお使いであれば、
CString::FormatMessage()で文字列リソースから読み込んで書式化できますよ。
中身は、単にLoadString()してFormatMessage()を呼び出しているだけです。

ひろ 2003/01/07(火) 00:30:02
解決済みにも関わらず返信、どうもありがとうございます。
CString::FormatMessage() の方は知っていました。
前まで(MFCを使っていた頃)はその方法を使っていたのですが、
今はSDKでやっているので CString などは使えないってわけなんです。

前まで使っていた CString::FormatMessage() は、
ただ単に ::FormatMessage() を呼び出しているだけだと思っていたので、
::FormatMessage() でやってみたんですが、
出来なかったので今回のような質問をしました。

SDKで、というのを書き洩れしていたようです。
情報不足で無駄なことをさせてしまい、すみませんでした。

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