1

Windows GUI に関する winprog.org のチュートリアルについて話しているのは、StackO の多くのユーザーが推奨しているためです。

私は基本的にこの例を試しました:

#include "stdafx.h"
#include "winapiTest1.h"


int WINAPI _tWinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPTSTR    lpCmdLine,
        int       nCmdShow)
{
    MessageBox(NULL, (LPCWSTR) "Goodbye, cruel world!", (LPCWSTR) "Note", MB_OK);
    return 0;
}

しかし、実行するとメッセージボックスが表示されますが、その中のすべての文字列 (タイトルも含む) は漢字で表されます。

問題に見えるのは?

4

2 に答える 2

5

しかし、実行すると、メッセージ ボックスが表示されますが、その中のすべての文字列 (タイトルも含む) は漢字で表されます。

その理由は、オペレーティング システムが文字列リテラルを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 文字列を処理するための独自の規定があります。フレームワーク/ライブラリを使用している場合は、代わりにそれらに従ってください。

于 2012-07-22T18:53:53.443 に答える
1

試す:

MessageBox(NULL, _T("Goodbye, cruel world!"), _T("Note"), MB_OK);
于 2012-07-22T18:50:06.767 に答える