MessageBox 上的 Visual Studio 2015 WinAPI 错误 [英] Visual Studio 2015 WinAPI error on MessageBox

查看:24
本文介绍了MessageBox 上的 Visual Studio 2015 WinAPI 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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,它扩展为 MessageBoxAMessageBoxW,基于您的项目设置(分别为 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:

'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"

解决方案

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 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