• Advertisement
Sign in to follow this  

Windows wont close program

This topic is 3735 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 am quite new in the world of OpenGL and Windows Programming and I have a very annoying problem. I have been following some examples from the book "OpenGL Game Programming", but when I compile my program it takes a lot longer than the one supplied on the disc also when I press the "X"-button in the windows window it wont shut down. The only way is to right click the program in the task bar and say "Close" or the hard way: Task Manager. I have been trying to debug this for a long time now and I cant seem to find the error so if any kind soul would look at file at www.beechwood.dk/Engine.rar (Visual Studio '05 project) and tell me what the problem is I would be ever gratefull. Also as a little side question: Is it possible to debug C++ programs in VS just as you can with C# with breakpoints and all that ? Thank you, Beechwood

Share this post


Link to post
Share on other sites
Advertisement
Show us your 'WndProc' window handler. If you fail to call DefWndProc for any messages you don't handle (and some that you do) then the window won't behave properly, including not shutting down when you try to close it.

Quote:
Original post by Beechwood
Also as a little side question: Is it possible to debug C++ programs in VS just as you can with C# with breakpoints and all that?

Of course. By default, VS should produce a debug build. Run this from the IDE after compiling by pressing F5 (or any of a variety of other ways) to start it with debugging. Breakpoints work exactly as you are used to.

Admiral

Share this post


Link to post
Share on other sites
Being new myself I know how annoying it can be as you really need to know the platform specifics to get OpenGL running when you migt really want to practice your openGL before learning the win32 API most IDE's should supply a win32 template that you can use until your confident with windows programing. Another option is to use Glut which can deal with the setting up of the window for you using glut you can almost program with out knowing anything of the OS specific stuff.

Your best option I'd say is to concentrate on the windows side try reading through MSDN as I find that side of thing to be alot more difficult than OpenGL.

As for you specific problem post the source if you don't yet know inclose source code between

["source"]
code here
["/source"]
removing the quotation marks

Share this post


Link to post
Share on other sites
#The Admiral:
Aye here it is:


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HDC hDC; // Device Context
static HGLRC hRC; // OpenGL Rendering Context
char string[] = "Hello World";
int width, height; // Width and Height of window

switch(message) {
case WM_CREATE: // Create Window
hDC = GetDC( hwnd ); // Fetch Device Context
g_hDC = hDC; // Make global DC
SetupPixelFormat( hDC ); // Set Pixelformat

hRC = wglCreateContext( hDC ); // Create OpenGL Rendering Context
wglMakeCurrent( hDC, hRC ); // Use the Rendering Context
return 0;

case WM_CLOSE:
wglMakeCurrent( hDC, NULL );
wglDeleteContext( hRC );
PostQuitMessage(0); // Sends WM_QUIT
return 0;

case WM_SIZE:
height = HIWORD( lParam );
width = LOWORD( lParam );
if( height == 0 )
height = 1;

glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();

gluPerspective( 45.0f, (GLfloat) width / (GLfloat) height, 1.0f, 1000.0f );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

return 0;

case WM_QUIT:
DestroyWindow( hwnd );
return 0;

default:
break;
}

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



As far as I can see the DefWindowProc will be returned on all parameters not handled in the switch case.

I will look into that VS problem at some point then. I have been using it for a couple of years, but mostly with C#. But with me C++ files it wont do it.

#ramearess
I use Glut when I program on my linux box :)
And Windows programming is not really something I want to go into depth with, yet! :)
The reason I did not copy the code in here is that I thought it might be easier just to review it in VS(or your own IDE). Also it would have been possible to see if my project were setup correctly, linkers and so on.

And thanks for the response lads.

Share this post


Link to post
Share on other sites
If i got thing right here when you choose close the function gets the msg M_close this one works fine as you have remembered to deselect the rendering context with


wglMakeCurrent( hDC, NULL );
wglDeleteContext( hRC );



