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函数:MessageBox是一个预处理器 ,它根据您的项目设置(分别为 ANSI/MBCS 或 Unicode)#define扩展为MessageBoxA或。MessageBoxW

从 VS2005 开始,Visual Studio 中的默认设置是Unicode(更准确地说:UTF-16)。因此,MessageBoxW在这种情况下,编译器会选择 API(即 Unicode 版本)。

MessageBoxWAPI 采用Unicode (UTF-16) 字符串,通过wchar_t指针表示(晦涩的LPCWSTR预处理器宏扩展为const wchar_t*,即以NUL- 终止的 C 样式 Unicode UTF-16 字符串)。

Unicode (UTF-16) 字符串文字使用L"..."语法表示(注意L 前缀)。
因此,while"Test_text"是 ANSI 字符串文字,L"Test_text"是 Unicode (UTF-16) 字符串文字。

由于您正在(通过 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("...")另一种方法是使用orTEXT("...")来装饰字符串文字。这些将扩展到"..."ANSI/MBCS 构建中的简单 ANSI 字符串文字,以及 Unicode 构建中的 Unicode (UTF-16) 字符串文字L"..."(这是现代版本的 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 回答
5

您选择使用 ANSI 文本,因此应MessageBoxA显式使用而不是使用宏MessageBox

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

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

或者,您可以使用TEXT宏让编译器自动匹配字符串和函数的类型。

#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, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL);
    return 0;
}
于 2016-03-01T15:28:10.233 回答
4

本例中的 MessageBox 实际上是 MessageBoxW,它采用 unicode 字符串。您可以通过以下方式修复它:

MessageBoxW(NULL, L"Test_text", L"Message Test", MB_ICONINFORMATION | MB_OKCANCEL);

或者

MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL);
于 2016-03-01T15:28:05.190 回答
2

你不能像这样传递一个裸字符串文字。

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

TEXT是一个宏,可以根据您的编译方式扩展为正确的字符串类型。

于 2016-03-01T15:27:30.090 回答
0

您需要Character Set为您的项目选择正确的设置。在 Visual Studio 项目的属性中,导航到该General类别。里面有一个条目Character Set

如果您选择Unicode Character Set编译器将为_UNICODE您定义,并且所有函数都MessageBox将评估为它们的宽字符变体,例如MessageBoxW.

如果您选择Multi-Byte(已弃用),编译器将为_MBCS您定义,并且函数将评估为多字节变体,例如MessageBoxA.

字符串也是如此,答案中提到的宏(如TEXT)将L在 unicode 环境中的所有字符串前面添加一个。

请参阅此处了解更多信息:https ://msdn.microsoft.com/en-us/library/ey142t48.aspx

恕我直言,很少有人想要明确地针对WorA方法进行编写。如果你必须这样做才能让你的编译器满意,你应该重新检查你的设置。

于 2016-03-01T15:45:54.367 回答