1

Visual Studio 2015 で基本的な Windows C++ アプリケーションを作成しましたが、いくつかのエラーがあります。

エラー画像

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MessageBox(NULL, "Test_text", "Message Test", MB_ICONINFORMATION | MB_OKCANCEL);
    return 0;
}

エラー:

'int MessageBoxW(HWND,LPCWSTR,LPCWSTR,UNIT)': cannot convert argument 2 from 
'const char [10]' to 'LPCWSTR'

argument of type "const char *" is incompatible with parameter of type "LPCWSTR"
argument of type "const char *" is incompatible with parameter of type "LPCWSTR"
4

5 に答える 5

5

ここでの問題は Win32TCHARモデルです。

実際にはMessageBox関数はありません:プロジェクト設定 (それぞれ ANSI/MBCS または Unicode) に基づいてまたはに展開されるMessageBoxプリプロセッサです。 #defineMessageBoxAMessageBoxW

VS2005 以降、Visual Studioの既定の設定はUnicode (より正確にはUTF-16 ) です。したがって、MessageBoxWこの場合、API (つまり Unicode バージョン) はコンパイラによって選択されます。

MessageBoxWAPI は、ポインターを介して表されるUnicode (UTF-16) 文字列wchar_tを取ります (あいまいなLPCWSTRプリプロセッサ マクロは に展開されますconst wchar_t*。つまり、終了するNULC スタイルの Unicode UTF-16 文字列)。

Unicode (UTF-16) 文字列リテラルは、構文を使用して表されます (接頭辞 LL"..."に注意してください)。 したがって、 whileは ANSI 文字列リテラルであり、 は Unicode (UTF-16) 文字列リテラルです。
"Test_text"L"Test_text"

(暗黙のうちに、Visual Studio のデフォルト設定を介して) Unicode ビルドを行っているため、文字列リテラルをL プレフィックスで装飾する必要があります。

MessageBox(nullptr,   // <--- prefer nullptr to NULL in modern C++ code 
           L"Test_text",      // <--- Unicode (UTF-16) string literal 
           L"Message Test",   // <--- Unicode (UTF-16) string literal
           MB_ICONINFORMATION | MB_OKCANCEL);

_T("...")別の方法は、またはTEXT("...")マクロを使用して文字列リテラルを修飾することです。これらは"..."、ANSI/MBCS ビルドでは単純な ANSI 文字列リテラルに拡張されL"..."、Unicode ビルドでは Unicode (UTF-16) 文字列リテラルに拡張されます (Visual Studio の最新バージョンでは既定です)。

// TEXT("...") works in both ANSI/MBCS and Unicode builds
MessageBox(nullptr, 
           TEXT("Test_text"),    
           TEXT("Message Test"),
           MB_ICONINFORMATION | MB_OKCANCEL);

個人的には、TCHAR モデルは過去の時代遅れのモデルだと考えています (最新の C++ Win32 アプリケーションの ANSI ビルドを作成する理由はないと思います)。また、最新の Windows API は Unicode のみ (たとえばDrawThemeText()) であることを考えると、文字列リテラルを装飾するだけです。接頭辞を使用しL"..."、ANSI ビルドを忘れてしまいます。

于 2016-03-01T16:01:30.250 に答える
2

そのような生の文字列リテラルを渡すことはできません。

MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL);

TEXTコンパイル方法に応じて適切な文字列型に展開されるマクロです。

于 2016-03-01T15:27:30.090 に答える