Simple Win Class annoying me please help

Started by
6 comments, last by JinJo 21 years, 6 months ago
I have wrote a simple windows class so that in my main loop i can just have window.Create(800, 600, 32, fullscreen); window.Run(); or siiimmilar; The run function is obviously the main message loop and it if theres no message it will call a virtual function Frame(). Theres a static WndProc function that redirects all messages to a MessageHandler function. My problem is is a window is created, but you can see the app behind it, i cant close or move the window or resize it and when i ctrl alt delete and close it, the program wont recompile unless i close some other program that it seems to be createing (dont know how). The thing thats annoying is ive made this class (well simmilar) before (twice), and i used it for direct x based games (my first 2). Now im releeeearning Open GL from Nehe and im now going to create some games with it, and the basis is the windows class, which ive actually called it GLApp. heres the source for the header
  
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>


class GLApp
{
protected:
	HWND		m_hWnd;
	HDC			m_hDC;
	HGLRC		m_hRC;
	HINSTANCE	m_hInstance;
	MSG			m_kMessage;

	bool m_bFullscreenFlag;
	bool m_bAppActiveFlag;
	bool m_abKeys[256];


public:
	//constructor(s) / destructor

	GLApp(void);
	~GLApp(void);

	bool Init(void);
		bool CreateGLWindow(int iWidth, int iHeight, int iBitDepth, bool bFullscreenFlag);
		static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
		bool MessageHandler(UINT message, WPARAM wParam, LPARAM lParam);
		bool InitGL(void);
	void Run(void);
		virtual bool Frame(void) = 0;
		bool Render(void);
		bool Update(void);
	bool Shutdown(void);
		bool DestroyGLWindow(void);

	//other functions

	void ReSizeGLScene(int iWidth, int iHeight);
};
  
and the .cpp file
  
#include "GLApp.h"
#include "E_Error.h"
#include "E_DataTypes.h"

GLApp::GLApp(void)
{
	m_hWnd		= NULL;
	m_hDC		= NULL;
	m_hRC		= NULL;
	m_hInstance	= GetModuleHandle(NULL);

	m_bFullscreenFlag	= true;
	m_bAppActiveFlag	= true;

	m_szError = NULL;
}

GLApp::~GLApp(void)
{
	//nothing yet

}

bool GLApp::InitGL(void)
{
	return true;
}

void GLApp::ReSizeGLScene(int iWidth, int iHeight)
{
	
}

bool GLApp::DestroyGLWindow(void)
{
	return true;
}

