2

I haven't been programming in c++ very long, but need to make an Win32 application for my school. The teacher helped me a lot with information but after a few days of trying I am still stuck.

Errors:

error C2440: '=' : cannot convert from 'const char [11]' to 'LPCWSTR'
error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [11]' to 'LPCWSTR'
error C2664: 'TextOutW' : cannot convert parameter 4 from 'char *' to 'LPCWSTR'
IntelliSense: argument of type "char *" is incompatible with parameter of type "LPCWSTR"

Don't know if all the other suff is right, but i only get those 4 error now

cpp file:

    /* Hoofdstuk 10, User Interface */
#include "Callback_NYCM.h"

// UI
int WINAPI WinMain(HINSTANCE thisInstance,HINSTANCE prevInstance,LPSTR lpCmdLine,int nShowCmd) 
{ 
    PAINTSTRUCT ps;
    HDC hdc;
    MSG msg;
    HWND hwnd;
    WNDCLASSEX wndclassex; //struct_WNDCLASSEX via windows.h    

    // toekenning
    wndclassex.cbSize = sizeof(WNDCLASSEX); 
    wndclassex.style = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc = WndProc;
    wndclassex.cbClsExtra = 0;
    wndclassex.cbWndExtra = 0;
    wndclassex.hInstance = thisInstance;
    wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclassex.hCursor = LoadCursor(thisInstance,IDC_ARROW);  
    wndclassex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wndclassex.lpszMenuName = NULL;  
    wndclassex.lpszClassName = "WNDCLASSEX"; 
    wndclassex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 

    // functie aanroep
    RegisterClassEx(&wndclassex);

// IfThen -> CreateWindows
    if(!(hwnd = CreateWindowEx(NULL,"WNDCLASSEX","Hoofdstuk 10",WS_OVERLAPPEDWINDOW 
        | WS_VISIBLE,50,50,650,300,NULL,NULL,thisInstance,NULL)))  
    {  
        return 0; 
    } 
// logische structuur
while(GetMessage(&msg, NULL, 0, 0))  
{  
    if(msg.message == WM_QUIT)    
        break;   
    TranslateMessage(&msg);   
    DispatchMessage(&msg);  
}  
return (int) msg.wParam; 
};

header file:

 /*Hoofdstuk 10, Deelnemer.h*/ 
//Declaratie 
class Deelnemer 
{ 
private: 
    char* nm; 
public: 

//Constructor 
Deelnemer(){
}
    //Methoden = prototype 
    void Deelnemer::Invoeren();
    char* Deelnemer::WeergevenNaam();
};  
//Implemenmtatie.Invoeren 
void Deelnemer::Invoeren() 
{
    nm = "Roy"; 
}  
//.Weergeven 
char* Deelnemer::WeergevenNaam()
{ 
    return nm;
}

callback_NYCM.h:

    /*Hoofdstuk 10, Callback_NYCM*/
#include "Windows.h"
#include "Deelnemer.h"  

// prototype
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam); 

//Implementatie 
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam) 
{  
    //Constructie  
    PAINTSTRUCT ps;
    HDC hdc;
    MSG msg;
    WNDCLASSEX wndclassex;
    // HWND hwnd;
    Deelnemer deelnemer1; 


    //UI   
    switch(message)
    {
    case WM_PAINT:    
        {     
            //Functieaanroep.Initialisatie     
            deelnemer1.Invoeren();          
            //.TextOut  
            TextOut(hdc,50,50,deelnemer1.WeergevenNaam(),     
            strlen(deelnemer1.WeergevenNaam()));     
            EndPaint(hwnd,&ps);     
            return 0;   
        }    
        break;
        case WM_DESTROY:    
            {     
                PostQuitMessage(0);     
                return 0;    
            }    
            break;   
        default:    
            {     
                return DefWindowProc(hwnd,message,wparam,lparam);    
            }    
            break; 
    }
    return 0;
}

I think my constructor or something like that is wrong and my return value for char* Deelnemer::WeergevenNaam()

Could somebody explain me what is wrong in my code so I know how to get it working?

UPDATE:

Updating your application requires to use UNICODE string literals throughout, i.e. L"MyString" instead of "MyString". You also need to use WCHAR/wchar_t in place of char

But how do i do this with my code, could somebody help?

UPDATE 2:

That solved al lot of errors!

But i have some more errors left in this part

