Sign in to follow this  
NUCLEAR RABBIT

Win32 Programming Problem

Recommended Posts

Hello, Im trying to learn how to do windows programming, but whenever I try, my IDE go wacko! The IDE im using is Visual C++ Express Edition. I installed the PSDK today, so I know thats not the problem because I tried using the incude <windoes.h> and it works. Below is my code and the errors im getting. Note: This is not my code, but I want to know how to fix it so it will work. For some reason, no win32 tutorials I've tried seem to work. Please help me. Thanks for any help! Errors:
1>c:\documents and settings\brandon\my documents\visual studio 2005\projects\psdktesting2\main.cpp(40) : error C2440: '=' : cannot convert 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\brandon\my documents\visual studio 2005\projects\psdktesting2\main.cpp(46) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [28]' to 'LPCWSTR'

1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

1>c:\documents and settings\brandon\my documents\visual studio 2005\projects\psdktesting2\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\brandon\my documents\visual studio 2005\projects\psdktesting2\main.cpp(62) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [24]' to 'LPCWSTR'

1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

1>c:\documents and settings\brandon\my documents\visual studio 2005\projects\psdktesting2\main.cpp(75) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data

Source:
#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, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "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;
}

Share this post


Link to post
Share on other sites
Wrap all your C-strings in the TEXT() macro and use the TCHAR macro for the type. For example,


const TCHAR g_szClassName[] = TEXT ( "myWindowClass" ) ;

The problem is that you are trying to use narrow ASCII strings where you need wide Unicode strings. These macros will use the proper types depending on whether you are building with Unicode support or not.

Share this post


Link to post
Share on other sites
As microdot said, you are trying to use ANSI charset while building Unicode application. Since VS2005 Unicode is the default one (because all WinNT based systems use Unicode internally).

If you still want to use ANSI for all your strings, you can change that in project's properties (General Settings->Character Set). Hovewer, I recommend getting used to Unicode, since it is native format for all newer Windows OSes and it will stay here for a while.

Share this post


Link to post
Share on other sites
Hey guys,

Thanx for the help! I tried doing the TCHAR and the TEXT solutions, but I dont know hw to fix the message box errors with that. I tried, but it doesnt seem to work. I tried changing the character set, and it worked. If anyone knows how to fix the MessageBoxW error, then please help me.

Thanx again!

Share this post


Link to post
Share on other sites
Quote:
Original post by Colin Jeanne
Wrap the strings in your MessageBox() function with TEXT() as well.


Hmm..last time i tried it, it didnt work, but it seemed to have worked this time. Thanks for the help. [smile]

Share this post


Link to post
Share on other sites
Here's a bit more elaborate detail so ya' can get the whole knowledge behind it if you haven't already. =]

Make sure you're aware of all the different string types you're dealing with! I'm sure we've all had issues with it at one point, and sometimes it's easy to miss, especially for a beginner! So, here's a little guide on how to do these things:

There's basically two types of character sets you'll run in to. Unicode and ANSI. They're simple to deal with if you know you're dealing with them and some basics. Here's a little table of what the common string types are what character set, and then I'll go over how to convert between them all (and use them generally). ^.^

ANSI: char* LPCSTR LPSTR CHAR*

UNICODE: LPCWSTR wchar_t* LPWSTR WCHAR*

Now, there's a few things to note about the naming conventions on here. You'll notice that all unicode types have W in them, and all types that're declared as constant have C in them. Also, all types have STR or CHR, there's really not much of a difference, here, though. ~.^ P (or LP, I can't figgure out any purpose to the L besides it looks pretty...) is for pointer. U is for unaligned. (no idea what real purpose, unfortunately...) PZP is for two pointer deep (WCHAR**) types.

Now... how does all that random stuff apply? Well, most of the time it doesn't really matter, as they can be swapped pretty easily among each character sets. In fact, the only real reason you'll need to worry about the difference between PCCHAR, PCHAR, PCH, LPSTR, LPCSTR... and LPCWSTR, LPWSTR, PWSTR, PTBYTE, PCWSTR... is only the few cases where it being constant, etc. makes a difference... I still have yet to run into such a case, though, so... =]

Now, how to convert between them all! There's a very nifty bit of includes you gotta' use to help with this.
#include <atlbase.h>
#include <atlconv.h>
Atlbase.h can be trouble compiling, but it's not too bad. I do beleave under the Express version of VS, it doesn't come with the proper libraries to fully compile it, BUT you can work around it simply by opening the file where it says something like "cannot find include library atlthunk.lib" and comment out the line:
#pragma comment(lib, "atlthunk.lib")
after that, it should compile fine! (this may not be the issue I'm thinking of, but it has been a long time, so forgive me if it isn't! =x)

There's one other caviette I've ran into... I've only been able to get the 'incorrect' method to work! Thusly, the macro's don't think LPCSTR _lpa, LPCWSTR _lpw, and int _convert exist! The fix is simple: just do as I do. =] It works, so what's so wrong about it?

converting from ANSI to Unicode:
// LPCSTR to LPCWSTR
LPCSTR _lpa; // Here's how to fix that issue! simple, eh?
int _convert;

LPCWSTR Dest;
LPCSTR Source="Yo, world.";
Dest=A2W(Source);
/* use Dest, it's now an LPCWSTR that contains "Yo, world."! */

// LPCSTR to LPWSTR
// LPSTR to LPWSTR
// char* to PTBYTE
// ... to ....
/* these are the same as above! */



converting from Unicode to ANSI:
// LPCWSTR to LPCSTR
LPCWSTR _lpw;
int _convert;

LPCSTR Dest;
LPCWSTR Source=L"Yo, world.";
Dest=W2A(Source);
/* use Dest, it's now an LPCSTR that contains "Yo, world."! */

// LPCWSTR to LPWSTR
// LPWSTR to LPWSTR
// wchar_t* to CHAR*
// ... to ....
/* these are the same as above! */



There's just two things to keep in mind when using and converting strings.

1. You're still dealing with pointers (char* is identical to LPSTR), so don't move addresses around and start randomly writing data out! You're asking for trouble. So long as you use them ONLY for strings, you should be fine, as these helper macros allocate the memory for you. (I beleave they also drop it as well, so memory leakage isn't a problem) As far as working with them, as long as you keep in mind char is not equivalent to LPSTR, only char* is, etc. you'll be fine.

2. Unicode strings in the compiler don't work quite the same way as ANSI. I'll illustrate it in code:
LPSTR Hello="Hello, world!";              // this works just fine.
LPSTR Hello2=Hello1; // this is fine but keep in mind that they are essentially the same thing now.
LPCWSTR HelloW="Hello, world!"; // this does NOT work. It will come out garbled if it even compiles without error.
LPCWSTR HelloW2=L"Hello, world!"; // this will work, the text will end up correct due to feeding it into the macro.
LPCWSTR HelloW3=TEXT("Hello, world!"); // exact same meaning as HelloW2. =]
LPCWSTR HelloW3=__TEXT("Hello, world!"); // exact same meaning as HelloW2 again. ^.^



The same concepts apply when just plugging strings into function parameters. If it's wide(unicode), use the macros. =]

Link to the MSDN spot for all this.

Sorry if this is incorrect, I'm not quite a pro by any stretch. :P Feel free to correct/add anything to this. (besides that I'm using the 'incorrect' method... I explained that. =[) Just no flames! they burn...

[Edited by - Motocrossdoug on October 22, 2006 5:47:40 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this