MessageBox上的Visual Studio 2015 WinAPI错误 我在VisualStudio 2015中创建了一个基本的Windows C++应用程序,并且我有一些错误:

MessageBox上的Visual Studio 2015 WinAPI错误 我在VisualStudio 2015中创建了一个基本的Windows C++应用程序,并且我有一些错误:,c++,winapi,visual-studio-2015,tchar,lpcwstr,C++,Winapi,Visual Studio 2015,Tchar,Lpcwstr,你不能像那样传递一个简单的字符串文本 MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL); TEXT是一个宏,它可以根据编译方式扩展为正确的字符串类型。这样的简单字符串文本是无法传递的 MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL

你不能像那样传递一个简单的字符串文本

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

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

这样的简单字符串文本是无法传递的

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

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

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

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


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

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


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


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


您需要为项目的角色集选择正确的设置。在Visual Studio项目的属性中,导航到“常规”类别。其中有一个输入字符集

如果选择Unicode字符集,编译器将为您定义_Unicode,所有函数(如MessageBox)将根据其宽字符变量(如MessageBoxW)求值

如果选择“不推荐使用多字节”,编译器将为您定义_MBCS,函数将计算为多字节变量,如MessageBoxA

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

有关更多信息,请参见此处:


我认为,很少有理由明确针对W或A方法编写代码。如果必须这样做才能使编译器满意,则应重新检查设置。

您需要为项目的字符集选择正确的设置。在Visual Studio项目的属性中,导航到“常规”类别。其中有一个输入字符集

如果选择Unicode字符集,编译器将为您定义_Unicode,所有函数(如MessageBox)将根据其宽字符变量(如MessageBoxW)求值

如果选择“不推荐使用多字节”,编译器将为您定义_MBCS,函数将计算为多字节变量,如MessageBoxA

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

有关更多信息,请参见此处:


我认为,很少有理由明确针对W或A方法编写代码。如果必须这样做才能使编译器满意,那么应该重新检查设置。

这里的问题是Win32 TCHAR模型

实际上没有MessageBox函数:MessageBox是一个预处理器定义,它分别基于您的项目设置ANSI/MBCS或Unicode扩展为MessageBoxA或MessageBoxW

从VS2005开始,VisualStudio中的默认设置为更精确的Unicode:UTF-16。因此,在本例中,编译器选择MessageBoxW API,即Unicode版本

MessageBoxW API采用Unicode UTF-16字符串,通过wchar\u t指针表示。晦涩的LPCWSTR预处理器宏扩展为const wchar\u t*,即以NUL结尾的C样式Unicode UTF-16字符串

Unicode UTF-16字符串文字使用L。。。语法注意L前缀。 因此,虽然Test_文本是ANSI字符串文本,但LTest_文本是Unicode UTF-16字符串文本

由于您的字符串是通过Visual Studio默认设置隐式生成Unicode的,因此您应该使用L前缀来修饰字符串文字,例如:


个人认为,过去的TCHAR模型是过时的模型,我认为没有理由产生现代C++ Win32应用的ANSI构建,并且考虑到现代Windows API仅是Unicode,所以我只使用L…前缀,有点忘了ANSI版本。

这里的问题是Win32 TCHAR模型

实际上没有MessageBox函数:MessageBox是一个预处理器定义,它分别基于您的项目设置ANSI/MBCS或Unicode扩展为MessageBoxA或MessageBoxW

从VS2005开始,VisualStudio中的默认设置为更精确的Unicode:UTF-16。因此,在本例中,编译器选择MessageBoxW API,即Unicode版本

MessageBoxW API采用Unicode UTF-16字符串,通过wchar\u t指针表示。晦涩的LPCWSTR预处理器宏扩展为const wchar\u t*,即以NUL结尾的C样式Unicode UTF-16字符串

Unicode UTF-16字符串文字使用L。。。语法注意L前缀。 因此,虽然Test_文本是ANSI字符串文本,但LTest_文本是Unicode UTF-16字符串文本

由于您的应用程序是通过Visual Studio默认设置隐式地执行Unicode生成的, 您应该使用L前缀修饰字符串文字,例如:


个人认为,过去的TCHAR模型是过时的模型,我认为没有理由产生现代C++ Win32应用的ANSI构建,并且考虑到现代Windows API仅是Unicode,所以我只使用L…前缀,有点忘了ANSI版本。

\T用于CRT,文本用于Windows API,所以在这种情况下使用文本更好。\T用于CRT,文本用于Windows API,所以在这种情况下使用文本更好。不要通过内联或外部链接的图像显示错误或代码。始终在此处以文本形式显示错误的全文。如果您搜索消息文本,您将已经找到解决方案。不要通过内联或外部链接的图像显示错误或代码。始终在此处以文本形式显示错误的全文。如果您搜索消息文本,您可能已经找到了解决方案。在传递宽字符字符串文本时,您应该显式调用API的宽字符版本,即MessageBoxW而不是MessageBox。@IInspectable:我不同意。MessageBoxW或DoSomethingW在Unicode构建中通常是无用的代码修饰:结尾W只是更清晰的MessageBox或DoSomething表单上的噪音。这与观点无关,与语言规则有关。MessageBox是通用的文本映射版本。MessageBoxW是Unicode版本。我会接受你认为丑陋的东西,而不是依赖我无法控制的环境。我理解你关于MessageBox是映射的推理,但如果我的代码不需要以ANSI模式构建,我更喜欢MessageBox和L。。。,如果有人试图进行ANSI构建而不是UNICODE构建,则会产生破坏编译的积极副作用。由于传递给函数的形式参数和参数不兼容,破坏代码没有任何积极意义。更糟糕的是:如果您没有明确说明您希望调用的函数,那么您可能没有完全调用您想要调用的函数。当传递nullptr时,编译器不会帮助您。它只会让你意外地调用一个你从未打算调用的函数。将预处理器符号用于泛型文本映射而不是真正的函数名并没有任何优势。停止基于错误声明提出建议。当传递宽字符字符串文本时,应显式调用API的宽字符版本,即MessageBoxW而不是MessageBox。@IInspectable:我不同意。MessageBoxW或DoSomethingW在Unicode构建中通常是无用的代码修饰:结尾W只是更清晰的MessageBox或DoSomething表单上的噪音。这与观点无关,与语言规则有关。MessageBox是通用的文本映射版本。MessageBoxW是Unicode版本。我会接受你认为丑陋的东西,而不是依赖我无法控制的环境。我理解你关于MessageBox是映射的推理,但如果我的代码不需要以ANSI模式构建,我更喜欢MessageBox和L。。。,如果有人试图进行ANSI构建而不是UNICODE构建,则会产生破坏编译的积极副作用。由于传递给函数的形式参数和参数不兼容,破坏代码没有任何积极意义。更糟糕的是:如果您没有明确说明您希望调用的函数,那么您可能没有完全调用您想要调用的函数。当传递nullptr时,编译器不会帮助您。它只会让你意外地调用一个你从未打算调用的函数。将预处理器符号用于泛型文本映射而不是真正的函数名并没有任何优势。不要再基于虚假的主张而提出它。
MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL);
#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;
}
#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;
}
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);
// TEXT("...") works in both ANSI/MBCS and Unicode builds
MessageBox(nullptr, 
           TEXT("Test_text"),    
           TEXT("Message Test"),
           MB_ICONINFORMATION | MB_OKCANCEL);