I am trying to create a simple window with C/C++ using the native Windows message queue system (without .NET). I followed the MSDN tutorial and wrote some basic code that creates an empty window:
void main()
{
HINSTANCE hinst;
HWND hwndMain;
WNDCLASSEX wnd;
MSG msg;
hinst = GetModuleHandle( NULL );
memset( &wnd, 0, sizeof( wnd ) );
wnd.cbSize = sizeof( wnd );
wnd.lpszClassName = "MainWClass";
wnd.lpfnWndProc = MainWProc;
wnd.hInstance = hinst;
int result = RegisterClassEx( &wnd );
if( !result )
{
printf("RegisterClassEx error: %d\r\n", GetLastError() );
}
hwndMain = CreateWindowEx
(
0, //extended styles
wnd.lpszClassName, //class name
"Main Window", //window name
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL | WS_MINIMIZEBOX, //style tags
CW_USEDEFAULT, //horizontal position
CW_USEDEFAULT, //vertical position
CW_USEDEFAULT, //width
CW_USEDEFAULT, //height
(HWND) NULL, //parent window
(HMENU) NULL, //class menu
(HINSTANCE) wnd.hInstance, //some HINSTANCE pointer
NULL //Create Window Data?
);
if( !hwndMain )
{
printf("Oh shi- %d\n", GetLastError() );
}
ShowWindow( hwndMain, SW_SHOWDEFAULT );
UpdateWindow( hwndMain );
}
When I run/debug the program, CreateWindowEx returns 0 which means it failed. This triggers the error message "Oh shi- [error code]". The most confusing part is that the error message prints to console:
Oh shi- 0
The error code returned by GetLastError() is 0, which is ERROR_SUCCESS!
I am at a total loss; what is happening? I am so confuse...
P.S. I am using Visual C++ Express 2010 on Windows 7 32-bit. I have written a Windows Procedure elsewhere but it simply returns 0 for all cases. If, however, anyone wants to see it, I will be happy to show it.
I have changed the Project Default character set of my Visual C++ project to "Not Set". I should not need to prefix L to my things.
Edit: added wnd.hInstance = hinst;
Edit: removed the unnecessary (WNDPROC) cast
Edit: added error checking for RegisterClassEx
It turns out that the problem was with Visual C++ Express (or at least not with the code itself). I copied the code to another project and it worked.
wnd.lpfnWndProc = (WNDPROC) MainWProc;
We can't see the real reason you need to use the cast but it is very fishy. Windows returns 0 from GetLastError() if it didn't see anything going wrong. Which can happen if the window procedure is broken. Like this one:
LRESULT CALLBACK MainWProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return 0;
}
Windows sends the WM_NCCREATE message to ask for the window to be created. If that message doesn't get processed then there will be no window. And no error. Fix:
LRESULT CALLBACK MainWProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Tweak as necessary to customize the window. Just make sure that DefWindowProc() gets called for every message that you don't want to handle yourself. And keep Petzold close at hand to avoid the simple mistakes. And lose the cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With