c++openglhwndgdihinstance

Cannot release Device Context, HWND, and cannot unregister Windows Class(OpenGL) -


I am following the http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/ OpenGL tutorial, and I got the code from that working. Now, I am trying to organise things by using multiple classes. As I was creating this class, I became unable to release the Device Context, HWND and I couldn't unregister the Windows Class. The code below is the code used to check if they can be released or not:

GLvoid KillGLWindow(GLvoid){ 
if (fullscreen){
    ChangeDisplaySettings(NULL, 0);
    ShowCursor(true);
}
if (hRC){
    if (!wglMakeCurrent(NULL, NULL)){
        MessageBox(NULL, "Release of DC and RC failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    }
    if (!wglDeleteContext(hRC)){
        MessageBox(NULL, "Release of RC failed", "Shutdown error", MB_OK | MB_ICONEXCLAMATION);
    }
    hRC = NULL;
}
if (hDC && !ReleaseDC(hWnd, hDC)){
    MessageBox(NULL, "Release of DC failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    hDC = NULL;
}
if (hWnd && !DestroyWindow(hWnd)){
    MessageBox(NULL, "Release of hWnd failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    hWnd = NULL;
}
if (!UnregisterClass("OpenGL", hInstance)){
    MessageBox(NULL, "Could not unregister window class", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    hInstance = NULL;
}
}

(The last three if statments fired)

The code I was moving around that caused these errors is the key detecting code in the WinMain function. This is the only code I changed.

else{
        if (active){

            if (testKey.isEsc()){
                done = true;
            }
            if (testKey.isA()){
                KillGLWindow();
            }
            else{
                DrawGLScene();
                SwapBuffers(hDC);
            }
        }
            if (testKey.isF1()){
                //Keys::keys[VK_F1] = false;
                KillGLWindow();
                fullscreen = !fullscreen;
                if (!CreateGLWindow("XcoxGL", 640, 480, 16, fullscreen)){
                    return 0;
                }
            }

What I changed is the testKey.THING part. testKey is initiated in the main class by the line

Keys testKey

The Keys.cpp looks like this:

bool Keys::keys[256] = { false };

bool Keys::isA(){
    if (&keys[0x41]){
        return true;
    }
    else{
        return false;
    }
}

bool Keys::isF1(){
    if (&keys[VK_F1]){
        return true;
    }
    else{
        return false;
    }
}

bool Keys::isEsc(){
    if (&keys[VK_ESCAPE]){
        return true;
    }
    else{
        return false;
    }
}

And finally, Keys.h looks like this:

#pragma once
class Keys{
public:
    static bool keys[256];
     bool isA();

     bool isF1();

     bool isEsc();
};

I can post the full code if you want, but the way I create my DC and HWND is shown and explained at the tutorial I posted above.

Does anyone know what in my Key code is causing my DC and HWND to not be able to release?


Solution

  • Probably KillGLWindow is called more than one time, and its not really proper, try this:

    GLvoid KillGLWindow(GLvoid){ 
    if (fullscreen){
        ChangeDisplaySettings(NULL, 0);
        ShowCursor(true);
    }
    if (hRC){
        if (!wglMakeCurrent(NULL, NULL)){
            MessageBox(NULL, "Release of DC and RC failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
        }
        if (!wglDeleteContext(hRC)){
            MessageBox(NULL, "Release of RC failed", "Shutdown error", MB_OK | MB_ICONEXCLAMATION);
        }
    }
    hRC = NULL;
    if (hDC && !ReleaseDC(hWnd, hDC)){
        MessageBox(NULL, "Release of DC failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    }
    hDC = NULL;
    if (hWnd && !DestroyWindow(hWnd)){
        MessageBox(NULL, "Release of hWnd failed", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    }
    hWnd = NULL;
    if (hInstance && !UnregisterClass("OpenGL", hInstance)){
        MessageBox(NULL, "Could not unregister window class", "Shutdown error", MB_OK | MB_ICONINFORMATION);
    }
    hInstance = NULL;
    }