Hi, this time I've borrowed a book called "Windows Game Programming for Dummies", albeit old it is still useful!

However, I came across a problem writing a simple code the author made, namely the TextOut()

The error it gives me at build time is as follows:

1>c:\users\shadow\documents\visual studio 2008\projects\g_app\g_app\main.cpp(75) : error C2664: 'TextOutW' : cannot convert parameter 4 from 'char [80]' to 'LPCWSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

And here is a small snippet of the code:
As you can see, it is a win32 application callback func... xD

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;
	char buffer[80];
	static int counter = 0;
    switch( message )
    {
        case WM_PAINT:
			{
            hdc = BeginPaint( hWnd, &ps );
			
			int length = sprintf( buffer, "The Count is %d   ", (int)counter++);
			TextOut(hdc, 0, 0, buffer, length);
            EndPaint( hWnd, &ps );
			}
            break;
		case WM_MOUSEMOVE:
			break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;

        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}

I also know that you should use static_cast<> instead of the old one, but it was just an example.(Oddly enough (LPCWSTR)buffer works, but all it does is show some gibberish symbols, like chinese) The question is obvious:
Why doesn't it work?
I have searched the net as I always do in these situations, and no site came close to answering my question (at least none that I could find)...

Remember that I am quite the novice on the subject so keep it in layman's terms. Now, let me also ask another question, possibly regarding the same subject.

Earlier in the book when the author explained the MessageBox() func, this couldnt compile:

MessageBox( NULL, "Blabla", "Meh", MB_OK);

And, after searching the net, I found that this works:

MessageBox( NULL, L"Blabla", L"Meh", MB_OK);

Why is this? does it have to do with the current problem?

Solution needs to be understandable, and explained!

Help! :icon_sad:

Full code for testing:

#include <windows.h>
#include <string>
#include <stdlib.h>

HINSTANCE   g_hInst = NULL;
HWND        g_hWnd = NULL;

HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK    WndProc( HWND, UINT, WPARAM, LPARAM );

int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
    // Main message loop
    MSG msg = {0};
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    return ( int )msg.wParam;
}


HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
    // Register class
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );//(HBRUSH)8;
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"RPG";
    wcex.hIconSm = LoadIcon( wcex.hInstance, IDI_APPLICATION);
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;

    // Create window
    g_hInst = hInstance;
    RECT rc = { 0, 0, 1024, 768 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"RPG", L"RPG Infinitus", WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
                           NULL );
    if( !g_hWnd )
        return E_FAIL;

    ShowWindow( g_hWnd, nCmdShow );

    return S_OK;
}


LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;
	char buffer[80];
	static int counter = 0;
    switch( message )
    {
        case WM_PAINT:
			{
            hdc = BeginPaint( hWnd, &ps );
			
			int length = sprintf( buffer, "The Count is %d   ", (int)counter++);
			TextOut(hdc, 0, 0, buffer, length);
            EndPaint( hWnd, &ps );
			}
            break;
		case WM_MOUSEMOVE:
			break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;

        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}

Since I can't edit anymore, I'm bumping it or something... I really need help here, I can't continue my studies until this phenomena has been explained! :(

As your compiler indicates that you're calling TextOutW(), the unicode version of TextOut(), it appears that you have set an option in your project to compile for unicode (or it was the default). The problem this gives you is that char buffer[80] is not suitable for a unicode string. Casting this string to LPCWSTR satisfies the compiler but as the string is in the wrong format TextOutW() cannot use it.
The snippet from the book is clearly not written for unicode, so track down that compiler option and disable it.
Can't help with that as you don't indicate which IDE you're using.

Ah, I'm using Visual express c++, but I tried changing it from unicode to multi, but it gave me a different amount of errors. Now that you know what I'm using, know anything I could do? In the meantime, I'll keep playing a bit with the VC++. Thanks so far, I guess you pinpointed the problem, how about using the L"string" does that convert the string into something other than unicode?

Ah, I'm using Visual express c++, but I tried changing it from unicode to multi, but it gave me a different amount of errors. Now that you know what I'm using, know anything I could do? In the meantime, I'll keep playing a bit with the VC++. Thanks so far, I guess you pinpointed the problem, how about using the L"string" does that convert the string into something other than unicode?

Try changing the "Character Set" property to "not set" instead of multi.

commented: It worked, thanks :) +1

Oh my, it worked, although I didn't realize it last night, you could have it in multicode, but since I used L"String" it gave errors on that instead. It also works if it isn't set. Thanks MrSpigot.

I tried this before posting, but I didn't look through the error messages it gave off when I had changed it. I've learned my lesson, always look on the error messages.

Can you explain why L"String" works if you use unicode? is there a way to keep unicode and make this work?
(Continuing thread, but marking it as solved)

Can you explain why L"String" works if you use unicode? is there a way to keep unicode and make this work?
(Continuing thread, but marking it as solved)

L"String" generates a constant string in unicode format, so if you compile for unicode, these strings are what you need for compatibility with the unicode specific functions like TextOutW().
If you want to try it under unicode, you could modify these lines in WndProc():

wchar_t buffer[80]; // make buffer into wide chars
int length = wsprintf(buffer, L"The Count is %d ", 1); // Use unicode compatible sprintf and L"String"

I haven't tried it myself, so no guarantees, but hopefully that will allow it to compile and run under unicode.

It worked splendidly! And you explained it well; you have my thanks.

I tried something similar not too long ago, when I googled the problem, it did suggest wchar_t (wide chars) like you just did, but I didn't think about the wsprintf() at that time, and thoughtless as I am, I didn't take the error messages into consideration either... I need to learn to check the error messages!...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.