RegisterClassEx keeps failing...

Started by
6 comments, last by freeworld 15 years, 2 months ago
I'm trying to create a window class, placing all the windows code into the class. but when I run the prgram RegisterClassEx keeps failing. I try'd using GetLastError() but it wasn't returning anything? I'll try to only include the most relevant code. My register function

bool zesys::Window::Register(HINSTANCE instance)
{
	// fill in the window class  default data
	m_window_class.cbSize        = sizeof(WNDCLASSEX);
	m_window_class.lpfnWndProc   = (WNDPROC)Window_Procedure;
	m_window_class.cbClsExtra    = 0;
	m_window_class.cbWndExtra    = 0;
	m_window_class.hInstance     = instance;
	m_window_class.hIcon         = NULL;
	m_window_class.hCursor       = LoadCursor( NULL, IDC_ARROW );
	m_window_class.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
	m_window_class.lpszMenuName  = NULL;
	m_window_class.lpszClassName = L"ZoloEngine";
	m_window_class.hIconSm       = NULL;

	ATOM result;
	result = RegisterClassEx( &m_window_class );

	// make sure the class got registered
	if ( result == 0 )
	{
		MessageBox( NULL, L"Failed to register window!", L"Engine::System Failure!", MB_OK );
		return false;
	}


	return true;
}

Window_Procedure is a static function within the class that does nothing at the moment. All that's in my winmain file is

int WINAPI WinMain( HINSTANCE instance, HINSTANCE previnstance, LPSTR cmdline, int cmdshow)
{
	zesys::Window Window;
	Window.Register( instance );
	Window.Create( instance, cmdshow );


	return 0;
}

Create just calls CreateWindow() with the most basic information. I try'd inserting GetLastError() into the error check inside the register function by replacing its call to messagebox like so.


MessageBox( NULL, "Failure", LPCWSTR( GetLastError() ), MBOK );


everything compiles, but both function fail?
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Advertisement
GetLastError() returns an integer, not a string. You can use std::stringstream or sprintf to convert it to a string.

Also, never ever do this:
m_window_class.lpfnWndProc = (WNDPROC)Window_Procedure;
If it doesn't compile without the cast there then there's something wrong with your Window_Procedure, and forcing the cast will just cause a crash (if you're lucky) at runtime, anf if you're unlucky you'll get "interesting" behaviour.
You really need to be more careful with your casting. First of all, if you're using C++ then you'll want to ditch the C-style cast. C++ has casting operators that can prevent mistakes and make your code easier to understand.

Having said that, don't cast function pointers unless you're 1000% sure you know what you're doing. Casting a function pointer has the possibilty to cause some insanely bizarre errors if you do it wrong. In your case you should have no reason to do it: the signature of your Window_Procedure function should match that of WNDPROC and you should have no problem assigning it to your WNDCLASSEX struct. If you take away the cast and it doesn't compile, then you screwed up the function signature and you should figure out what you did wrong.

The reason your MessageBox for displaying the error code isn't working is again because of casting. GetLastError returns a DWORD, which is a typedef of an unsigned long. In other words, it returns an unsigned 32-bit integer. MessageBox (or actually, MessageBoxW) on the other hand takes an LPCWSTR, which is a typedef for "constant wchar_t*"...in other words a C-string. As you surely know, an unsigned integer is not a string. I'm sure the compiler told you this when you wrote that code, however sticking that cast in there is the equivalent of saying "shut up compiler, I know what I'm doing!".

As the documentation for GetLastError indicates, if you want a string representation of your error code you should use the FormatMessage function. An easier alternative would be to set a breakpoint in the debugger, store the value of GetLastError in a variable, look a the value of the variable, and then look up the error code here.
Quote:Original post by Evil Steve
GetLastError() returns an integer, not a string. You can use std::stringstream or sprintf to convert it to a string.

Also, never ever do this:
m_window_class.lpfnWndProc = (WNDPROC)Window_Procedure;
If it doesn't compile without the cast there then there's something wrong with your Window_Procedure, and forcing the cast will just cause a crash (if you're lucky) at runtime, anf if you're unlucky you'll get "interesting" behaviour.


ok I got rid of the type casting ie.(WNDPROC).
and change the getlasterror code to.

// make sure the class got registered	if ( result == 0 )	{		std::stringstream ss;		ss << GetLastError();		MessageBox( NULL, L"Failed to register window!", LPCWSTR( ss.str().c_str() )/*L"Engine::System Failure!"*/, MB_OK );		return false;	}


but its not showing up as a number, it's just appears as a bunch of squares?
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
std::stringstream uses narrow characters, and you're trying to pass it to a wide character function. This is not kosher. Try using a wstringstream.
Again: ditch the cast. std::stringstream uses strings of char's, not wchar_t's. You have to either convert from multi-byte to Unicode (hard), or use std::wstringstream (easy).
Thank you guys on all that information, never had an error with that kind of stuff, but I'll read up on it.

It returns Error 87 ERROR_INVALID_PARAMETER
"The parameter is incorrect"

That's rather vague, and I can't think what parameter would be wrong or am I leaving something out?

[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Figured it out, I wasn't setting the style parameter... well new problem, CreateWindow return a NULL handle and GetLastError returns 0?

m_window = CreateWindow( "ZoloEngine", // window name 							 "Application Name", // title bar description							 WS_OVERLAPPEDWINDOW, // window style							 CW_USEDEFAULT, // starting x position							 CW_USEDEFAULT, // starting y position							 800, // width of the window							 600, // height of the window							 NULL, // parent window and probably never going to be needed							 NULL, // menu and probably never going to be needed							 instance, // application instance							 NULL); // window parameters


EDIT Figured it out, thanks you guys for all the insight.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.

This topic is closed to new replies.

Advertisement