Using WinAPI with MSVC++

Hi ~

I usually compile my WinAPI code with Dev-C++, but I'm trying it out with MSVC++. However, I get errors when trying to compile... here are the error messages:

-- Build started: Project: WinAPI, Configuration: Debug Win32 --
Compiling...
WinAPI.cpp
c:\documents and settings\christopher\my documents\visual studio 2005\projects\winapi\winapi\winapi.cpp(42) : error C2440: '=' : cannot convert from 'const char [14]' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
c:\documents and settings\christopher\my documents\visual studio 2005\projects\winapi\winapi\winapi.cpp(48) : 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
c:\documents and settings\christopher\my documents\visual studio 2005\projects\winapi\winapi\winapi.cpp(59) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [14]' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
c:\documents and settings\christopher\my documents\visual studio 2005\projects\winapi\winapi\winapi.cpp(64) : 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
c:\documents and settings\christopher\my documents\visual studio 2005\projects\winapi\winapi\winapi.cpp(77) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data
Build log was saved at "file://c:\Documents and Settings\Christopher\My Documents\Visual Studio 2005\Projects\WinAPI\WinAPI\Debug\BuildLog.htm"
WinAPI - 4 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Here is the code that I am trying to compile:

#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;
}

What is wrong?
[4207 byte] By [chrishowarth] at [2007-11-20 10:45:15]
# 1 Re: Using WinAPI with MSVC++
This is due to MSVC++ defaulting to UNICODE compiling, you can tell since the LPWSTR, the W is for Wide.

Theres a couple ways to fix it. You can go into Project Properties(Alt-F7) and under Configuration Properties->General change 'Character Set' from 'Use Unicode Character Set' to either 'Use Multi-Byte Character Set' or 'Not Set'.
You can also use some macros for the strings.

for instance where you have:

MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);

Change those two strings (arguments 2 and 3) to _T("Window Creation Failed!") and _T("Error!") respectively. The _T is just a macro that will convert the string to UNICODE, you can also use the TEXT() macro or just put a 'L' in front of the string like

L"My String";

Note that if you want to use _T() macro you'll need to include 'tchar.h'

I'm not 100% sure what the differences between all these are, if any.
Notsosuperhero at 2007-11-9 13:32:19 >
# 2 Re: Using WinAPI with MSVC++
Thanks. :) Unfortunately, I do now get these errors... -- Build started: Project: WinAPI, Configuration: Debug Win32 --
Linking...
WinAPI.obj : error LNK2019: unresolved external symbol __imp__DefWindowProcA@16 referenced in function "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z)
WinAPI.obj : error LNK2019: unresolved external symbol __imp__PostQuitMessage@4 referenced in function "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z)
WinAPI.obj : error LNK2019: unresolved external symbol __imp__DestroyWindow@4 referenced in function "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z)
WinAPI.obj : error LNK2019: unresolved external symbol __imp__DispatchMessageA@4 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__TranslateMessage@4 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__GetMessageA@16 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__UpdateWindow@4 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__ShowWindow@8 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__CreateWindowExA@48 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__MessageBoxA@16 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__RegisterClassExA@4 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__LoadCursorA@8 referenced in function _WinMain@16
WinAPI.obj : error LNK2019: unresolved external symbol __imp__LoadIconA@8 referenced in function _WinMain@16
MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
C:\Documents and Settings\Christopher\My Documents\Visual Studio 2005\Projects\WinAPI\Debug\WinAPI.exe : fatal error LNK1120: 14 unresolved externals
Build log was saved at "file://c:\Documents and Settings\Christopher\My Documents\Visual Studio 2005\Projects\WinAPI\WinAPI\Debug\BuildLog.htm"
WinAPI - 15 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
chrishowarth at 2007-11-9 13:33:18 >
# 3 Re: Using WinAPI with MSVC++
Do you have the platform SDK properly setup?

I don't know which version you are using but if it is the Express Edition, you have to set it up yourself.
Notsosuperhero at 2007-11-9 13:34:16 >
# 4 Re: Using WinAPI with MSVC++
When you get linker errors but not compiler errors it may mean that you're not linking the proper libraries. Try creating a new project with the wizard. I bet it won't give those linker errors. The reason would be because the wizard set up the linker options to link (if I remember correctly) user32.lib, kernel32.lib and gdi32 or gdi.lib. You could also check MSDN docs for, for instance, PostQuitMessage. In those docs it should mention which library PostQuitMessage is a part of. You then need to add that library in the linker options for your project.
Martin O at 2007-11-9 13:35:21 >
# 5 Re: Using WinAPI with MSVC++
Thanks
chrishowarth at 2007-11-9 13:36:19 >