add those two lines to case WM_QUIT and you should be ok. Or I could be completely wrong in which case I'm as stumped as you are.

The other thing it could be after referring to me boook the likle x may senfd the message WM_DESTROY which is a case you don't have. Also as destroy quit and close all do the same thing try.


case WM_DESTROY:
case WM_QUIT:
case WM_CLOSE:

//Deselect RC
wglMakeCurrent( hDC, NULL );
wglDeleteContext( hRC );

//send WM_QUIT to message queue
PostQuitMessage(0);
break;



This code is used to exit a continus loop in WinMain using the fact that if(!getmessage()) will now evaluate to true and carry out the block of code. for your case it maybe you replace PostQuitMesage(0) with DestroyWindow( hwnd )

Share this post


Link to post
Share on other sites
I'm not an expert on Windows messages, but it looks like you aren't handling things quite right. As far as I can tell, WM_SIZE and WM_QUIT are being handled incorrectly and WM_DESTROY isn't being handled at all.

WM_QUIT and WM_SIZE are coded into the low word of wParam, not into message. And I can't say for sure, but I believe that your program should respond to a WM_DESTROY with PostQuitMessage. Here's my minimal handler:


<snip />

This was produced by the Visual C++ wizard, so I delegate any irresponsible code accordingly.

Edit 2: Perhaps I should stay within my area of expertise. In retrospect, the wizard didn't produce anything of the sort. I'll get to fixing that right away. Though I should add that the wizard's code is very happy calling DefWindowProc from the default case bracket, not that I disagree with you: Microsoft sample code is far from exemplary in most cases.

Edit: Judging from your other post, the problem may be that the WndProc isn't being called at all. Make sure that your program's main loop is keeping the message pump flowing with something along the lines of:

do {
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
MainProgramLoop();
}
} while (running);





Admiral

[Edited by - TheAdmiral on November 1, 2007 9:01:44 AM]

Share this post


Link to post
Share on other sites
Holy f*ck, i don't believe a single second that the VS wizard is creating that code.

WM_SIZE is a proper message, handle it in the switch/case like any other message.

Do never put return DefWindowProc in a default case handler. What if you need to handle a message AND pass the message on to DefWindowProc?

Do not pass a HWND in PeekMessage/GetMessage. You'll never receive WM_QUIT that way, since WM_QUIT is a thread message. This means it isn't sent to any specific HWND (hWnd = NULL in that case).

@Beechwood:

Your WindowProc looks quite good, just rearrange a few things:


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HDC hDC; // Device Context
static HGLRC hRC; // OpenGL Rendering Context
char string[] = "Hello World";
int width, height; // Width and Height of window

switch(message) {
case WM_CREATE: // Create Window
hDC = GetDC( hwnd ); // Fetch Device Context
g_hDC = hDC; // Make global DC
SetupPixelFormat( hDC ); // Set Pixelformat

hRC = wglCreateContext( hDC ); // Create OpenGL Rendering Context
wglMakeCurrent( hDC, hRC ); // Use the Rendering Context
return 0;

case WM_CLOSE:
wglMakeCurrent( hDC, NULL );
wglDeleteContext( hRC );
// Just pass the message on break;

case WM_SIZE:
height = HIWORD( lParam );
width = LOWORD( lParam );
if( height == 0 )
height = 1;

glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();

gluPerspective( 45.0f, (GLfloat) width / (GLfloat) height, 1.0f, 1000.0f );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

return 0;
case WM_DESTROY:
// End the game here
PostQuitMessage(0); // Sends WM_QUIT
break;
}

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



Handle WM_QUIT in the main message loop via GetMessage. WM_QUIT should be the last message processed.

Pass WM_CLOSE on to DefWindowProc, it will call DestroyWindow for you.
In WM_DESTROYWINDOW call PostQuitMessage to end your main message loop.

You didn't show your message loop, but make sure you do NOT pass a HWND into PeekMessage/GetMessage.

Share this post


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

  • Advertisement