The following is a portion of my code. Every time I run the program, CreateWindowEx
of the SPanel returns NULL
, triggering an error. Can anyone see what is wrong with this piece of code?
SPanelProc
and MainWndProc
are declared already, and is of the prototype LRESULT CALLBACK SPanelProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
.
The environment I'm programming in is Visual C++ 2010.
Why is CreateWindowEx
always returning NULL
?
#include <Windows.h>
#include <WindowsX.h>
LRESULT CALLBACK SPanelProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_MOUSEMOVE:
break;
}
return 0;
}
void Init ()
{
HWND child;
HINSTANCE hInstance = (HINSTANCE)(GetWindowLongPtr (parent, GWLP_HINSTANCE));
WNDCLASSEX wc;
const char PanelClassName[] = "SPanel"; //ClassName of the panel. Do not reuse on another window
//Create the window, initialize GWLP_USERDATA, check for errors, register the window class, and hide the window
//Create the windowclass for the button
wc.cbSize = sizeof (WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = SPanelProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor (hInstance, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = PanelClassName;
wc.hIconSm = LoadIcon (hInstance, IDI_APPLICATION);
//If could not register window class
if(!RegisterClassEx (&wc))
{
MessageBox (NULL, "Panel registration failed!", "Error!", MB_OK);
PostQuitMessage (0);
return;
}
//Create window
child = CreateWindowEx (WS_EX_NOPARENTNOTIFY, PanelClassName, "TITLE_TEXT", WS_CHILD, 0, 0, 400, 200, parent, NULL, hInstance, NULL);
//Check for error in window creation
if (child == NULL)
{
MessageBox (NULL, "Panel creation failed!", "Error!", MB_OK);
PostQuitMessage (0);
return;
}
return;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG Msg;
int length, width;
//Register the window, create the window, and check for errors
{
//Window class
wc.cbSize = sizeof (WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //Instance used to create the window
wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_CODERICON)); //Change here to change large application icon
wc.hCursor = LoadCursor (hInstance, IDC_ARROW); //Change here to change application cursor
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //Change here to change starting background color (white)
wc.lpszMenuName = NULL;
wc.lpszClassName = Coder::Constants::MAINWNDCLASSNAME;
wc.hIconSm = (HICON)LoadImage (hInstance, MAKEINTRESOURCE (IDI_CODERICON), IMAGE_ICON, GetSystemMetrcs (SM_CXSMICON), GetSystemMetrics (SM_CYSMICON), 0); //Change here to change application icon (small, as in taskbar)
//Register the window class so that the ClassName can be used to create the window and then check for error
if (!RegisterClassEx (&wc))
{
MessageBox (NULL, "Main window registration failed!", "Error!", MB_OK);
return 0;
}
//Get screen dimensions
length = GetSystemMetrics (SM_CXSCREEN);
width = GetSystemMetrics (SM_CYSCREEN);
//Create window
hWnd = CreateWindowEx (WS_EX_CLIENTEDGE, /*Border*/
Coder::Constants::MAINWNDCLASSNAME,
Coder::Constants::MAINWNDTITLETEXT, /*Title of window*/
WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN, /*Window style*/
(length - Coder::Constants::XDEFAULT - Coder::Constants::XSHIFT) / 2, (width - Coder::Constants::YDEFAULT - Coder::Constants::YSHIFT) / 2, /*Top-left x and y coordinates*/
Coder::Constants::XDEFAULT + Coder::Constants::XSHIFT, Coder::Constants::YDEFAULT + Coder::Constants::YSHIFT, /*Lengths and widths of window*/
NULL, NULL,
hInstance, NULL);
//Check for error in window creation
if (hWnd == NULL)
{
MessageBox (NULL, "Main window creation failed!", "Error!", MB_OK);
return 0;
}
}
//Call function
Init (hWnd);
//Show and redraw the window
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
//Put window in message loop
while (GetMessage (&Msg, NULL, 0, 0) > 0) //While not terminated
{
TranslateMessage (&Msg);
DispatchMessage (&Msg);
}
//Return
return static_cast<int>(Msg.wParam);
}
Every window procedure MUST return DefWindowProc(hwnd,msg,wparam,lparam)
on every message, with exceptions on messages like WM_ERASEBKGND
and WM_PAINT
when you are using your custom painting procedure (you must return 0 so the OS doesn't the repaint the window with it's default procedure)