I am trying to create a simple window, but I had some problem. Compiler won't give error, but it simply can't create the hWnd of the window. Also it says that "msg" variable is being used without being initialized. It is not an error, just a warning, however I feel uncomfortable. It says "unused CXX0030: Error: expression cannot be evaluated" when I click to the hWnd table in the debug screen. Here is the code:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "Breakout_Test";
wcex.hIconSm = NULL;
if(!RegisterClassEx(&wcex))
return 0;
hWnd = CreateWindowEx(NULL, "Breakout_Test", "Breakout Test (DirectX 9)", WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Your message loop is all wrong. The compiler is quite right that you are not initializing msg
. I'm not sure where you got that message loop from. Here's the standard one:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
If you want to use a non-blocking PeekMessage
based loop which seems popular for DirectX applications, it might look like this:
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// game code here
}
}
Notice that we initialise msg
before entering the while
loop which tests msg.message
.
Your other big problem is in your window procedure. You don't return the value that you get back from DefWindowProc
. The default
handler should look like this:
return DefWindowProc(hWnd, message, wParam, lParam);
Your broken window procedure is the reason why CreateWindowEx
fails. A broken window procedure is one of the classic failure modes for CreateWindowEx
.
Make these two changes and your program will work.
For people like Remy, who are worried about the fact that GetMessage
returns -1
when it fails, Raymond Chen explains why you don't need to worry about that, at least for this message loop.