0

Windows 7 でシステム リソースが返されないように見えるという問題があります。一連のウィンドウを作成し、無限ループでそれらを破棄する以外は何もしない短いテスト プログラムを C で作成しました。ループが繰り返されるたびに、タスク マネージャー ウィンドウのハンドル数が増加し、最初の値に戻ることはありません。また、使用されるメモリが忍び寄ります。プログラムを十分長く実行すると、クラッシュします。最終的には、OpenGL コンテキストを作成および破棄できる必要があります。この単純なテスト アプリに OpenGL を含めた場合、動作は同じですが、リソースの消費が速くなります。何か不足していますか?

// ResourceTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "../GL/gl.h"
#include "../GL/glext.h"
#include "../GL/wglew.h"

typedef struct _WindowInfo {
    int x, y;
    int width, height;
    GLboolean visible;
    char *title;
    HWND hWnd;
    HDC device_context;
    GLint id;
    GLint pixelFormat;
    HGLRC hglrc;
} WindowInfo;

typedef GLboolean (APIENTRY *ChoosePixelFormatARBFunc_t)(HDC, GLint *, GLfloat *,  GLuint, GLint *, GLuint *);

ChoosePixelFormatARBFunc_t ChoosePixelFormatARB_func;

#define WINDOW_NAME window->title

HANDLE windowDestroyed;

LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    /* int w,h; */
    switch ( uMsg )
    {
        case WM_CREATE:
        {
            HDC hDC;
            int attribList[100];
            float fattribList[] = { 0.0, 0.0 };
            int i = 0;
            WindowInfo *window =
                (WindowInfo *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
            PIXELFORMATDESCRIPTOR *ppfd = NULL;

            hDC = GetDC(hWnd);
            if (window->pixelFormat <= 0)
            {
                PIXELFORMATDESCRIPTOR pfd = {
                    sizeof(PIXELFORMATDESCRIPTOR),  /*  size of this pfd */
                    1,                              /* version number */
                    PFD_DRAW_TO_WINDOW |            /* support window */
                    PFD_DOUBLEBUFFER   |
                    PFD_SUPPORT_OPENGL,             /* support OpenGL */
                    PFD_TYPE_RGBA,                  /* RGBA type */
                    32,                             /* 24-bit color depth */
                    0, 0, 0, 0, 0, 0,               /* color bits ignored */
                    0,                              /* no alpha buffer */
                    0,                              /* shift bit ignored */
                    1,
                    0, 0, 0, 0,                     /* accum bits ignored */
                    24,                              /* set depth buffer     */
                    8,                              /* set stencil buffer */
                    0,                              /* no auxiliary buffer */
                    PFD_MAIN_PLANE,                 /* main layer */
                    0,                              /* reserved */
                    0, 0, 0                         /* layer masks ignored */
                };
                attribList[i++] = WGL_DRAW_TO_WINDOW_EXT;
                attribList[i++] = GL_TRUE;
                attribList[i++] = WGL_ACCELERATION_EXT;
                attribList[i++] = WGL_FULL_ACCELERATION_EXT;
                attribList[i++] = WGL_COLOR_BITS_EXT;
                attribList[i++] = 24;
                attribList[i++] = WGL_RED_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_GREEN_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_BLUE_BITS_EXT;
                attribList[i++] = 1;
                attribList[i++] = WGL_DOUBLE_BUFFER_EXT;
                attribList[i++] = GL_TRUE;
                attribList[i++] = WGL_DEPTH_BITS_EXT;
                attribList[i++] = 1;
                /* End the list */
                attribList[i++] = 0;
                attribList[i++] = 0;

                ppfd = &pfd;
                if (ChoosePixelFormatARB_func)
                {
                    GLuint numFormats;
                    ChoosePixelFormatARB_func(hDC, attribList, fattribList,
                        1, &window->pixelFormat, &numFormats);
                }
                else
                {
                    /* Okay, we were loaded manually.  Call the GDI functions. */
                    window->pixelFormat = ChoosePixelFormat(hDC, ppfd);
                }
            }
            else
            {
                PIXELFORMATDESCRIPTOR p;
                ppfd = &p;
                DescribePixelFormat(hDC, window->pixelFormat,
                    sizeof(PIXELFORMATDESCRIPTOR), ppfd);
            }
            if (window->pixelFormat)
            {
                SetPixelFormat(hDC, window->pixelFormat, ppfd);
            }
        }
        break;
    }

    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

DWORD WINAPI createWindow(LPVOID args)
{
    WindowInfo *window = (WindowInfo *)args;
    HINSTANCE hinstance;
    WNDCLASS  wc;
    DWORD     window_style;
    MSG msg;
    char name[32];
    HANDLE windowCreated;
    static int id;

    sprintf(name, "createwindow%d", window->id);
    windowCreated = OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
    windowDestroyed = CreateEvent(NULL, TRUE, FALSE, NULL);
    hinstance = GetModuleHandle( NULL );
    if (!hinstance)
    {
        printf( "Couldn't get the module handle.\n" );
        return GL_FALSE;
    }

    if (!GetClassInfo(hinstance, "Test_Window", &wc)) 
    {
        wc.style = CS_OWNDC;
        wc.lpfnWndProc = (WNDPROC) MainWndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hinstance;
        wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
        wc.hCursor = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Test_Window";

        if (!RegisterClass(&wc))
        {
            printf( "Couldn't register window class.\n" );
        }
    }

    window_style = WS_POPUP;

    window->hWnd = CreateWindowA( "Test_Window", WINDOW_NAME, window_style,
        window->x, window->y, window->width, window->height, NULL, NULL, hinstance,
        window);

    if ( !window->hWnd )
    {
        printf( "Create Window failed!.\n" );
    }
    window->device_context = GetDC(window->hWnd);

    if (window->visible)
    {
        ShowWindow(window->hWnd, SW_SHOWNORMAL);
    }

    SetEvent(windowCreated);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.hwnd == window->hWnd)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    CloseHandle(windowCreated);
    window->hWnd = NULL;
    window->device_context = 0;
    SetEvent(windowDestroyed);
    return 0;
}

