Archived

This topic is now archived and is closed to further replies.

Windows Wrapper : Message Pump Error

This topic is 5147 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I know about enough Win32 to not go, "OMGH WTF IS HWND?!" when I see some Win32 code. Thats pretty much as far as I go =P So OBVIOUSLY I''ve decided to embark on the quest of writing my own Windows Wrapper =P I''m having some problems with the message / message pump though... And that error is, that none of the messages are coming on through. I''ve probably screwed something up in the logic somewhere, so I''m hoping maybe its pretty easy to spot. The window appears and shows just fine, but no messages being sent down the pump are ever received or processed. Heres a snipit from CWindow.h
...
	int Create(DWORD dwExStyle, char *szClassName, char *szWindowName, DWORD dwStyle, int iX, int iY, int iWidth, int iHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
	static LRESULT CALLBACK MessageRouter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	int MessageHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	bool MessageDispatcher(void);
...
Here are my implementations:
int CWindow :: Create(DWORD dwExStyle, char *szClassName, char *szWindowName, DWORD dwStyle, int iX, int iY, int iWidth, int iHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
	m_WndClassEx.cbClsExtra		= 0;
	m_WndClassEx.cbSize			= sizeof(WNDCLASSEX);
	m_WndClassEx.cbWndExtra		= 0;
	m_WndClassEx.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	m_WndClassEx.hCursor		= LoadCursor(hInstance, IDC_ARROW);
	m_WndClassEx.hIcon			= LoadIcon(hInstance, IDI_APPLICATION);
	m_WndClassEx.hIconSm		= LoadIcon(hInstance, IDI_APPLICATION);
	m_WndClassEx.hInstance		= hInstance;
	m_WndClassEx.lpfnWndProc	= MessageRouter;
	m_WndClassEx.lpszClassName	= "Window1";
	m_WndClassEx.lpszMenuName	= NULL;
	m_WndClassEx.style			= CS_OWNDC;

	RegisterClassEx(&m_WndClassEx);

	m_hWnd = CreateWindowEx(	dwExStyle,		// Extended Window Attributes

								szClassName,
								szWindowName,
								dwStyle,
								iX,
								iY,
								iWidth,
								iHeight,
								hWndParent,
								hMenu,
								hInstance,
								lpParam);

	if(m_hWnd == NULL)
		return 1;

	m_hInstance = hInstance;

	return 0;
}

LRESULT CALLBACK CWindow :: MessageRouter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	// Grab A Pointer To Our Window

	CWindow *pWnd = (CWindow *)GetWindowLong(hWnd, GWL_USERDATA);

	if(pWnd)
	{
		pWnd->MessageHandler(hWnd, message, wParam, lParam);
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

int CWindow :: MessageHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_CREATE:
			MessageBox(NULL, "CREATING WINDOW", "...", MB_OK);
			return 0;
		case WM_LBUTTONDOWN:
			MessageBox(NULL, "Left Mouse Pushed", "...", MB_OK);
			return 0;
		case WM_DESTROY:
		case WM_CLOSE:
			PostQuitMessage(0);
			return 0;
	}

	return 1;
}

bool CWindow :: MessageDispatcher(void)
{
	static MSG msg;

	if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	else
	{
		// Compute Stuff Here

	}

	if(msg.message == WM_QUIT)
		return false;

	return true;
}
And heres my WinMain just for kicks.
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
	CWindow Window;
	if(Window.Create(NULL, "Window1", "GroZ32 Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hinstance, NULL) == 1)
	{
		MessageBox(NULL, "Could Not Create Window!", "ERROR", MB_OK);
		return 0;
	}
	Window.Show(SW_SHOWNORMAL);

	while(true)
	{
		if(Window.MessageDispatcher() == false)
			break;
	}

	return 0;
}
As you can see, its pretty much a hacked together version of the article already posted here on GameDev. I''ve just taken some ideas out of it and tried to create my own from scratch. And I mean, its really not going THAT poorly, I just can''t think of why these messages aren''t going through. Thanks guys, if you need more information on anything, feel free to just let me know.

Share this post


Link to post
Share on other sites
I''m not all that familiar with Win32, but...

I think your message handler should be a WND_PROC or something, that is, a pointer to a windows message processor, and use your WND_PROC in the creation of the window.

Or LP_WND_PROC? Something like that.

Wizza Wuzza?

Share this post


Link to post
Share on other sites
i think u should be giving the same name to the class name
so that windows can send ur window the messeges:

m_WndClassEx.lpszClassName = "Window1";

RegisterClassEx(&m_WndClassEx);
and
m_hWnd = CreateWindowEx( dwExStyle, // Extended Window Attributes "Window1",
hope it works and it will

Share this post


Link to post
Share on other sites
I see a couple of problems. First, inside your message router function (wndproc), if you use GWL_USERDATA you need to set it to something. So catch the first message in the message router, I catch WM_NCCREATE, but that''s not really the first message. You have to set GWL_USERDATA to a pointer to your window. If the message is not a WM_NCCREATE, THEN get the value in GWL_USERDATA. Second, you need to pass in a pointer of your window to the CreateWindowEx function to allow access to it inside the message router. Example:

bool Create( ... )
{
...
m_hWnd = CreateWindowEx( ..., (LPVOID)this );
}

LRESULT CALLBACK CWindow::MessageRouter( .... )
{
CWindow * pWindow = NULL;

if( message == WM_NCCREATE )
{
// CreateParams is the pointer to the window instance
LPCREATESTRUCT lpCreate = (LPCREATESTRUCT)lParam;
SetWindowLong( hWnd, GWL_USERDATA, lpCreate->lpCreateParams );
return TRUE;
}
else
{
pWindow = GetWindowLong( hWnd, GWL_USERDATA );
}

if( pWindow ) {
// Handle Message
}
}

Sorry about the formatting, haven''t figured it out yet. But this should work.

Kory

Share this post


Link to post
Share on other sites
EDIT: Figured it out.

Thanks a bunch kspansel for putting me in the right track, really appreciate it.

And thanks r for pointing out that "Window1" discrepancy =)

Thanks a bunch guys! It works beautifully!


[edited by - GroZZleR on November 7, 2003 6:39:38 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

So catch the first message in the message router, I catch WM_NCCREATE, but that''s not really the first message.



WM_NCCREATE is the first message thrown when creating a window.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I think using SetProp() is better than SetWindowLong() as its a bigger chance someone uses SetWindowLong() and if so that will crash his/hers program. However I think SetProp()/GetProp() is slower, but maybe adding an atom can fix the most of those speed issues? Although I don''t think speed is much of a concern in this case.

Share this post


Link to post
Share on other sites