Child-Window korrekt freigeben



  • Hallo miteinander,

    ich hab da mal eine vieleicht naive Frage. Ich erzeuge ein Anwendungsfenster und in der WM_CREATE-Nachricht dessen Fenster-Prozedur erzeuge ich ein Child Fenster. Das funktioniert soweit ganz gut. Um das ganze am Ende wieder abzubauen, konnte ich der Dokumentation von VS 2003.net entnehmen, dass es ausreicht eine DestroyWindow(hWnd) and das Parent-Window zu senden und diese dafür sorgt dass zunächst die Child-Windows abgebaut werden.

    Ich bin also davon ausgegangen, dass auch das Child-Window eine WM_DESTROY-Message erhält und habe in der ChildWndProc(...) in der nachricht WM_DESTROY code zum Aufräumen untergebracht. Dieser wird jedoch niemals ausgeführt.

    Nun zur Frage. Bekommnen Child-Windows eine WM_DESTROY-Message? Wo muss ich sonst den Code für Speicherfreigaben, ReleaseDC etc. platziertn?

    Danke für eure Hilfe.

    Mfg
    Knecht



  • Bekommnen Child-Windows eine WM_DESTROY-Message?

    Ja.



  • mal ne andere naive Frage. Was ist das für ein ChildWindow Wo reagierst du auf die WM_DESTROY Message von deinem Child-Window?
    evtl. ein bissel code posten.

    MfG schirrmie



  • Hallo miteinander,

    der Code sieht etwa so aus...

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wndclass;
    	wndclass.cbSize			= sizeof(WNDCLASSEX);
    	wndclass.cbClsExtra		= 0;
    	wndclass.cbWndExtra		= 0;
    	wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wndclass.hIconSm		= LoadIcon(NULL, IDI_APPLICATION);
    	wndclass.hInstance		= hInstance;
    	wndclass.lpfnWndProc	= MainWndProc;
    	wndclass.lpszClassName	= TEXT("3dTest_OpenGL");
    	wndclass.lpszMenuName	= TEXT("TestProg");
    	wndclass.style			= CS_HREDRAW | CS_VREDRAW;
    
    	if (!RegisterClassEx(&wndclass))
    	{
    		MessageBox(0, "Programm arbeitet mit Unicode und setzt windows NT voraus!", "3dTest_OpenGL", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
    		return 0;
    	}
    
    	wndclass.hIcon			= 0;
    	wndclass.hIconSm		= 0;
    	wndclass.lpfnWndProc	= GLWndProc;
    	wndclass.lpszClassName	= TEXT("GL_Window");
    	wndclass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    	wndclass.hbrBackground	= 0;
    
    	if (!RegisterClassEx(&wndclass))
    	{
    		MessageBox(0, "Programm arbeitet mit Unicode und setzt windows NT voraus!", "GL_Window", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
    		return 0;
    	}
    
    	HWND hWnd = CreateWindow(TEXT("3dTest_OpenGL"), TEXT("3d Test OpenGL"), WS_OVERLAPPEDWINDOW, 
    		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0);
    
    	if (!hWnd)
    	{
    		MessageBox(0, TEXT("Die Erzeugung des Anwendungsfensters ist fehlgeschlagen!"), TEXT("3d Test OpenGL"), MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
    		return 0;
    	}
    
    	ShowWindow(hWnd, nCmdShow);
    	UpdateWindow(hWnd);
    
    	MSG msg;
    	BOOL bRet = false;
    	HACCEL hAccel = LoadAccelerators(hInstance, TEXT("TestProg"));
    
    	while (bRet = GetMessage(&msg, 0, 0, 0))
    	{
    		if (bRet == -1)
    		{
    			MessageBox(hWnd, TEXT("Fehler in der Nachrichtenschlange!"), TEXT("3d Test OpenGL"), MB_OK | MB_ICONERROR);
    			return 0;
    		}
    		else if (hDlgRefine == 0 || !IsDialogMessage(hDlgRefine, &msg))
    		{
    			if (!TranslateAccelerator(hWnd, hAccel, &msg))
    			{
    				TranslateMessage(&msg);
    				DispatchMessage(&msg);
    			}
    		}
    	}
    	return int(msg.wParam);
    }
    
    LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hGLWnd;
    	static HINSTANCE	hInst;							// handle to the main-window
    	static int			cxClient, cyClient;				// Window client size
    	static int			numElements;					// anzahl an elementen
    
    	switch(Msg)
    	{
    	case WM_CREATE:
    		hInst = ((LPCREATESTRUCT)lParam)->hInstance;
    
    		hGLWnd = CreateWindow(TEXT("GL_Window"), 0, WS_CHILDWINDOW | WS_VISIBLE, 
    			0, 0, 0, 0, hWnd, (HMENU)1, hInst, 0);
    
    		// ... Weiterer Code ...
    		return 0;
    	case WM_SIZE:
    		cxClient = LOWORD(lParam)/2;					// set new client width
    		cyClient = HIWORD(lParam);						// set new client hight
    		MoveWindow(hGLWnd, LOWORD(lParam)/2, 0, LOWORD(lParam)/2, HIWORD(lParam), TRUE);
    		return 0;
    
    	// ... weitere Messages ...
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    LRESULT CALLBACK GLWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	static PIXELFORMATDESCRIPTOR pdf;
    	pdf.nSize			= sizeof(PIXELFORMATDESCRIPTOR);
    	pdf.nVersion		= 1;
    	pdf.dwFlags			= PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
    	pdf.iPixelType		= PFD_TYPE_RGBA;
    	pdf.cColorBits		= 16;
    	pdf.cRedBits		= 0;
    	pdf.cRedShift		= 0;
    	pdf.cGreenBits		= 0;
    	pdf.cGreenShift		= 0;
    	pdf.cBlueBits		= 0;
    	pdf.cBlueShift		= 0;
    	pdf.cAlphaBits		= 0;
    	pdf.cAlphaShift		= 0;
    	pdf.cAccumBits		= 0;
    	pdf.cAccumRedBits	= 0;
    	pdf.cAccumGreenBits = 0;
    	pdf.cAccumBlueBits	= 0;
    	pdf.cAccumAlphaBits	= 0;
    	pdf.cDepthBits		= 16;
    	pdf.cStencilBits	= 0;
    	pdf.cAuxBuffers		= 0;
    	pdf.iLayerType		= PFD_MAIN_PLANE;
    	pdf.bReserved		= 0;
    	pdf.dwLayerMask		= 0;
    	pdf.dwVisibleMask	= 0;
    	pdf.dwDamageMask	= 0;
    
    	static HDC		hdc = 0;
    	static HGLRC	rc	= 0;
    
    	static int PixelFormat = 0;
    
    	switch(Msg)
    	{
    	case WM_CREATE:
    		if (!(hdc = GetDC(hWnd)))
    		{
    			MessageBox(hWnd, TEXT("Unable to create a device context for the GL window!"), 
    				TEXT("Error"), MB_OK | MB_ICONERROR);
    			DestroyWindow(GetParent(hWnd));
    		}
    		if (!(PixelFormat = ChoosePixelFormat(hdc, &pdf)))
    		{
    			MessageBox(hWnd, TEXT("Unable to find a suitable pixel format!"), 
    				TEXT("Error"), MB_OK | MB_ICONERROR);
    			DestroyWindow(GetParent(hWnd));
    		}
    		if (!SetPixelFormat(hdc, PixelFormat, &pdf))
    		{
    			MessageBox(hWnd, TEXT("Unable to set the pixel format!"), 
    				TEXT("Error"), MB_OK | MB_ICONERROR);
    			DestroyWindow(GetParent(hWnd));
    		}
    		if (!(rc = wglCreateContext(hdc)))
    		{
    			MessageBox(hWnd, TEXT("Unable to get a rendering context!"),
    				TEXT("Error"), MB_OK | MB_ICONERROR);
    			DestroyWindow(GetParent(hWnd));
    		}
    		if (!wglMakeCurrent(hdc, rc))
    		{
    			MessageBox(hWnd, TEXT("Unable to make the rendering context current!"), 
    				TEXT("Error"), MB_OK | MB_ICONERROR);
    			DestroyWindow(hWnd);
    		}
    		if (!InitGL())
    		{
    			MessageBox(hWnd, TEXT("Initialization failed."), 
    				TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
    			DestroyWindow(GetParent(hWnd));
    		}
    		return 0;
    	case WM_SIZE:
    		ResizeGlScene(LOWORD(lParam), HIWORD(lParam));
    		return 0;
    	case WM_PAINT:
    		DrawGLScene();
    		SwapBuffers(hdc);
    		return 0;
    	case WM_DESTROY:
    		KillGlWindow(hWnd, hdc, rc);
    	}
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    void KillGlWindow(HWND hWnd, HDC hdc, HGLRC rc)
    {
    	if (rc)
    	{
    		if (!wglMakeCurrent(0, 0))
    			MessageBox(0, TEXT("Release of dc and rc failed."), 
    				TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
    		if (!wglDeleteContext(rc))
    			MessageBox(0, TEXT("Release rendering context failed."), 
    				TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
    		rc = 0;
    	}
    	if (hdc && !ReleaseDC(hWnd, hdc))
    	{
    		MessageBox(0, TEXT("Release device context failed."), 
    			TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
    		hdc = 0;
    	}
    }
    

    hilft das weiter ?

    Danke im Voraus

    Mfg
    Knecht


Anmelden zum Antworten