0

文字列をリソースに移動しました。幸い、LPCTSTR演算子を使用して、次のように文字列を便利にインスタンス化できます。

CString str( (LPCSTR) IDS_MY_STRING);

次に、MessageBox()を使用して同様の型キャストを実行し、リソースから文字列もロードするようにします。これにより、次のようになります。

MessageBox( hWnd, (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);

しかし、これは機能せず、コンパイルされますが、実行時にクラッシュします。これで、次のことが機能します。

MessageBox( hWnd, (CString) (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);

私の質問は、MessageBox()がLPCTSTRを2番目のパラメーターとしてとにかく取るということですが、なぜこれを機能させるためにLPCTSTRからCStringに追加で型キャストする必要があるのですか?

4

4 に答える 4

3

あなたIDS_MY_STRINGは実際には文字列へのポインタではありません。整数です。(文字列ポインタの場合、LPCTSTRそもそもキャストは必要ありません。)CString統合リソースIDからリソース文字列をロードする方法を知っています。

MessageBoxそうではありません。CString暗黙的に提供する実際の文字ポインタが必要です。

于 2012-04-17T20:55:32.563 に答える
3

本当の質問(または少なくとも答えの興味深い部分)は、2番目がどのように失敗するかについてではなく、最初がどのように機能するかについてです。

1つ目は、LPCSTRを受け取るCStringのコンストラクターが実際に値を調べて、それが実際に文字列へのポインターなのか、文字列リソースの識別子なのかを判断するために機能します。後者の場合、文字列リソースを自動的にロードし、同じ内容のCStringを作成します。IOW、文字列識別子からCStringへの暗黙の変換があります。

CStringは、LPCSTR / LPCSTR/LPCWSTRへの暗黙的な変換もサポートします。

ただし、C ++は、渡されるタイプから式に必要なタイプに取得するために、ユーザー定義の暗黙的な変換を1つだけ実行します。この場合、文字列IDからに取得するにはLPCTSTR、2つ必要です。1つは文字列IDからCString、もう1つはからCStringになり LPCTSTRます。コンパイラは自動的にそれを行いません。

したがって、文字列IDからを取得するには、文字列IDからLPCTSTRを明示的に変換する必要があります。これは、をとるのコンストラクタCStringを使用します。したがって、文字列IDをにキャストし、そこからにキャストすると、が作成されます。次に、コンパイラは自動的に(実際の)`LPCTSTRに変換します。CStringLPCTSTRLPCTSTRCStringCStringCString

于 2012-04-17T20:58:56.607 に答える
1

MessageBoxリソースIDを取得するオーバーロードはありませんが、AfxMessageBox代わりに使用できます。

于 2012-04-17T20:54:02.207 に答える
1

型キャスト等の詳細を説明している方もいらっしゃいます。

さらに、コードを単純化するために、次#defineのような便利なマクロが必要になる場合があります。

#define _S(id) (CString(LPCTSTR(id))) 

そしてそれをMessageBox(または他のLPCTSTRパラメータにも)使用します:

MessageBox( hWnd, _S(IDS_MY_STRING), _S(IDS_TITLE), MB_RETRYCANCEL );
于 2012-04-17T21:56:56.237 に答える