Simple Win32 API errors

Started by
4 comments, last by Spoonbender 16 years, 10 months ago
I have a problem with getting a simple Win32 application to get working. Any ideas? code = http://rafb.net/p/O9M08w64.html error = http://rafb.net/p/u07zY961.html OR LOOK HERE:

#include <windows.h>
 
const char g_szClassName[] = "myWindowClass";
 
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
 
    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"),
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
 
    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        TEXT("The title of my window"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);
 
    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
 
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
 
    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
ERROR is below:

1>------ Build started: Project: winsome, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>c:\documents and settings\eric\my documents\visual studio 2005\projects\winsome\winsome\main.cpp(40) : error C2065: 'Lg_szClassName' : undeclared identifier
1>c:\documents and settings\eric\my documents\visual studio 2005\projects\winsome\winsome\main.cpp(57) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [14]' to 'LPCWSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\documents and settings\eric\my documents\visual studio 2005\projects\winsome\winsome\main.cpp(75) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data
1>Build log was saved at "file://c:\Documents and Settings\Eric\My Documents\Visual Studio 2005\Projects\winsome\winsome\Debug\BuildLog.htm"
1>winsome - 2 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Any help would be appreciated. thanks!
Advertisement
You have UNICODE enabled in your project settings.

So the call to CreateWindowEx is expecting a LPCWSTR string not an LPCSTR that you are giving it.

To fix it you can either do:
a) Disable UNICODE by going to the project proprties. Configuration Properties -> General, and for Character Set choose 'None'. If you do that you can remove the TEXT() macros you are using for the other strings they are using.
b) Change the declaration of g_szClassname to a wchar_t, or LPCWSTR
Raven Software :: Tools Programmer
[Ravensoft] [My Site] [Full Sail]
I keep hearing about this UNICODE stuff. I'm actually using Win XP Pro SP2. What effect would it have on me turning this off through the project settings?

Generally what does this mean, and why would anyone want it "turned on" if all it does is cause compiler issues?
Enabling Unicode will allow you to use a wider range of text and symbols, for localization to other languages. So you only need it if you are going to support foreign languages where you can't show all their characters using ascii.
Raven Software :: Tools Programmer
[Ravensoft] [My Site] [Full Sail]
Perfect explanations thanks!
Quote:Original post by Instigator
I keep hearing about this UNICODE stuff. I'm actually using Win XP Pro SP2. What effect would it have on me turning this off through the project settings?

Generally what does this mean, and why would anyone want it "turned on" if all it does is cause compiler issues?


The simple explanation is this:
in C++, a regular char is only 1 byte wide. That's not enough to represent international characters. Hence the need for bigger characters.
Enter the unicode character set. This is an absolutely huge list of pretty much any character you can imagine. And to fit this into C++, you have two options. Either use variable-length characters using UTF8 (Windows will do this if you disable Unicode), which means that ASCII characters are represented as single bytes, but everything else are made up of multiple bytes. This works, but makes manipulating strings much more complicated (you need to scan through a string to determine the number of characters in it, instead of simply being able to look at its length in bytes. And you can't just split a string at arbitrary positions because you might chop a character into two.
Alternatively, you can use bigger fixed-width characters. That's what you get when you enable unicode in your Win32 project.

To use unicode, you need to use:
- wchar_t instead of char (wchar_t is a wide char, under Windows this is 16 bit)
- L"foo" instead of "foo" (the L tells the compiler to make a LONG character literal, that is, a wchar_t* instead of a char*)
- std::wstring instead of std::string (and the same for std::wcout, std::wstringstream and so on)

And no, it doesn't cause compiler issues.
But consider an API containing functions that take or returns characters or strings. If a function expects a string, do you give it a wchar_t* or a char*?
The answer is, it depends on the API, of course.
In the case of the Win32 API, it can use both. The entire API is implemented twice, once using Unicode, and once without. And which one gets used depends on your compiler settings.

If you have Unicode enabled, then *all* Win32 functions will expect wchar_t where they otherwise would have expected char. if you give them a char, you get an error.
The solution is fairly simple. Either disable unicode, or just give the functions the correct arguments. Or explicitly call the version you want. To give an example, CreateWindow is actually just a macro. One that maps to either CreateWindowA (for ASCII) or CreateWindowW (for Wide), depending on whether Unicode is enabled. The *A functions use char's, the *W functions use wchar_t. So if you have unicode enabled, but want to, say, show a message box with a non-unicode string, you just call MessageBoxA instead of MessageBox.

This topic is closed to new replies.

Advertisement