Jump to content
  • Advertisement
Sign in to follow this  
chadsxe

Why is a message always there when I PeekMessage() - can't exit past PeekMessage loop

This topic is 3269 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

Hi, I am having a little trouble with my game loop. As of now everytime I check if there is a message via PeekMessage it is NEVER empty. Hear is my loop... Loop
bool Application::Run()
{
	if ( m_loaded == true)
	{
		// display the window on the screen
		ShowWindow(m_window.GetWindow(), SW_NORMAL);
		UpdateWindow( m_window.GetWindow() );

		MSG msg;  // message from window
		ZeroMemory(&msg, sizeof(MSG));

		// forever
		while(msg.message != WM_QUIT)
		{
			//Update High-rez timer
			m_timer.Update();

			// Check for message
			while(PeekMessage(&msg,NULL,0,0, PM_REMOVE)) 
			{
				// translate messages into the right format
				TranslateMessage(&msg); 

				// send the message to the WindowProc function
				DispatchMessage(&msg);  
			}
				// Update our inherited application
				UpdateApp();

				// Update the current state (if there is one), taking state
				// changes into account.
				m_stateManager.Update();

				// Render the state
				m_stateManager.Render();
		}
	}

	// Call our inherited application
	ShutdownApp();

	return true;
}


As you can see I am using a while loop to process all message. The problem is if I place a break point just outside of the while loop (Lets say on UpdateApp()) it will never reach it. Now for the rest of the story. I am trying to implement a "MessageHandler" class. This will allow me to access various parts of my program inside my WindowProc. Hear is the one fucntion inside of that class.. Message Handler..
LRESULT MessageHandler::WindowMessanger(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg ) 
	{
		case WM_GRAPHNOTIFY:
			return 0;
		case WM_PAINT:
			return 0;
		case WM_ENTERSIZEMOVE:
			return 0;
		case WM_DESTROY: 
			// close the application entirely
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


When I create a window I pass a pointer of the MessageHandler class to the user data portion of the window like so.
HRESULT Window::GenerateWindow( HINSTANCE instance, bool windowed )
{
	MessageHandler *messageHandler = new MessageHandler();

	// Set up or style depending on windowed or not windowed
	DWORD style;
	if( windowed )
		style = WS_BORDER | WS_CAPTION | WS_SYSMENU;
	else
		style = WS_EX_TOPMOST | WS_POPUP;

	// create the window and use the result as the handle
	m_window = CreateWindowEx(NULL,
		m_className.c_str(),
		m_captionName.c_str(),
		style,
		m_windowXPos, m_windowYPos,
		m_windowWidth, m_windowHeight,
		NULL,
		NULL,
		GetModuleHandle(NULL),
		/*NULL*/(LPVOID)messageHandler);

	// Make sure the window was created
	if(!m_window)
		return E_FAIL;

	return S_OK;
}


Finally my WindowPrc function is defined like so
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	MessageHandler *messageHandler;

	// Upon app creation
	if( message == WM_CREATE )
	{
		// Get pointer from user data portion of window
		messageHandler = ( MessageHandler* )( ( LPCREATESTRUCT )lParam )->lpCreateParams;
		SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)messageHandler );

		return 0;
	}
	else // Once created we now need to 
	{
		// Get out pointer from user data portion of window
		messageHandler = ( MessageHandler* )GetWindowLongPtr( hWnd, GWLP_USERDATA );

		// If pointer is not valid
		if(!messageHandler)
			// handle any messages that our callback did not
			return DefWindowProc( hWnd, message, wParam, lParam );
	}
	
	return messageHandler->WindowMessanger( hWnd, message ,wParam, lParam );
}


It is also worth noting that before I implemented the MessageHandler class the game loop worked normal. I am 100% lost and would love some advice.... Regards Chad

Share this post


Link to post
Share on other sites
Advertisement
It's because you return 0 in your WM_PAINT handler. If you don't validate the update-rect in WM_PAINT, a new message will immediately be sent, and WM_PAINT will be received again.

You can solve it with one of the following methods:

case WM_PAINT: {
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
if(hDC != NULL) {
// Paint with hDC, ps.rcPaint is the dirty rectangle to be updated

EndPaint(hWnd, &ps);
}
} return 0;

case WM_PAINT: {
// Tell windows that the entire client rect is now validated and don't need repainting
RECT rect;
GetClientRect(hWnd, &rect);
ValidateRect(hWnd, &rect);
} return 0;

Share this post


Link to post
Share on other sites
If I was making a call to a Render function when WM_PAINT was called how would I set it up? Like this?
case WM_PAINT:{
Render();
ValidateRect( hWnd, NULL );
}return 0;
Or do I still need to get the Client Rect

Regards

Chad

Share this post


Link to post
Share on other sites
Actually the documentation for ValidateRect states that NULL means the entire client rect, so that will work. You need to validate unless your Render function does that already. Drawing is not the same as validating.

Share this post


Link to post
Share on other sites
Quote:
Original post by Erik Rufelt
Actually the documentation for ValidateRect states that NULL means the entire client rect, so that will work. You need to validate unless your Render function does that already. Drawing is not the same as validating.


Let me just start by saying thanks. You have helped me a lot over the past few days. It appears to working as of now. Though I am sure at some point I will be asking more question.

Regards

Chad

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
The title of this thread is pretty funny if you cut it off at the right place:



yeah I actually thought this was a joke..

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!