0

I have the following c++ code, and it seems like everywhere I attempt to put a string, I have to convert it in order to avoid a `Cannot conver parameter 2 from 'const char[x] to LPCWSTR. I know I can fix this issue by doing a simple conversion, but is there any way around having to convert practically every string I provide? I am a c# developer learning c++ so I'm guessing I'm missing some fundamental concept of the language, if someone could shed some light on this, I'd be grateful!

#include <Windows.h>
#include <string>
using namespace std;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   PSTR cmdLine,
                   int showCmd)
{
    MessageBox(0, "First Win32 Program.", "My App", MB_OK);
}

Is there a better solution than just this:

{
    MessageBox(0, (LPCWSTR)"First Win32 Program.", (LPCWSTR)"My App", MB_OK);
}

And for some odd reason my application is coming up in Japanese or Chinese. So lost on this one.

enter image description here

Volearix
  • 1,573
  • 3
  • 23
  • 49
  • 3
    `MessageBox(0, L"First Win32 Program.", L"My App", MB_OK);` –  Apr 10 '14 at 13:54
  • @DieterLücking Okay, that worked, any possible explanation you might be able to help me out with? I'm more looking for the reason than the solution... If that makes sense. I'm just trying to understand what's going on. – Volearix Apr 10 '14 at 13:56
  • @DieterLücking And why the heck does `L(string)` give me English and `LPCWSTR` gives me Japanese/Chinese? – Volearix Apr 10 '14 at 13:57
  • It's not Japanese nor Chinese, it's garbage code. – Matt Apr 10 '14 at 13:57
  • 8
    Because the cast tells the compiler "I have some data of wrong type, but I must lie to suppress your warnings." – harper Apr 10 '14 at 13:58
  • Your usual strings in C / C++ are ASCII while WinAPI takes unicode ones. Maybe a more comfortable solution will be changing standard charset somewhere in the compiler options. – ionagamed Apr 10 '14 at 13:58
  • 1
    @Volearix, `L""` forms a proper wide string literal with the given data. Casting takes the data of the narrow string literal and pretends it's a wide string literal. The two have different representations. Pretending one is the other gives unsurprisingly incorrect results. – chris Apr 10 '14 at 14:00

2 Answers2

2

Use L"text" to create your strings. This way you're creating a wide string which most-likely are expected from the WinAPI.

#include <Windows.h>
#include <string>
using namespace std;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   PSTR cmdLine,
                   int showCmd)
{
    MessageBox(0, L"First Win32 Program.", L"My App", MB_OK);
}

The problem is you're injecting a narrow string by using a C-style cast to LPCWSTR. So two of your narrow chars (8 bit each) will end mixed-up in one UNICODE char (16 bit each).

Sambuca
  • 1,224
  • 18
  • 30
1

You should use the L prefix with your literals. The WINAPI works mostly with wide strings.

As for why that prefix works, here's the relevant part in the standard (§2.14.5/11):

A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type “array of n const wchar_t”, where n is the size of the string as defined below; it has static storage duration and is initialized with the given characters.

The garbage you get is because you're doing a cast that doesn't mean anything, and end up with garbage data that the library tries to interpret as a wide string.

Indeed, here's what a LPCWSTR:

typedef const wchar_t* LPCWSTR;
JBL
  • 12,588
  • 4
  • 53
  • 84