Initialisierung von 'PenBlue' durch 'case'-Marke übersprungen



  • Hallo liebe Community,

    ich arbeite gerade mit dem Buch "Spieleprogrammierung mit DirectX" und bin gerade beim GDI angekommen. Ich habe den Code genau abgetippt und mir wirft der Compiler (Visual C++ 2010 EXPRESS) einige Fehler aus. Die eine steht im Titel.

    Hier einmal der Code:

    #include <Windows.h>
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    	case WM_PAINT:
    		PAINTSTRUCT ps;
    		HDC hDC;
    
    		hDC = BeginPaint(hWnd, &ps);
    
    		HPEN PenRed	  = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
    		HPEN PenGreen = CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
    		HPEN PenBlue  = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
    
    		SelectObject(hDC, PenBlue);
    		Ellipse(hDC, 60, 5, 340, 250);
    		Ellipse(hDC, 150, 190, 250, 210);
    
    		SelectObject(hDC, PenGreen);
    		Rectangle(hDC, 110, 40, 160, 80);
    		Rectangle(hDC, 240, 40, 290, 80);
    
    		SelectObject(hDC, PenRed);
    		MoveToEx(hDC, 200, 120, NULL);
    		LineTo(hDC, 180, 150);
    		LineTo(hDC, 220, 150);
    		LineTo(hDC, 200, 120);
    
    		DeleteObject(PenRed);
    		DeleteObject(PenGreen);
    		DeleteObject(PenBlue);
    
    		EndPaint(hWnd, &ps);
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    		break;
    	case WM_QUIT:
    		return 0;
    		break;
    	default:
    		return DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int CmdShow)
    {
    	HWND hWnd1;
    	MSG msg;
    
    	WNDCLASSEX WndClass1;
    	WndClass1.cbClsExtra	= NULL;
    	WndClass1.cbSize		= sizeof(WNDCLASSEX);
    	WndClass1.cbWndExtra	= NULL;
    	WndClass1.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	WndClass1.hCursor		= NULL;
    	WndClass1.hIcon			= NULL;
    	WndClass1.hIconSm		= NULL;
    	WndClass1.hInstance		= hInstance;
    	WndClass1.lpfnWndProc	= WndProc;
    	WndClass1.lpszClassName = "Class1";
    	WndClass1.lpszMenuName	= NULL;
    	WndClass1.style			= NULL;
    
    	if(!RegisterClassEx(&WndClass1))
    	{
    		MessageBox(NULL, "Fehler beim Registrieren der Fensterklasse!", "Fehler", MB_OK | MB_ICONERROR);
    		return 0;
    	}
    
    	hWnd1 = CreateWindowEx(WS_EX_CLIENTEDGE, "Class1", "Das ist ein Fenster", WS_OVERLAPPEDWINDOW, NULL, NULL, 1000, 800, NULL, NULL, hInstance, NULL);
    
    	ShowWindow(hWnd1, CmdShow);
    
    	while(GetMessage(&msg, hWnd1, NULL, NULL) > NULL)
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return 0;
    }
    

    Anscheinend werden die Initialisierungen übersprungen, aber warum, und wie kann ich das verhindern?



  • Ich habs "gelöst".

    Ich musste lediglich die Deklaration von der Definition trennen:

    HPEN PenRed;
    HPEN PenGreen;
    HPEN PenBlue;
    
    PenRed	  = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
    PenGreen  = CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
    PenBlue   = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
    

    Warum dies erst jetzt kompiliert wird, weiß ich auch nicht 😕



  • Der Code im WM_PAINT-Zweig könnte in eine eigene Funktion ausgelagert werden (bei der Länge von ~30 Zeilen ist das schon eine Überlegung wert).

    Wenn du Variablen innerhalb eines case-Zweiges deklarieren möchtest, muss ein neuer Scope her:

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd, &ps);
        ....
        break;
    }
    

    Im Übrigen solltest du lokale Variablen immer erst so spät wie möglich deklarieren und immer wenn es möglich ist, direkt initialisieren.



  • Thorgrim schrieb:

    Der Code im WM_PAINT-Zweig könnte in eine eigene Funktion ausgelagert werden (bei der Länge von ~30 Zeilen ist das schon eine Überlegung wert).

    Wenn du Variablen innerhalb eines case-Zweiges deklarieren möchtest, muss ein neuer Scope her:

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd, &ps);
        ....
        break;
    }
    

    Im Übrigen solltest du lokale Variablen immer erst so spät wie möglich deklarieren und immer wenn es möglich ist, direkt initialisieren.

    Okay, danke dir


Anmelden zum Antworten