GLboolean createTestWindow(WindowInfo *window )
{
    HANDLE windowCreated;
    char name[32];

    sprintf(name, "createwindow%d", window->id);
    printf("Create window %d\n", window->id);
    windowCreated = CreateEvent(NULL, TRUE, FALSE, name);

    CreateThread(NULL, 2000, createWindow, (LPVOID)window, 0, NULL);
    WaitForSingleObject(windowCreated, 50000);
    CloseHandle(windowCreated);
    printf("Window created\n");
    return GL_TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HWND hWnd;
    WindowInfo window[34];
    char windowTitle[34];
    int i;
    static int id = 1;

    // Create a window
    window[0].id = 1;
    window[0].x = 40;
    window[0].y = 600;
    window[0].width  = 800;
    window[0].height = 600;
    window[0].visible = 0; // wait to make window visible
    window[0].pixelFormat = 9;
    window[0].title = _strdup("Window 0");
    createTestWindow(&window[0] );
//  Create a context
//  window[0].hglrc = wglCreateContext((HDC)window[0].device_context );
//  wglMakeCurrent(window[0].device_context, window[0].hglrc);
//  Load function pointers
//  ChoosePixelFormatARB_func =
//      (ChoosePixelFormatARBFunc_t)wglGetProcAddress("wglChoosePixelFormatARB");
    // Destroy context
    // wglMakeCurrent(window[0].device_context, 0);
    // wglDeleteContext(window[0].hglrc);
    // DeleteDC(window[0].device_context);
    // Destroy window
    PostMessage(window[0].hWnd, WM_QUIT, 0, 0);
    free(window[0].title);

    while (1)
    {
        for (i = 0; i < 34; i++)
        {
            // Create 34 windows
            window[i].id = i + 1;
            window[i].x = 40;
            window[i].y = 600;
            window[i].width  = 800;
            window[i].height = 600;
            window[i].visible = 1; // wait to make window visible
            window[i].pixelFormat = 9;
            sprintf(windowTitle, "Window %d", window[i].id);
            window[i].title = _strdup(windowTitle);
            createTestWindow(&window[i] );
            // Create 34 contexts
//          window[i].hglrc = wglCreateContext((HDC)window[i].device_context );
//          wglMakeCurrent(window[i].device_context, window[i].hglrc);
        }
        Sleep(3000);
        for (i = 0; i < 34; i++)
        {
            // Destroy contexts
//          wglMakeCurrent(window[i].device_context, 0);
//          wglDeleteContext(window[i].hglrc);
//          DeleteDC(window[i].device_context);
            // Destroy windows
            PostMessage(window[i].hWnd, WM_QUIT, 0, 0);
            Sleep(100);
            printf("%s destroyed\n", window[i].title);
            free(window[i].title);
        }
        Sleep(2000);
    }
    return 0;
}
4

0 に答える 0