无法释放设备上下文、HWND,并且无法取消注册 Windows 类(OpenGL) -

Posted

技术标签:

【中文标题】无法释放设备上下文、HWND,并且无法取消注册 Windows 类(OpenGL) -【英文标题】:Cannot release Device Context, HWND, and cannot unregister Windows Class(OpenGL) - 【发布时间】:2015-02-25 16:33:25 【问题描述】:

我正在关注http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/ OpenGL 教程,并从中获得了代码。现在,我正在尝试通过使用多个类来组织事物。在创建此类时,我无法释放设备上下文 HWND,也无法取消注册 Windows 类。下面的代码是用来检查它们是否可以释放的代码:

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;


(最后三个 if 语句被触发)

导致这些错误的代码是 WinMain 函数中的关键检测代码。这是我更改的唯一代码。

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;
                
            

我改变的是 testKey.THING 部分。 testKey 在主类中由行发起

Keys testKey

Keys.cpp 看起来像这样:

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;
    

最后,Keys.h 看起来像这样:

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

     bool isF1();

     bool isEsc();
;

如果您愿意,我可以发布完整的代码,但我创建 DC 和 HWND 的方式在我上面发布的教程中显示和解释。

有人知道我的密钥代码中的什么导致我的 DC 和 HWND 无法释放吗?

【问题讨论】:

【参考方案1】:

可能 KillGLWindow 被调用了不止一次,而且它不是很合适,试试这个:

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;

【讨论】:

以上是关于无法释放设备上下文、HWND,并且无法取消注册 Windows 类(OpenGL) -的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )

Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )

无法访问已释放的上下文实例 EF 核心

Asp.Net Core 无法访问已释放的上下文实例

无法在 Android 中取消注册 GCM

无法将通知推送到 iOS9 设备