Uys of Spades
Uys of Spades

Reputation: 93

Win32 Application Programming C++, Error with parameter Type LPCWSTR

I am constructing a program using the Win32 Application on Visual Studio 2013. From the tutorials I have read, I know this following code is correct, but I don't know where to change the parameter type to read the following:

case WM_CREATE:
{
    hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", "",
        WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL |
        ES_AUTOVSCROLL, 50, 100, 300, 300, hWnd, (HMENU)IDC_EDIT_BOX, 
        NULL, NULL);

The compiler highlights "Edit" and gives me this error:

Error 1 error C2664: 'HWND CreateWindowExW(DWORD,LPCWSTR,LPCWSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID)' : cannot convert argument 2 from 'const char [5]' to 'LPCWSTR'

Upvotes: 1

Views: 2510

Answers (4)

LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam){
switch (Message){   
case WM_PAINT:
    break;
case WM_CREATE:

    break;

case WM_DESTROY:

    return 0;

default:

    if (IsWindowUnicode(hWnd))
        return DefWindowProcW(hWnd, Message, wParam, lParam);
    else
        return DefWindowProcA(hWnd, Message, wParam, lParam);
    break;
}
return 0;}

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320709

First and foremost, you need to decide what type of project you are trying to create with regard to character set. You have at least four options for project type

  1. Project that uses regular (narrow) characters only (char)
  2. Project that uses wide characters only (wchar_t)
  3. "Transformer" project that can be easily compiled as either type 1 or type 2 by a simple change in project settings
  4. Project that freely mixes narrow and wide characters

This is the decision that you have to make first. There's no point in proceeding before you make that decision.

Now, depending on the choice you made, you should proceed as follows

  1. Regular char project

    • Go to project settings and set "Character Set" to "Use Multi-Byte Character Set"
    • In your code use regular (narrow) string and character literals: "Edit", 'A' etc.
    • Use regular char, char [N], char * and std::string types to work with characters and strings
    • Use narrow versions of standard library functions: printf, strcpy etc.
    • Use either "normal" names to call Windows API functions: CreateWindowEx, or their narrow names: CreateWindowExA (whichever you like better)
  2. Wide wchar_t project

    • Go to project settings and set "Character Set" to "Use Unicode Character Set"
    • In your code explicitly use wide string and character literals: L"Edit", L'A' etc.
    • Use wide wchar_t, wchar_t [N], wchar_t * and std::wstring types to work with characters and strings
    • Use wide versions of standard library functions: wprintf, wcscpy etc.
    • Use either "normal" names to call Windows API functions: CreateWindowEx, or their wide names: CreateWindowExW (whichever you like better)
  3. "Transformer" project

    • Include <tchar.h> into every translation unit
    • In your code always explicitly use macro _T with string and character literals: _T("Edit"), _T('A') etc.
    • Use TCHAR, TCHAR [N], TCHAR * and std::basic_string<TCHAR> types to work with characters and strings
    • Use "transformer" versions of standard library functions: _tprintf, _tcscpy etc.
    • Use "normal" names to call Windows API functions: CreateWindowEx  
       
      With this kind of project, if you do everything properly, you will be able to automatically switch between type 1 and type 2 by simply changing the "Character Set" setting in project settings.
  4. Mix-and-match project

    • Use whatever type of character you prefer (narrow or wide) in each specific context, but remember to call the proper version of standard library and Windows API function for each character type. In some cases, when narrow and wide contexts meet, you will have to perform conversions between narrow and wide character types.

Of course, if you started a project of type 1 or type 2, you can always turn it into a project of type 4 by starting to mix character types. But if you need a type 3 project, it is a good idea to stick to its principles from the very beginning (converting to type 3 later is a very laborious process).


It is not immediately obvious what you are trying to do in your project. But a wild guess would be that you are trying to build a type 1 project. In that case all you need to do to fix the problem is go to project settings and set "Character Set" to "Use Multi-Byte Character Set".

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 597941

The error message is complaining about CreateWindowExW() but your code is calling CreateWindowEx(). That means your project is being compiled with UNICODE defined. In which case, CreateWindowEx() maps to CreateWindowExW(), which expects wide (wchar_t*) data, but you are passing it narrow (char*) data instead, hence the error.

You need to either:

  1. call CreateWindowExW() directly, and prefix the literals with L to make them wide instead of narrow:

    hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", L"", ...);
    
  2. continue calling CreateWindowEx() but wrap literals with the TEXT() macro so it will make them narrow or wide for you based on whether UNICODE is defined or not:

    hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""), ...);
    

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 613432

You are compiling with UNICODE defined. That means that CreateWindowEx is an alias for CreateWindowExW, the wide character version. Either:

  1. Supply wide character text, or
  2. Call CreateWindowExA, or
  3. Compile for ANSI.

Personally I would suggest option 1. Your code would become:

CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", L"",
  WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 
  50, 100, 300, 300, hWnd, (HMENU)IDC_EDIT_BOX, NULL, NULL);

The L prefix to your string literals is used to specify a wide character literal.

Upvotes: 9

Related Questions