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.