bool GLApp::CreateGLWindow(int iWidth, int iHeight, int iBitDepth, bool bFullscreenFlag)
{
	//setup window position

	RECT WindowRect;
	WindowRect.left = 0;
	WindowRect.top = 0;
	WindowRect.right = iWidth;
	WindowRect.bottom = iHeight;

	//set the fullscreen flag to what the user wants

	m_bFullscreenFlag = bFullscreenFlag;

	//setup windows class

	WNDCLASS WndClass;

	WndClass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	WndClass.hInstance		= m_hInstance;
	WndClass.lpfnWndProc	= (WNDPROC) WndProc;
	WndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	WndClass.hIcon			= LoadIcon(NULL, IDI_WINLOGO);
	WndClass.lpszClassName	= "GLApp";
	WndClass.hbrBackground	= NULL;
	WndClass.cbClsExtra		= NULL;
	WndClass.cbWndExtra		= NULL;	
	WndClass.lpszMenuName	= NULL;

	//try and register windows class

	if(!RegisterClass(&WndClass))
	{
		m_szError = E_ErrorRegisterClass;
		return false;
	}
	
	//if fullscreen change display settings

	if(m_bFullscreenFlag)
	{
		DEVMODE dmScreenSettings;
		memset(&dmScreenSettings, 0, sizeof(DEVMODE));	//make sure memorys clear

		dmScreenSettings.dmBitsPerPel   = iBitDepth;
		dmScreenSettings.dmPelsWidth	= iWidth;			
		dmScreenSettings.dmPelsHeight	= iHeight;

		//Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.

		if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			//If The Mode Fails, Offer Two Options.  Quit Or Run In A Window.

			if(MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","GLApp",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
			{
					m_bFullscreenFlag = false;				// Select Windowed Mode (Fullscreen=FALSE)

			}
			else
			{
				//Pop Up A Message Box Letting User Know The Program Is Closing.

				MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
				m_szError = E_ErrorChangeDisplayMode;
				return false;					
			}
		}
	}

	//// Window Style

	DWORD		dwExStyle;						
	DWORD		dwStyle;
	
	//if still using fullscreen

	if(m_bFullscreenFlag)
	{
		dwExStyle=WS_EX_APPWINDOW;
		dwStyle=WS_POPUP;
		ShowCursor(false);	//Hide Mouse cursor

	}
	else
	{
		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			
		dwStyle=WS_OVERLAPPEDWINDOW;				
	}
	
	// Adjust Window To True Requested Size

	AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);	

	//try to create the applications main window

	if(!(m_hWnd=CreateWindowEx(dwExStyle,			
							"GLApp",			
							"GLApp",				
							WS_CLIPSIBLINGS |			
							WS_CLIPCHILDREN |			
							dwStyle,				
							0, 0,				
							WindowRect.right-WindowRect.left,	
							WindowRect.bottom-WindowRect.top,	
							NULL,					
							NULL,					
							m_hInstance,				
							(void*)this)))				
	{
		DestroyGLWindow();						
		m_szError = E_ErrorCreateWindow;
		return false;						
	}

	//try to get a device context

	if(!(m_hDC = GetDC(m_hWnd)))						
	{
		DestroyGLWindow();	
		m_szError = E_ErrorGetDC;
		return false;						
	}
	
	//setup pixel format descriptor

	UInt32 PixelFormat;
	static PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),	// Size Of This Pixel Format Descriptor

		1,								// Version Number

		PFD_DRAW_TO_WINDOW |			// Format Must Support Window

		PFD_SUPPORT_OPENGL |			// Format Must Support OpenGL

		PFD_DOUBLEBUFFER,				// Must Support Double Buffering

		PFD_TYPE_RGBA,					// Request An RGBA Format

		iBitDepth,							// Select Our Color Depth

		0, 0, 0, 0, 0, 0,				// Color Bits Ignored

		0,								// No Alpha Buffer

		0,								// Shift Bit Ignored

		0,								// No Accumulation Buffer

		0, 0, 0, 0,						// Accumulation Bits Ignored

		16,								// 16Bit Z-Buffer (Depth Buffer)

		0,								// No Stencil Buffer

		0,								// No Auxiliary Buffer

		PFD_MAIN_PLANE,					// Main Drawing Layer

		0,								// Reserved

		0, 0, 0							// Layer Masks Ignored

	};

	//try and find a matching pixel format?

	if(!(PixelFormat = ChoosePixelFormat(m_hDC, &pfd)))		
	{
		DestroyGLWindow();	
		m_szError = E_ErrorChoosePixelFormat;
		return false;
	}

	//try and now set the pixel format

	if(!SetPixelFormat(m_hDC, PixelFormat, &pfd))		
	{
		DestroyGLWindow();	
		m_szError = E_ErrorSetPixelFormat;
		return false;
	}
	
	//try and create a rendering context

	if(!(m_hRC = wglCreateContext(m_hDC)))		
	{
		DestroyGLWindow();	
		m_szError = E_ErrorCreateRenderingContext;
		return false;
	}

	//Try To Activate The Rendering Context

	if(!wglMakeCurrent(m_hDC, m_hRC))				
	{
		DestroyGLWindow();	
		m_szError = E_ErrorActivateRenderingContext;
		return false;
	}

	ShowWindow(m_hWnd,SW_SHOW);						
	SetForegroundWindow(m_hWnd);						
	SetFocus(m_hWnd);								
	
	//Set Up Perspective GL Screen

	ReSizeGLScene(iWidth, iHeight);						
	
	//initialize Open GL

	if(!InitGL())								
	{
		DestroyGLWindow();	
		m_szError = E_ErrorInitGL;
		return false;						
	}

	//everything initialized ok

	return true;
}

