WinAPI and VC++ 2005

Started by
4 comments, last by Grant1219 17 years, 9 months ago
I finally decided to try learning the WinAPI, but when I tried building the code below in Visual C++ 2005, it gave the errors following the code. The thing is this code builds perfectly in Visual C++ 6. I'm not sure if the difference is with the project settings or something else. #include <windows.h> static char g_szClassName[] = "MyWindowClass"; static HINSTANCE g_hInst = NULL; LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; g_hInst = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = g_hInst; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = g_szClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL); return 0; } hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, g_hInst, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } Here are the errors. winmain.cpp .\winmain.cpp(41) : error C2440: '=' : cannot convert from 'char [14]' to 'LPCWSTR' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast .\winmain.cpp(47) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [28]' to 'LPCWSTR' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast .\winmain.cpp(57) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'char [14]' to 'LPCWSTR' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast .\winmain.cpp(62) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [24]' to 'LPCWSTR' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast .\winmain.cpp(74) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data
Advertisement
Go to your project properties, under general, change the Character Set setting to "Use Multi-Byte Character Set"

Most Windows API functions and structures come in two versions: a narrow character version and a wide character version. These are also known as ANSI and Unicode versions. For example, CreateWindow() is actually two functions: CreateWindowA() and CreateWindowW(). A macro transformation maps CreateWindow() calls to one of these two functions depending on what preprocessor definitions are in effect. If UNICODE is defined, CreateWindow() is actually CreateWindowW(). If it isn't defined CreateWindow() is actually CreateWindowA(). In MSVC, the Character Set project property controls whether or not UNICODE is defined.

The difference between the two versions is that the ANSI versions use CHARs for their character type in strings. The wide character versions use WCHARs for their character types. Normal string literals in C++ are narrow characters, which is what the CHAR type works out to. However, WCHAR eventually turns into wchar_t, not char, and pointers to normal char strings are not compatible with pointers to wchar_ts. In order to create a wchar_t string literal you would prefix the string with L. For example "this is a narrow character string" vs. L"this is a wide character string".
Visual C++ 2005 uses UNICODE by default. Either use wide strings, or change your project to use a Multi-Byte or Single-Byte character set by going to Project->Properties->Configuration Properties->General->Character Set and set that to "Use Multi-Byte Character Set" or "Not Set".

[edit: aghh... ]
Thanks for the solution and the explanation too. That helped me understand the difference rather than just telling me how to fix it. Also, is the any reason to set the Character Set to Unicode? Because I have seen L"string" before.
Well, not to be overly obvious, but you'd use Unicode if you want to use Unicode. For example: if you want to have "三.txt" as a file name, or even just display "三.txt" on the screen (assuming you have a Unicode font that properly displays CJK unified ideographs).
Oh ok, lol sorry for the dumb question. Thanks again for the help.

This topic is closed to new replies.

Advertisement