しかし、実行すると、メッセージ ボックスが表示されますが、その中のすべての文字列 (タイトルも含む) は漢字で表されます。
その理由は、オペレーティング システムが文字列リテラルを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 文字列を処理するための独自の規定があります。フレームワーク/ライブラリを使用している場合は、代わりにそれらに従ってください。