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;
}