I'm a newbie to c++, and I'm stuck on displaying the window. I'm not getting any errors, but my Window is not displaying on the desktop. When I open the task manager, it appears under the 'Proccesses' tab. I haven't been finding any solutions to this problem, so any help is appreciated. Thanks! :)
**Note: I'm using Microsoft Visual Studio 2012 **Note: Not exactly a newbie to c++, but more to creating a win32 application
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
static TCHAR WindowClass[] = L"Window";
LRESULT CALLBACK WindowProc(
HWND WinH,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
switch (Msg)
{
PAINTSTRUCT pntStruct;
static HDC hdc;
case WM_PAINT:
{
BeginPaint(
WinH,
&pntStruct
);
TextOut(hdc,
5, 5,
L"Hello, World!", _tcslen(L"Hello, World!"));
//pntStruct.rcPaint
EndPaint(
WinH,
&pntStruct
);
} break;
case WM_SIZE:
{
} break;
case WM_MOVE:
{
} break;
case WM_DESTROY:
{
} break;
case WM_CLOSE:
{
} break;
default:
{
return DefWindowProc(WinH, Msg, wParam, lParam);
} break;
case WM_ACTIVATEAPP:
{
if (WM_ACTIVATEAPP)
{
OutputDebugStringA("WM_ACTIVEAPP->TRUE");
}
else
{
OutputDebugStringA("WM_ACTIVEAPP->FALSE");
}
} break;
}
return 0;
};
int WINAPI WinMain(
HINSTANCE Window,
HINSTANCE PrevInstance,
LPSTR Cmd,
int CmdShow
)
{
WNDCLASSEX wclass;
//wclass.cbSize = sizeof(WNDCLASS);
wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wclass.lpfnWndProc = WindowProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = Window;
//wclass.hIcon; TODO: CREATE ICON
//wclass.hCursor;
//wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = (LPCTSTR)WindowClass;
// HICON hIconSm;
RegisterClassEx(&wclass);
HWND CreateWin = CreateWindow(
WindowClass,
L"NAME OF WINDOW",
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
0,
0,
Window,
0
);
ShowWindow(CreateWin, CmdShow);
UpdateWindow(CreateWin);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
};
return 0;
};
There are lots of things wrong with this code.
You are declaring WindowClass
as a TCHAR[]
, but initializing it with a wchar_t[]
. Same thing with the lpString
parameter of TextOut()
. That will only work if UNICODE
is defined for the project, otherwise you will get a compiler error. When you use TCHAR
, you need to wrap string literals with the TEXT()
macro so they use the correct character type. Otherwise, stop using TCHAR
and just use Unicode APIs for everything. You only need to use TCHAR
if your code needs to support both ANSI (Win9x/ME) and Unicode (NT4+) compilations. Nobody really supports Win9x/Me anymore, so new code should focus on just Unicode APIs.
You are not zeroing the contents of the WNDCLASSEX
structure, so all of the fields that you have intentionally commented out and not assigned values to (most importantly, the cbSize
field) will contain random values from the stack. That is likely to cause RegisterClassEx()
to fail, which you are not checking for. To avoid this problem, ALWAYS zero out API structures before using them. This is especially important for structures that grow in size over time (when newer Windows releases introduce new structure fields). Such structures typically have a cbSize
field so the API knows which version of the structure you are using, so you must provide an accurate value. And you need to zero out any unused fields so you do not get unexpected behavior from the API.
You are not checking if CreateWindow()
fails, such as a side effect of RegisterClassEx()
failing.
Your WindowProc()
is supposed to pass unhandled messages to DefWindowProc()
, but you are not doing that. Most of your case
blocks are simply discarding messages so Windows cannot process them. Is that what you really want? I doubt it. In particular, the default behavior of DefWindowProc()
for WM_CLOSE
is to destroy the window, triggering the WM_DESTROY
message.
Your WM_DESTROY
handler is not calling PostQuitMessage()
to put a WM_QUIT
message into the calling thread's message queue so GetMessage()
can return 0 to break your message loop and let the app exit.
Your WM_PAINT
handler is not using the HDC
that BeginPaint()
provides to you, you are drawing using an uninitialized HDC
variable.
With all of that said, try something more like this:
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h> // Or: remove this
static TCHAR WindowClass[] = TEXT("Window");
// or: static WCHAR WindowClass[] = L"Window";
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
static const TCHAR* HelloWorld = TEXT("Hello, World!");
// or: const WCHAR* HelloWorld = L"Hello, World!";
PAINTSTRUCT pntStruct = {0};
HDC hdc = BeginPaint(hWnd, &pntStruct);
TextOut(hdc, 5, 5, HelloWorld, _tcslen(HelloWorld));
// or: TextOutW(hdc, 5, 5, HelloWorld, lstrlenW(HelloWorld));
EndPaint(hWnd, &pntStruct);
break;
}
case WM_SIZE:
{
//...
break;
}
case WM_MOVE:
{
//...
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
case WM_CLOSE:
{
//...
break;
}
case WM_ACTIVATEAPP:
{
if (WM_ACTIVATEAPP)
{
OutputDebugString(TEXT("WM_ACTIVEAPP->TRUE"));
// or: OutputDebugStringW(L"WM_ACTIVEAPP->TRUE");
}
else
{
OutputDebugString(TEXT("WM_ACTIVEAPP->FALSE"));
// or: OutputDebugStringW(L"WM_ACTIVEAPP->FALSE");
}
break;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wclass = {0}; // Or: WNDCLASSEXW
wclass.cbSize = sizeof(wclass);
wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wclass.lpfnWndProc = &WindowProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = NULL; // TODO: CREATE ICON
wclass.hCursor = NULL;
wclass.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = WindowClass;
wclass.hIconSm = NULL;
if (!RegisterClassEx(&wclass)) // Or: RegisterClassExW()
{
// error! Use GetLastError() to find out why...
return 0;
}
HWND hCreateWin = CreateWindow( // Or: CreateWindowW()
WindowClass,
TEXT("NAME OF WINDOW"), // Or: L"NAME OF WINDOW"
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
0,
0,
hInstance,
0
);
if (!hCreateWin)
{
// error! Use GetLastError() to find out why...
return 0;
}
ShowWindow(hCreateWin, nCmdShow);
UpdateWindow(hCreateWin);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
};
return 0;
};