Sign in to follow this  
Marco H

Another problem - DestroyWindow(hWnd) causes error

Recommended Posts

Hello, there is another problem that is not that bad, but I think it could indicate that somewhere else something is going wrong. When I try to close my program, all the OpenGL-terminating stuff works fine, except for the "DestroyWindow(hWnd)" call. Calling this function the program gives out an access error and closes. What could be the reason for that error? I de-initialised everything dealing with OpenGL before, but this error still appears... ...thanks in advance, Marco

Share this post


Link to post
Share on other sites
Most likely you're corrupting the heap somewhere. Double check all your pointers and arrays to check you're not making invalid accesses anywhere. Also run your program through a debugger and watch the value of hWnd to see if it gets changed anywhere.

Enigma

Share this post


Link to post
Share on other sites
I checked everything, but I did not find anything. Seems that I did not so see samoething, as the crash is still there.

In the meantime I have tried some memory-leak-finding-programs, but one did not work (just crashed at a normal new command) and the other does not display that many information I want to have.

Perhaps someone of you can recommend such a program? :)

Share this post


Link to post
Share on other sites
I don't think you need such a program.
The problem, most likely, lays in your code (I had something like this myself), so I'd rather look for errors in the creation of the window.

Share this post


Link to post
Share on other sites
If you're calling DestroyWindow() after the main message-processing loop (the one with the GetMessage or PeekMessage), then you're calling it AFTER the window is already destroyed!

Normally, the main loop finishs when the WM_QUIT message is received. A WM_QUIT message is posted by the function PostQuitMessage(), that "is typically used in response to a WM_DESTROY message" (according the MSDN). Finally, DestroyWindow() is the default procedure in response to a WM_CLOSE message (if the user confirms the exit).

With that all in mind, I think there is no need to call DestroyWindow() after the main loop. Although, you probably have a hDC=GetDC(hWnd); somewhere before the main loop (at least, I have that line)... and if you try to call ReleaseDC(hWnd,hDC); it will fail. I have that problem and I'm still looking for a good solution; because moving the OpenGL initialization/termination inside the WndProc seemed to not work for me (that was some time ago and I can't remember the details, I'll try to do it again soon).

If you find a good solution to this problem, please let me know.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
In my program, there are two ways to quit the program: press alt+F4 (or just shut it somehow from windows) or simply press the escape key. This makes the main loop ending and after that the shutdown process begins. So, in fact there is not PostQuitMessage() call or a WM_CLOSE message or anything.

But the problem still exists, so I guess the problem can be found elsewhere... I'll check my window initialising code when I am at home.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
In my program, there are two ways to quit the program: press alt+F4 (or just shut it somehow from windows) or simply press the escape key. This makes the main loop ending and after that the shutdown process begins. So, in fact there is not PostQuitMessage() call or a WM_CLOSE message or anything.

Wrong. Pressing Alt-F4 will trigger a WM_CLOSE event, which as has been mentioned will by default destroy the window.

Share this post


Link to post
Share on other sites
Quote:
Original post by joanusdmentia
Wrong. Pressing Alt-F4 will trigger a WM_CLOSE event, which as has been mentioned will by default destroy the window.

Sorry, misunderstanding.

I meant that one way to close the program is to press alt+f4 or close it somehow different over windows. This all results in the WM_CLOSE message as you said.

But another way is to press the escape key. This simply tells my program to leave the main loop and begin with the terminating process. So by that way, there is no WM_CLOSE message, but the error still appears...

Edit: I have now commented out all parts of my programm except for the initialising and de-initialising part, but the DestroyWindow() call still causes a crash.
Thus I think the error is to be found in the initialising code (where else could it be? ;) ), but after comparing it to the code from NeHe's tutorial #1 I did not find any important differences.

So, I am really confused... what could be the reason for that error?

[Edited by - Marco H on December 3, 2004 11:12:47 AM]

Share this post


Link to post
Share on other sites
Ah, OK :)

Well, there are only 2 possible things I can think of that might cause it.
1) The window is already destroyed (unlikely)
2) The window handle is invalid

Now, I doubt you forgot to set the window handle in your code since everything else is working. It could still be modified if you overflow a buffer though. Try stepping through the code, taking note of the window's HWND immediately after you create it, and then compare that against the HWND just before you destroy the window. If they're different, odds are you have a buffer overflow somewhere. And if not....err..... *shrugs*.

Also, how much code are we talking here? It would be alot easier if you could post the relevant parts.

Share this post


Link to post
Share on other sites
Quote:
Original post by joanusdmentia
Try stepping through the code, taking note of the window's HWND immediately after you create it, and then compare that against the HWND just before you destroy the window. If they're different, odds are you have a buffer overflow somewhere. And if not....err..... *shrugs*.

Ok, stupid question maybe, but how do I check the value of hWnd? What type is HWND? A structure? I tried to google it, but I found nothing...

