しかし、実行すると、メッセージ ボックスが表示されますが、その中のすべての文字列 (タイトルも含む) は漢字で表されます。
その理由は、オペレーティング システムが文字列リテラルをUTF-16を使用してエンコードされているかのように解釈しているためです。
のような一部の識別子にMessageBox()は、MessageBoxA()関数とMessageBoxW(). MessageBoxA()は、現在のコード ページでエンコードされた文字列を受け入れる「ANSI」バージョンでありMessageBoxW()、UTF-16 でエンコードされた文字列を受け入れる「ワイド」バージョンです (つまり、「Unicode 対応」です)。MessageBox()実際には、マクロが定義されているかどうかに応じて、これらのいずれかに定義するUNICODEマクロです。MessageBox() Windows API には、それ自体が呼び出される実際の関数はありません。
問題の核心はここにあります:
MessageBox(NULL, (LPCWSTR) "Goodbye, cruel world!", (LPCWSTR) "Note", MB_OK);
プロジェクトにはおそらく#define UNICODEどこかに があり、MessageBox()識別子が に解決されMessageBoxW()、UTF-16 でエンコードされた文字列が必要になります。通常、コンパイラはそれについて不平を言います (つまり、コンパイル エラー) が、LPCWSTRキャストは本質的にコンパイラをシャットダウンし、強制的にコンパイルします。
ランダムなキャストを投げて、常にそれが機能することを期待することはできません。残念ながら、多くの Windows API チュートリアル (および一部の C++ チュートリアル全般) では、キャストが必要でない場合や不適切な場合でさえ、いたるところでキャストが乱用されています。
James が提案する解決策では_T()、キャストを必要とせずに、文字列リテラルが適切にエンコードされるように設定するのに役立つマクロを使用します。ただし、新しいアプリケーションの優れたソリューションは、関数の ANSI バージョンを忘れて、常に Unicode で作業することです。この_T()マクロは、アプリケーションが Unicode 対応 API に移行するための応急処置です。
#include "stdafx.h" // Make sure UNICODE is defined before windows.h
#include "winapiTest1.h"
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPCSTR lpCmdLine,
int nCmdShow)
{
MessageBox(NULL, L"Goodbye, cruel world!", L"Note", MB_OK);
return 0;
}
文字列リテラルにはL接頭辞が付いていることに注意してください。これは、リテラルを UTF-16 でエンコードされた文字列として解釈するように Visual C++ コンパイラに指示します (他の C++ コンパイラでは別のエンコードに変換される可能性があることに注意してください。これは Visual C++ のみに適用されます)。
また、上記のアドバイスは、Windows API のみを使用する場合にのみ適用されることに注意してください。Windows API をラップする一部のフレームワークとライブラリには、Unicode 文字列を処理するための独自の規定があります。フレームワーク/ライブラリを使用している場合は、代わりにそれらに従ってください。