Deelnemer deelnemer1;   
    switch(message)
    {
    case WM_PAINT:    
        {     
            //Functieaanroep.Initialisatie     
            deelnemer1.Invoeren();          
            //.TextOut  
        TextOut(hdc,50,50,deelnemer1.WeergevenNaam(),     
            strlen(deelnemer1.WeergevenNaam()));     
            EndPaint(hwnd,&ps);     
            return 0;   
        }

so the errors are on line: deelnemer1.WeergevenNaam()

-TextOutW' : cannot convert parameter 4 from 'char *' to 'LPCWSTR'

-IntelliSense: argument of type "char *" is incompatible with parameter of type "LPCWSTR"

UPDATE 3:

After some testing i found a solution (like you guys said below) But now i only got this one left: TextOut (hdc,50,50,deelnemer1.WeergevenNaam(), // on the deelnemer1.weergevenNaam()
with error C2664: 'TextOutW' : cannot convert parameter 4 from 'const char *' to 'LPCWSTR'

7
  • It would help if you highlighted the line with the error. Commented Aug 27, 2013 at 16:30
  • 1
    Seems that You compile ASCII code with Unicode enabled in VC++. Thus, it says - "cannot convert from 'const char [11]' to 'LPCWSTR'". Check Character-Set set to UNICODE (Project Settings -> Configuration Options -> General Commented Aug 27, 2013 at 16:31
  • Prepend L to all your string literals. You're building with Unicode support. Either turn that off (found on the main project configuration dialog page) or ensure you pass wide strings to the various Windows API's that expect them. Commented Aug 27, 2013 at 16:32
  • and what do i need to do to "compile ASCII code with Unicode enabled in VC++" @NeilKirk? Commented Aug 27, 2013 at 16:33
  • As WhozCraig advised, either turn off Character-Set set to UNICODE (Project Settings -> Configuration Options -> General). Or use w_char types instead of char and prepend "L" to string literals. Commented Aug 27, 2013 at 16:39

5 Answers 5

6

Your code is written to compile as ANSI but your solution settings include _UNICODE/UNICODE. You can either set your solution to use ANSI encoding by changing Character Set (on the General node of the Configuration Properties) from Use Unicode Character Set to Use Multi-Byte Character Set or update your application code (the latter is recommended).

Updating your application requires to use UNICODE string literals throughout, i.e. L"MyString" instead of "MyString". You also need to use WCHAR/wchar_t in place of char (where applicable) and call the wide versions of the Windows API. For many API calls there exists a wide version that has a W at the end, e.g. CreateWindowExW. If you are using the Standard C++ Library you will also want to make sure to use the UNICODE variants where character encoding is necessary (e.g. std::wstring instead of std::string). Additional information can be found at Text and Strings in Visual C++.

A bit more background about what is going on here: The Windows API and Microsoft's CRT implementation can be used to compile code using ANSI/Multi-Byte character set or UNICODE character set. To support both character encodings the C/C++ preprocessor replaces the respective character types and API calls with the specific implementations depending on whether or not the _UNICODE and UNICODE preprocessor symbol is defined.

For example, the call CreateWindowEx is expanded to either CreateWindowExA or CreateWindowExW. Both implementations have different parameter types for string arguments (char* and wchar_t* respectively). To use ANSI/Multi-Byte encoding the call would be CreateWindowExA(NULL,"WNDCLASSEX",...). For UNICODE it would look like CreateWindowExW(NULL,L"WNDCLASSEX",...).

To see what the code looks like after the preprocessor is through you can use the /P or /E compiler switches (assuming you're using the Microsoft Compiler).

Note: Don't forget to read The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Sign up to request clarification or add additional context in comments.

5 Comments

UNICODE seems overkill for a simple school project.
@ThomasMatthews i think so, but how to get it working without it? with wchar? and l""? and everywhere
@Thomas What's overkill about writing L"MyString" in place of "MyString"? You don't have to have a full understanding of UNICODE to use the corresponding types. Dealing with Multi-Byte encoding on the other hand has its own set of intricacies.
@IInspectable - The overkill includes,as your answer states, using wchar and std::wstring. The UNICODE characters also vary in size. If there are no international character sets required, ASCII would suffice. I recommend the OP use Multi-Byte or "no' character set.
@Thomas Again, what's so overkill about using wchar_t in place of char? Plus, if you assume varying UNICODE character sizes, you will have to deal with varying Multi-Byte character sizes, too. That's why they are called Multi-Byte. Of course, as an American, you have not ever seen varying character sizes in your life, regardless of character encoding.
2

simple answer - with no explanation of why

change quoted strings to L"foo"

change char to wchar_t

6 Comments

Please see update 2, what to do with those two errors, @pm100?
thanks for helping, i have 'just' 2 errors left, see UPDATE 2 on my original post above. thanks ;)
change char* to wchar_t*
hi, this gives me this errors: error C2440: '=' : cannot convert from 'const char [4]' to 'wchar_t *' AND error C2664: 'strlen' : cannot convert parameter 1 from 'wchar_t *' to 'const char *' AND IntelliSense: a value of type "const char *" cannot be assigned to an entity of type "wchar_t *" AND IntelliSense: argument of type "wchar_t *" is incompatible with parameter of type "const char *"
Still trying some stuff. but stil get the same errors as wrote above (and by update 2)
|
0

LPCWSTR -> Long Pointer to Constant Wide Character String.

All of your error messages reduce to some form of char[XX] is not the same type as wchar_t[XX].

Microsoft's Win32 API's are designed to compile either with ANSI strings, char, or wide character strings, wchar_t. This is why many Win32 function have two signatures, one ending in A, the other in W.

Example:

CreateWindowExW
CreateWindowExA

CreateWindowEx - A macro that expands to one of the above signatures depending on your build configuration. If you define UNICODE or _UNICODE it will expand to the W version.

Typically you use the macros when you are programming in Win32, and wrap all of your string literals with the _T macro. When defining character arrays that are strings, you'll want to use LPCTSTR and LPTSTR. These are also macros which will expand to either char * or wchar_t * depending on your build settings.

2 Comments

Not all Windows APIs have two signatures, like UpdateWindow. Also, neither LPCTSTR nor LPTSTR expand to array types. They expand to pointer types.
Array syntax is just syntactic sugar for working with pointers to contiguous blocks of memory. So yes, you're correct that LPCTSTR is really just a pointer, but semantically it's intended to convey to the programmer that they are working with a group (array) of characters in memory.
0

I have it working. The use wchar_t * and L"string". The problem with my code was more the structure because copy/pasting to a new project solved my errors. Thanks guys!

Comments

0

By choosing "not set" on Character Set in Project > Property > Configuration Properties > General, I was able to remove errors C2440 and C2264.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.