问题描述
我在 Visual Studio 2015 中创建了一个基本的 Windows C++ 应用程序,但出现了一些错误:
#include #include #include #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){MessageBox(NULL, "Test_text", "Message Test", MB_ICONINFORMATION | MB_OKCANCEL);返回0;}
错误:
'int MessageBoxW(HWND,LPCWSTR,LPCWSTR,UNIT)': 无法将参数 2 从'const char [10]' 到 'LPCWSTR'const char *"类型的参数与LPCWSTR"类型的参数不兼容const char *"类型的参数与LPCWSTR"类型的参数不兼容
这里的问题是 Win32 TCHAR
模型.
实际上没有 MessageBox
函数:MessageBox
是一个 预处理器 #define
,它扩展为 MessageBoxA
或 MessageBoxW
,基于您的项目设置(分别为 ANSI/MBCS 或 Unicode).
从 VS2005 开始,Visual Studio 中的默认设置一直是Unicode(更准确地说:UTF-16).因此,在这种情况下,编译器会选择 MessageBoxW
API(即 Unicode 版本).
MessageBoxW
API 采用 Unicode (UTF-16) 字符串,通过 wchar_t
指针(晦涩的 LPCWSTR
> 预处理器宏扩展为 const wchar_t*
,即以 NUL
结尾的 C 风格 Unicode UTF-16 字符串).
Unicode (UTF-16) 字符串文字使用 L"..."
语法表示(注意 L 前缀).
因此,虽然 "Test_text"
是 ANSI 字符串文字,但 L"Test_text"
是 Unicode (UTF-16) 字符串文字.
由于您(隐式地,通过 Visual Studio 默认设置)进行 Unicode 构建,您应该使用 L 前缀 装饰您的字符串文字,例如:
MessageBox(nullptr,//<--- 在现代 C++ 代码中更喜欢 nullptr 而不是 NULLL"Test_text",//<--- Unicode (UTF-16) 字符串文字L"Message Test",//<--- Unicode (UTF-16) 字符串文字MB_图标信息 |MB_OKCANCEL);
另一种方法是使用 _T("...")
或 TEXT("...")
宏.这些将在 ANSI/MBCS 构建中扩展为简单的 "..."
ANSI 字符串文字,以及 Unicode (UTF-16) 字符串文字 L"..."
在 Unicode 版本中(这是现代版本的 Visual Studio 中的默认设置).
//TEXT("...") 适用于 ANSI/MBCS 和 Unicode 版本消息框(空指针,TEXT("Test_text"),TEXT("消息测试"),MB_图标信息 |MB_OKCANCEL);
就我个人而言,我认为 TCHAR 模型是过去的过时模型(我认为没有理由生成现代 C++ Win32 应用程序的 ANSI 版本),并考虑到现代 Windows API 仅支持 Unicode(例如 DrawThemeText()
),我只是使用 L"..."
前缀装饰字符串文字,有点忘记 ANSI 构建.
I created a basic Windows C++ application in Visual Studio 2015 and I have a few errors:
#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;
}
Errors:
The problem here is the Win32 TCHAR
model.
There's actually no MessageBox
function: MessageBox
is a preprocessor #define
, that expands to MessageBoxA
or MessageBoxW
, based on your project settings (ANSI/MBCS or Unicode, respectively).
Starting with VS2005, the default setting in Visual Studio has been Unicode (to be more precise: UTF-16). So the MessageBoxW
API (i.e. the Unicode version) is picked in this case by the compiler.
The MessageBoxW
API takes Unicode (UTF-16) strings, represented via wchar_t
pointers (the obscure LPCWSTR
preprocessor macro is expanded to const wchar_t*
, i.e. a NUL
-terminated C-style Unicode UTF-16 string).
Unicode (UTF-16) string literals are represented using the L"..."
syntax (note the L prefix).
So, while "Test_text"
is an ANSI string literal, L"Test_text"
is a Unicode (UTF-16) string literal.
Since your are (implicitly, via Visual Studio default settings) doing a Unicode build, you should decorate your string literals with the L prefix, e.g.:
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);
An alternative is to decorate the string literals using the _T("...")
or TEXT("...")
macros. These will be expanded to simple "..."
ANSI string literals in ANSI/MBCS builds, and to Unicode (UTF-16) string literals L"..."
in Unicode builds (which are the default in modern versions of Visual Studio).
// TEXT("...") works in both ANSI/MBCS and Unicode builds
MessageBox(nullptr,
TEXT("Test_text"),
TEXT("Message Test"),
MB_ICONINFORMATION | MB_OKCANCEL);
Personally, I consider the TCHAR model an obsolete model from the past (I see no reason to produce ANSI builds of modern C++ Win32 applications), and considering that modern Windows APIs are Unicode-only (e.g. DrawThemeText()
), I'd just decorate strings literals using the L"..."
prefix, and kind of forget about the ANSI builds.
这篇关于MessageBox 上的 Visual Studio 2015 WinAPI 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!