//normal message handler, this directs all messages to the MessageHandler function

LRESULT CALLBACK GLApp::WndProc(HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam)
{
	GLApp*  pkWindow   = NULL;
	bool    bProcessed = false;

	switch(message)
	{
	//Window is creating - set custom information 

	case WM_NCCREATE:
		SetWindowLong(hWindow, GWL_USERDATA, 
						(long)((LPCREATESTRUCT(lParam))->lpCreateParams));
		break;
	//Window message - Let our handler process it

	default:
		pkWindow = (GLApp *)GetWindowLong(hWindow, GWL_USERDATA);
		if (NULL != pkWindow)
		{
			bProcessed = pkWindow->MessageHandler(message, wParam, lParam);
		}
		break;
	}

	//Message not processed - let windows handle it 

	if (false == bProcessed)
	{
		return DefWindowProc(hWindow, message, wParam, lParam);
	}
	return 0;
}


bool GLApp::MessageHandler(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_ACTIVATE:						
		{
			if(!HIWORD(wParam))			// Check Minimization State

			{
				m_bAppActiveFlag=true;	// Program Is Active

			}
			else
			{
				m_bAppActiveFlag=false;	// Program Is No Longer Active

			}

			return 0;						
		}
		case WM_SYSCOMMAND:						// Intercept System Commands

		{
			switch (wParam)						// Check System Calls

			{
				case SC_SCREENSAVE:				// Screensaver Trying To Start?

				case SC_MONITORPOWER:			// Monitor Trying To Enter Powersave?

				return 0;					// Prevent From Happening

			}
			break;							
		}
		case WM_CLOSE:							
		{
			PostQuitMessage(0);					
			return 0;						
		}
		case WM_KEYDOWN:						
		{
			m_abKeys[wParam] = true;				
			return 0;					
		}
		case WM_KEYUP:						
		{
			m_abKeys[wParam] = false;				
			return 0;					
		}
		case WM_SIZE:							
		{
			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));	// LoWord=Width, HiWord=Height

			return 0;					
		}
	}
	// Pass All Unhandled Messages To DefWindowProc

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

//Real time message loop 

void GLApp::Run(void)
{
	while(1)	//infinate loop

	{
		//Query to see if there is any message in the queue 

		if (PeekMessage (&m_kMessage, m_hWnd, 0, 0, PM_REMOVE))
		{
			//if it is the WM_QUIT message, quit the loop 

			if (WM_QUIT == m_kMessage.message)
			{
				break;
			}
			else
			//Process the message normally 

			{
				TranslateMessage (&m_kMessage);
				DispatchMessage (&m_kMessage);
			}
		}
		else
		{
			//No message, do frame 

			if(Frame() == false)
			{
				return;
			}
		}
	}
}
  
If anyone could point out my stupid mistake(s) that i just cant spot i would be very thankfull. Sorry if i havent described my problem clearly or if i just never made any sense, ill check back here often just in case you need more info. Thanks.
Advertisement
seeing the app behind it, make sure youre clearing the color buffer, and make sure youre swapping the front and backbuffers afterwards, and the other problems, you're assigning bProcessed to whatever youre message handler returns, which in many cases is 0, and when its not, its from DefWindowProc so you dont know what the value is, maybe re-work that,(especially that you call DefWindowProc again if you yourself returned 0 from MessageHandler)

[edited by - digitec devil on October 16, 2002 5:01:05 PM]

[edited by - digitec devil on October 16, 2002 5:06:27 PM]