Quote:
Original post by joanusdmentia
Also, how much code are we talking here? It would be alot easier if you could post the relevant parts.

At the moment I have exactly 2167 lines of code (without comments or blank lines, only the real code ;) ), but the initialising and de-initialising parts are not that different from those of NeHe's tutorials. In fact it is mostly the same...

For testing I commented everything out in the WinMain function, so that only the window init and de-init part is compiled, but the error remains.
If I would know how to check the value of hWnd it would be easier =)

Share this post


Link to post
Share on other sites
HWND is the type used by windows for window handles. It's what get's returned by CreateWindow() and is passed into DestroyWindow(). As for checking it, just set a breakpoint in your debugger and check the value of the variable in which you store the result of CreateWindow() (in VS you can just hold your mouse over the variable and it should show it's value). Also set a breakpoint just before you call DestroyWindow() and check that value that you pass in, it *should* be the same as what was returned by CreateWindow().

Post you're WinMain(), init and uninit code. It should help.

Share this post


Link to post
Share on other sites
I think the debugger in Dev-C++ is not that useful... anyway, here is my CreateWindow call

hWnd=CreateWindowEx( dwExStyle, 
// Die erweiterten Eigenschaften des Fensters
szClass, // Der Name der Klasse
title, // Der Titel des Fensters
WS_CLIPSIBLINGS | // Wird von OpenGL benötigt
WS_CLIPCHILDREN | // Wird auch von OpenGL benötigt
dwStyle, // auch Eigenschaften des Fensters
0, 0, // Die Position des zu erstellenden Fensters
WindowRect.right-WindowRect.left,
// Hier werden die ermittelten Werte für die Breite eingesetzt
WindowRect.bottom-WindowRect.top, // und hier für die Länge
NULL, // Es soll kein übergordnetes Fendster erstellt werden
NULL, // kein Menü
hInstance, // Die Instanz wird übergeben
NULL)





It is commented in German, sorry for that (now you know why my English is that bad ;) ).

And here is my de-init code:

	if (hRC) // Rendering Context (RC) vorhanden?
{
if (!wglMakeCurrent(NULL,NULL)) // Kann der DC und RC überhaupt
// gelöscht werden?
{
MessageBox(NULL,"Entfernen des DC und RC fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
};

if (!wglDeleteContext(hRC)) // Kann der RC gelöscht werden?
{
MessageBox(NULL,"Entfernen des RC fehlgeschlagen.","Fehler...",MB_OK | MB_ICONINFORMATION);
};
hRC=NULL; // Der RC wird NULL gesetzt, also entfernt
};

if (hDC && !ReleaseDC(hWnd,hDC)) // Kann der Device Context (DC) freigegeben werden?
{
MessageBox(NULL,"Freigabe des Device Context fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Der DC wird entfernt
};
// ***** Here the program crashes as DestroyWindow is called ******
if (hWnd && !DestroyWindow(hWnd)) // Kann das Programmfenster geschlossen werden?
{
MessageBox(NULL,"Konnte hWnd nicht löschen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Setze den hWnd auf NULL
};
if (!UnregisterClass(szClass,hInstance)) // Kann die Registrierung rückgängig gemacht werden?
{
MessageBox(NULL,"Konnte Klasse nicht entfernen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Setze hInstance auf NULL
};
[...]





Thanks for you patience so far.

Share this post


Link to post
Share on other sites
Heureka, I got it! I have been so stupid I can not believe... After deinitialising the Window I have made a MessageBox-call to check if everything has been shut down correctly, and in that call I passed hWnd as first parameter, as the parent window. But of course the window was already destroyed and so this little MessageBox crashed the program.

So I am very sorry for wasting your time, but during the checking for memory lecks I have found some of them in some of my classes, so the whole thing also has its positive effect.

Again, thanks for you patience =)

Share this post


Link to post
Share on other sites
I can't see anything wrong in the code you pasted... Anyway, you can use the GetLastError() and FormatMessage() functions to know why it is failing.

LPVOID lpMsgBuf;

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);

// Display the string.
MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );

// Free the buffer.
LocalFree( lpMsgBuf );

Share this post


Link to post
Share on other sites
Quote:
Original post by Marco H
Heureka, I got it! I have been so stupid I can not believe... After deinitialising the Window I have made a MessageBox-call to check if everything has been shut down correctly, and in that call I passed hWnd as first parameter, as the parent window. But of course the window was already destroyed and so this little MessageBox crashed the program.

So I am very sorry for wasting your time, but during the checking for memory lecks I have found some of them in some of my classes, so the whole thing also has its positive effect.

Again, thanks for you patience =)

LOL! No worries [smile]
As a side note, you're english is a lot better than some native speakers of the language that I know....

Quote:
Original post by theNestruo
Anyway, you can use the GetLastError() and FormatMessage() functions to know why it is failing.

Good suggestion in general, but the program was crashing so it wouldn't help in this case.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this