Original Post
Hey. Something strange is going on with my window; if I use the menu at all and select any options and then close it down I can't recompile the code after changes as it says the exe is still in use, and it is when I look at task manager which forces me to destroy the window from in there...obviously not good. I've searched over MSDN pages and googled everything I can think of, but still no luck... Heres the code anyway; there is a fair amount so I appreciate any replies from anyone. Thanks.
#include "WinMain.h"
#include "GameWorld.h"
#include "resource.h"
//--------------------------------------------------------------------------------------------------
/**
@globals
**/
//--------------------------------------------------------------------------------------------------
bool g_Exiting = false;
int g_WindowWidth = 1024; // Defaulted window width
int g_WindowHeight = 768; // Defaulted window height
int g_Fullscreen = 0; // Defaulted to not full screen
f64 g_FOV = 45.0; // Default field of view
f64 g_zNear = 0.1; // Defaulted z near plane
f64 g_zFar = 8000.0; // Defaulted z far plane
HDC g_HDC = NULL;
bool g_ShowFPS = false;
Timer g_Timer;
GameWorld* g_pGameWorld = NULL;
//--------------------------------------------------------------------------------------------------
/**
@function SetupPixelFormat
@brief Create the rendering context
**/
//--------------------------------------------------------------------------------------------------
void SetupPixelFormat( HDC hDC )
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof( PIXELFORMATDESCRIPTOR ), // size
1, // version
PFD_SUPPORT_OPENGL | // OpenGL window
PFD_DRAW_TO_WINDOW | // render to window
PFD_DOUBLEBUFFER, // support double-buffering
PFD_TYPE_RGBA, // color type
32, // preferred color depth
0, 0, 0, 0, 0, 0, // color bits (ignored)
0, // no alpha buffer
0, // alpha bits (ignored)
0, // 0
0, 0, 0, 0, // accumulation bits (ignored)
24, // depth buffer
0, // stencil buffer
0, // no auxiliary buffers
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0, // no layer, visible, damage masks
};
int pixelFormat = ChoosePixelFormat( hDC, &pfd );
SetPixelFormat( hDC, pixelFormat, &pfd );
}
//--------------------------------------------------------------------------------------------------
/**
@function MainWindowProc
@brief Windows callback function
**/
//--------------------------------------------------------------------------------------------------
LRESULT CALLBACK MainWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static HDC hDC;
static HGLRC hRC;
static int height = 0;
static int width = 0;
// Get a pointer to the camera each time the callback is invoked...
Camera* pCamera = NULL;
// Retrieve a pointer to the game world if it has been created...
if( g_pGameWorld )
pCamera = g_pGameWorld->GetCamera();
// Get the window handle for the mouse each time the call back function is invoked
if( pCamera )
pCamera->GetWindowHandle( hWnd );
// dispatch messages
switch( uMsg )
{
// Process Menu commands
case WM_COMMAND:
if( LOWORD( wParam ) == ID_FILE_QUIT )
SendMessage( hWnd, WM_CLOSE, 0, 0 );
if( LOWORD( wParam ) == ID_TERRAIN_WIREFRAMEON )
g_pGameWorld->GetTerrain()->ToggleRenderMode();
if( LOWORD( wParam ) == ID_FILE_SHOWFPSON )
g_ShowFPS = !g_ShowFPS;
break;
case WM_CREATE: // window creation
hDC = GetDC( hWnd );
SetupPixelFormat( hDC );
hRC = wglCreateContext( hDC );
wglMakeCurrent( hDC, hRC );
break;
case WM_DESTROY: // window destroy
case WM_QUIT:
case WM_CLOSE: // windows is closing
// De-select rendering context and delete it
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, g_HDC );
break;
case WM_SIZE:
height = HIWORD( lParam ); // retrieve width and height
width = LOWORD( lParam );
if( height == 0 )
height = 1;
// Get the dimensions of the screen
if( pCamera )
pCamera->GetWindowDimensions( width, height );
// Size the OpenGL view port
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// Calculate OpenGL perspective
gluPerspective( g_FOV, g_WindowWidth/g_WindowHeight, g_zNear, g_zFar );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
break;
case WM_ACTIVATEAPP: // activate app
break;
case WM_PAINT: // paint
PAINTSTRUCT ps;
BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;
case WM_LBUTTONDOWN:
if( pCamera )
pCamera->SetViewWithMouse( true );
ShowCursor( false );
break;
case WM_RBUTTONDOWN:
break;
case WM_MOUSEMOVE:
break;
case WM_LBUTTONUP:
if( pCamera )
pCamera->SetViewWithMouse( false );
ShowCursor( true );
break;
case WM_RBUTTONUP:
break;
case WM_KEYUP:
break;
case WM_KEYDOWN:
int fwKeys;
LPARAM keyData;
fwKeys = (int)wParam; // virtual-key code
keyData = lParam; // key data
switch( fwKeys )
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
default:
break;
}
break;
default:
break;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//--------------------------------------------------------------------------------------------------
/**
@function WinMain
@brief Windows main function
**/
//--------------------------------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// Load the window data
LoadWindowData();
WNDCLASSEX windowClass; // window class
HWND hwnd; // window handle
MSG msg; // message
DWORD dwExstyle; // Window Extended style
DWORD dwstyle; // Window style
RECT windowRect;
windowRect.left =(long)0; // Set Left Value To 0
windowRect.right =(long)g_WindowWidth; // Set Right Value To Requested Width
windowRect.top =(long)0; // Set Top Value To 0
windowRect.bottom =(long)g_WindowHeight; // Set Bottom Value To Requested Height
// fill out the window class structure
windowClass.cbSize = sizeof( WNDCLASSEX );
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = MainWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); // default icon
windowClass.hIconSm = NULL;
windowClass.hCursor = LoadCursor( NULL, IDC_ARROW ); // default arrow
windowClass.hbrBackground = NULL; // don't need background
windowClass.lpszClassName = kAppName;
// Menu item
windowClass.lpszMenuName = MAKEINTRESOURCE( IDR_MENU1 );
//windowClass.hIcon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) );
//windowClass.hIconSm = ( HICON )LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ), IMAGE_ICON, 32, 32, 0 );
// Register the windows class
if ( !RegisterClassEx( &windowClass ) )
{
MessageBox( NULL, "WinMain: Failed to register class!", NULL, MB_OK );
return 0;
}
if ( g_Fullscreen ) // full screen?
{
DEVMODE dmScreenSettings; // device mode
memset( &dmScreenSettings, 0, sizeof( dmScreenSettings ) );
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = g_WindowWidth; // screen width
dmScreenSettings.dmPelsHeight = g_WindowHeight; // screen height
dmScreenSettings.dmBitsPerPel = kWindowBits; // bits per pixel
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if( ChangeDisplaySettings( &dmScreenSettings, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL )
{
// Setting display mode failed, switch to windowed
MessageBox( NULL, "WinMain: Display mode failed!", NULL, MB_OK );
g_Fullscreen = 0;
}
}
if( g_Fullscreen )
{
dwExstyle = WS_EX_APPWINDOW; // Window Extended style
dwstyle = WS_POPUP; // Windows style
}
else
{
dwExstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended style
dwstyle = WS_OVERLAPPEDWINDOW; // Windows style
}
AdjustWindowRectEx( &windowRect, dwstyle, false, dwExstyle ); // Adjust Window To True Requested Size
// class registered, so now create our window
hwnd = CreateWindowEx( NULL, // extended style
kAppName, // class name
kAppName, // app name
dwstyle | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
0, 0, // x,y coordinate
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, // width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance, // application instance
NULL ); // no extra params
g_HDC = GetDC( hwnd );
// Check if window creation failed (hwnd would equal NULL)
if( !hwnd )
return 0;
ShowWindow( hwnd, SW_SHOW ); // display the window
UpdateWindow( hwnd ); // update the window
if( !Timer::QueryHighPerformanceTimer() )
{
MessageBox( NULL, "WinMain: QueryHighPerformanceTimer failed!", NULL, MB_OK );
return 0;
}
g_Timer.Initialise();
g_pGameWorld = new GameWorld();
if( !g_pGameWorld->Initialise( hwnd ) )
{
MessageBox( NULL, "WinMain: Failed to initialise GameWorld!", NULL, MB_OK );
delete g_pGameWorld;
_CrtDumpMemoryLeaks();
return 0;
}
glEnable( GL_TEXTURE_2D );
glEnable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
while( !g_Exiting )
{
g_Timer.Update();
f32 delta = g_Timer.GetDeltaTime();
g_pGameWorld->Update( delta );
g_pGameWorld->Render();
SwapBuffers( g_HDC );
if( g_ShowFPS )
CalculateFrameRate( hwnd );
else
SetWindowText( hwnd, kAppName );
while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if( !GetMessage( &msg, NULL, 0, 0 ) )
{
g_Exiting = true;
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
g_pGameWorld->Shutdown();
delete g_pGameWorld;
g_pGameWorld = NULL;
// Test for CRT leaks...
_CrtDumpMemoryLeaks();
if( !DestroyWindow( hwnd ) )
MessageBox( NULL, "WinMain: Failed to destroy window!", NULL, MB_OK );
// Unregister the class
if( !UnregisterClass( kAppName, windowClass.hInstance ) )
MessageBox( NULL, "WinMain: Failed to unregister class!", NULL, MB_OK );
return (int)msg.wParam;
}