[edited by - digitec devil on October 16, 2002 5:09:30 PM]
Thanks. I checked the app and for some odd reason i had commented out the call to swapbuffers
So i compiled and i got my window wich was cleared to red (nothin special just thought it was different from black)
however i still cant move it or close it with the x on the title bar, i can close the app by pushing escape though
Heres the code for the updated functions if you can help again ill be greatful


    //normal message handler, this directs all messages to the MessageHandler functionLRESULT CALLBACK GLApp::WndProc(HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam){	GLApp*  pkWindow   = NULL;	bool  bProcessed = false;	switch(message)	{		//Window is creating - set custom information 		case WM_NCCREATE:		{				SetWindowLong(hWindow, GWL_USERDATA, 							(long)((LPCREATESTRUCT(lParam))->lpCreateParams));			return 0;		}//Window message - Let our handler process it		default:		{	pkWindow = (GLApp *)GetWindowLong(hWindow, GWL_USERDATA);			if (NULL != pkWindow)			{				bProcessed = pkWindow->MessageHandler(message, wParam, lParam);			}			break;		}	}	if(bProcessed == false)	{		return DefWindowProc(hWindow, message, wParam, lParam);	}	return 0;}bool GLApp::MessageHandler(UINT message, WPARAM wParam, LPARAM lParam){	switch(message)	{		case WM_ACTIVATE:								{			if(!HIWORD(wParam))			// Check Minimization State			{				m_bAppActiveFlag=true;	// Program Is Active			}			else			{				m_bAppActiveFlag=false;	// Program Is No Longer Active			}			break;								}		case WM_SYSCOMMAND:						// Intercept System Commands		{			switch (wParam)						// Check System Calls			{				case SC_SCREENSAVE:				// Screensaver Trying To Start?				case SC_MONITORPOWER:			// Monitor Trying To Enter Powersave?				break;			}			break;									}		case WM_CLOSE:									{			PostQuitMessage(0);								break;									}		case WM_KEYDOWN:								{			m_abKeys[wParam] = true;							break;								}		case WM_KEYUP:								{			m_abKeys[wParam] = false;							break;								}		case WM_SIZE:									{			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));	// LoWord=Width, HiWord=Height			break;								}		default:		{				return false;		}	}	return true;}//Real time message loop void GLApp::Run(void){	while(1)	//infinate loop	{		//Query to see if there is any message in the queue 		if (PeekMessage (&m_kMessage, m_hWnd, 0, 0, PM_REMOVE))		{			//if it is the WM_QUIT message, quit the loop 			if (WM_QUIT == m_kMessage.message)			{				break;			}			else			//Process the message normally 			{				TranslateMessage (&m_kMessage);				DispatchMessage (&m_kMessage);			}		}		else		{			//No message, do frame 			if(Frame() == false)			{				return;			}		}	}}    


[edited by - JinJo on October 16, 2002 5:56:14 PM]
hmm I cant see really what one thing it might be, if you want, send me your project files at digitecdevil@houston.rr.com and Ill get back to ya
quote:Original post by JinJo
//Real time message loop
void GLApp::Run(void)
{
while(1) //infinate loop
{
//Query to see if there is any message in the queue
if (PeekMessage (&m_kMessage, m_hWnd, 0, 0, PM_REMOVE))
{
//if it is the WM_QUIT message, quit the loop
if (WM_QUIT == m_kMessage.message)
{
break;
}
else
//Process the message normally
{
TranslateMessage (&m_kMessage);
DispatchMessage (&m_kMessage);
}
}
else
{
//No message, do frame
if(Frame() == false)
{
return;
}
}
}
}
[edited by - JinJo on October 16, 2002 5:56:14 PM]


Try changing the break here to a return.

[EDIT]Actually, I don't think that return/break would ever be executed...I'm assuming that your Frame() code returns false when you press escape, so that's why that works. IIRC, PeekMessage will return 0 when you do a PostQuitMessage(0). If that's the case, I'm sure you can fix the problem yourself.


[edited by - Thunder_Hawk on October 16, 2002 6:55:01 PM]
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
You are bypassing the DefWindowProc processing that needs to occur in order for the titlebar''s close button to work. For now I''d suggest always returning false from your MessageHandler function.
Your WM_SYSCOMMAND is returning a ''true'' while it is almost doing nothing. That explain the non-functioning ''x'' button, i guess. (hints: check for SC_CLOSE)
"after many years of singularity, i'm still searching on the event horizon"
Thanks i wasnt really thinking properly because i was getting annoyed.
Im at college just now so ill check it when i go home.

This topic is closed to new replies.

Advertisement