MTS MTS - 4 months ago 17
C++ Question

Why Does my Message Box Show Up in Another Language?

Honest to God, I'm losing my mind right now. Let me just start by saying the "MessageBox" function works perfectly fine in CodeBlocks when I define the text inside of it and what-not; but for whatever reason, Visual Studio is so picky about what can go inside of this MessageBox function.

It kept telling me that whatever I put inside of it was invalid for the LPCWSTR "thing". To circumvent this, I programmed this thing below:

int main()
{
LPCWSTR a;
std::string s = "Please help me.";
a = (LPCWSTR)s.c_str();

LPCWSTR b;
std::string t = "MTS";
b = (LPCWSTR)t.c_str();

MessageBox(0,a,b, MB_OK | MB_ICONSTOP);
}


Instead of it working how I originally thought it would, I instead got THIS as a result:

Image

This is very stressful for me and I know it has been asked once before here, so please don't mark my question as a duplicate. How do I make this code work so my message shows up in ENGLISH and portrays what I'm trying to say clearly?

Thanks ahead of time,

MTS

Answer

The reason why it shows up in another language (and usually, it is gibberish in the language you're seeing) is that you're casting the string type instead of using the proper string type:

LPCWSTR b;
std::string t = "MTS";
b = (LPCWSTR)t.c_str();

This code does not turn a narrow, ANSI based string into a wide string. Casting does not convert string types. If you removed the cast, you would see that the compiler gives you an error that the string types / pointers do not match.

Since you're using the MessageBox function, this is actually a call to MessageBoxW, which requires wide string arguments.

The reason in your case why MessageBoxW is called is that MessageBox will either be MessageBoxA or MessageBoxW, depending on the build type (MBCS or Unicode, respectively). For CodeBlocks, you probably had your project set up as MBCS, while on Visual Studio, it is set up as Unicode, thus it worked for one project, and failed on the other.

Thus the fix is to provide a wide string in this case:

LPCWSTR b;
std::wstring t = L"MTS";
b = t.c_str();

or even this:

LPCWSTR b;
std::basic_string<WCHAR> t = L"MTS";
b = t.c_str();

If you want to have the same code work for both MBCS and Unicode builds without coding changes, then the following could also be used:

#include <tchar.h>
//...
LPCTSTR b;
std::basic_string<TCHAR> t = _T("MTS");
b = t.c_str();

This uses the _T (or TEXT macro) to make the string literal either narrow or wide, depending on the build type. The TCHAR will either be narrow or wide, depending on the build type.


The bottom line is this -- if you're calling a function that requires a string, and the compiler gives you an error that the string types do not match, do not try C-style casts to "fix" the compiler error. This is especially the case for strings. Instead, either

1) Provide the correct string types so that casting is never necessary,

or

2) Call the correct function (in this case MessageBoxA) that accepts your string types without having to apply casts.