C++Builder's compilers have a _TCHAR maps to option which controls the behavior you are seeing. See _TCHAR Mapping in C++Builder's documentation.
When the mapping is set to char, the UNICODE conditional is not defined, causing TCHAR-based APIs to map to their ANSI versions.
When the mapping is set to wchar_t, the UNICODE conditional is defined, causing TCHAR-based APIs to map to their Unicode versions.
In this situation, the Win32 MessageBox() is a TCHAR-based API. It maps to either MessageBoxA or MessageBoxW, respectively. You can see this in winuser.h:
WINUSERAPI
int
WINAPI
MessageBoxA(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE
Your C++Builder 2009 project is set to map TCHAR to char, but your C++Builder 12 project is set to map TCHR to wchar_t. That is why you are getting a mismatch.
When using strings with TCHAR-based APIs, you should be using the TCHAR type for string variables, and the TEXT() macro for string literals, eg:
TCHAR testString[256] = TEXT("This is a test");
MessageBox(NULL, testString, TEXT("Test"), 0);
MessageBox(NULL, TEXT("This is a test"), TEXT("Test"), 0);
Otherwise, call the ANSI/Unicode APIs directly based on the types of strings you are using, eg:
char testStringA[256] = "This is a test";
MessageBoxA(NULL, testStringA, "Test", 0);
wchar_t testStringW[256] = L"This is a test";
MessageBoxW(NULL, testStringW, L"Test", 0);
MessageBoxA(NULL, "This is a test", "Test", 0);
MessageBoxW(NULL, L"This is a test", L"Test", 0);
AandWversions. You just need to call the correct one that matches your character type.auto& testString = "This is a test";which both makes it immutable and preserves its size (so its string length becomes known at compile time:sizeof testString - 1).