Bildzittert & Backgroundfarbe ändern klappt nicht



  • Hi,

    hab folgende 2 probleme:

    1. Wenn ich die Größe meines Fensters ändere, wird ja jedesmal ein neu gezeichnet, das sieht allerdings unschön aus. Während man die Größe ändert, zittert das Bild so - wie kann man das abstellen?

    2. Ich möchte gerne die Hintergrundfarbe meines Fensters ändern, allerdings klappt das nicht. Programm lässt sich kompilieren, aber die Farbe wird nicht gemalt.

    case WM_PAINT:
            {
                hDC = BeginPaint(hWnd, &ps);
                SetBkColor(hDC, RGB(90,0,0));
                SelectObject(hDC,GetStockObject(LTGRAY_BRUSH));
                Rectangle(hDC, 0, 0, cxClient / 4, cyClient);
    
                SelectObject(hDC, CreateSolidBrush(RGB(255,0,0)));
                Rectangle(hDC, cxClient/4, cyClient, cxClient - (cxClient / 4), cyClient);
                EndPaint(hWnd, &ps);
    
                return 0;
            }
    

    Den grauen Kasten den ich mit LTGRAY_BRUSH zeichne wird dargestellt, nur meine eigene, über RGB() definierte Farbe, nicht. Why?

    Danke für Hilfe.





  • dEsweiteren hab mal nen bisschen so ausgebaut das ich das Ding nachvollziehen kann also wenn ich mein Fenster groesser zieh sehe ich sehrwohl ein dunkleres Rechteck aber nen stueck weiter rechtsoben muesste bei Dir bestimmt genauso sein aber mein Tipp durch denn Link bringt auch nicht sehr viel denke ich

    hmm mal gucken





  • case WM_PAINT:
                hDC = BeginPaint(hwnd, &ps);
    
                HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0));
                GetClientRect(hwnd, &clientRect);
    
                HRGN hRgn = CreateRectRgnIndirect(&clientRect);
                FillRgn(hDC,hRgn,hBrush);
    
                EndPaint(hwnd, &ps);
                ReleaseDC(hwnd, hDC);
    
                break;
    


  • so kann ich den Hintergrund rot machen und bei mir das flackern unterbinden/mildern

    case WM_PAINT:
                hDC = BeginPaint(hwnd, &ps);
    
                HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0));
                GetClientRect(hwnd, &clientRect);
    
                HRGN hRgn = CreateRectRgnIndirect(&clientRect);
                FillRgn(hDC,hRgn,hBrush);
                ShowSize(hDC,10,10,cxClient,cyClient);
    
                EndPaint(hwnd, &ps);
                ReleaseDC(hwnd, hDC);
    
                break;
    
            case WM_SIZE:
                InvalidateRect(hwnd,0,false);
                UpdateWindow(hwnd);
                const int wert = lParam;
                cxClient =  wert << 16 >> 16; // Breite so ermittel hmm hab kein HIWORD Selbstbau
                cyClient =  wert >> 16;       // höhe so ermitteln kien LOWORD selbstbau
                break;
    
            case WM_MOVE: {
                // zeichnen brauchst du hier nichst
                // und den hintergrund löschen mit true
                InvalidateRect(hwnd, NULL, true);
                UpdateWindow(hwnd);
                break;
                }
    
            case WM_ERASEBKGND:
                return (1); // Rückgabe muss ungleich "0" sein!
    
        }
    
        return 0;
    }
    
    void ShowSize(HDC hdc, int xPos, int yPos, int cx, int cy)
    {
        char buffer[512];
        sprintf(buffer,"width := %i height := %i", cx, cy);
        TextOut(hdc,xPos,yPos,buffer,strlen(buffer));
    }
    


  • ShowSize habsch nur eingebaut damit was zusehen ist damit ich das eventuell wahnnsinnig flackern besser sehe



  • GetClientRect

    erwartet einen Pointer auf eine Struktur des Types RECT

    bei mir

    RECT clientRect;
    

    und eben mit initialisiert durch

    GetClientRect(hwnd, &clientRect);
    

    so jetzt muesste ichs rund bekommen haben fuer Dich
    is ja auch schon spät. 🙂



  • achj Das Object hBrush muss auch gelöscht werden

    DeleteObject(hBrush);
    


  • case WM_PAINT: 
                hDC = BeginPaint(hwnd, &ps); 
    
                HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0)); 
                GetClientRect(hwnd, &clientRect); 
    
                HRGN hRgn = CreateRectRgnIndirect(&clientRect); 
                FillRgn(hDC,hRgn,hBrush); 
                ShowSize(hDC,10,10,cxClient,cyClient); 
    
                EndPaint(hwnd, &ps); 
                ReleaseDC(hwnd, hDC); 
                DeleteObject(hBrush);
                break; 
    
            case WM_SIZE: 
                InvalidateRect(hwnd,0,false); 
                UpdateWindow(hwnd); 
                const int wert = lParam; 
                cxClient =  wert << 16 >> 16; // Breite so ermittel hmm hab kein HIWORD Selbstbau 
                cyClient =  wert >> 16;       // höhe so ermitteln kien LOWORD selbstbau 
                break; 
    
            case WM_MOVE: { 
                // zeichnen brauchst du hier nichst 
                // und den hintergrund löschen mit true 
                InvalidateRect(hwnd, NULL, true); 
                UpdateWindow(hwnd); 
                break; 
                } 
    
            case WM_ERASEBKGND: 
                return (1); // Rückgabe muss ungleich "0" sein! 
    
        } 
    
        return 0; 
    } 
    
    void ShowSize(HDC hdc, int xPos, int yPos, int cx, int cy) 
    { 
        char buffer[512]; 
        sprintf(buffer,"width := %i height := %i", cx, cy); 
        TextOut(hdc,xPos,yPos,buffer,strlen(buffer)); 
    }
    


  • Ihr macht haufenweise GDI-Leaks....vllt. solltet ihr euch mal mit DeleteObject() auseinander setzen. 💡

    => http://msdn.microsoft.com/library/en-us/gdi/devcons_1vsk.asp

    Beispiel:

    HRGN hRgn = CreateRectRgnIndirect(&clientRect);
    

    Die erstellte Region muss mittels DeleteObject() auch wieder gelöscht werden!



  • @sclearscreen: Meinst du nicht, dass ein bis zwei Posts genügt hätten 😮

    Also dann noch was zum eigentlichen Thema 👍 :

    1. Tipp:

    WNDCLASSEX	wndclex;
    // ...
    wndclex.cbSize = sizeof(WNDCLASSEX);
    wndclex.style  = 0; // kein: CS_VREDRAW | CS_HREDRAW
    // ...
    

    2. Tipp:
    DoubleBuffering... siehe: 💡 Hier! 💡

    3. Tipp:

    case WM_ERASEBKGND:
          return (1);
    

    Hoffe ich konnte helfen 😉



  • Heeeeyyyy Super - cool viel, vielen Dank für eure Mühe.

    Oder Verbesserungsvorschläge für den Stil? Ich möchte mir nichts unschönes angewöhnen, das wird man später immer so schwer wieder los 😉

    Aber schonmal dicken thx!

    Hier mal mein WndProc - sind da jetzt noch leaks drin?

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC			hDC;
    	PAINTSTRUCT ps;
    	static HWND	hButNeu;
    	static HWND	hButAbort;
    	static HWND	hWndNeu;
    	static HBRUSH	hBrush;
    	static RECT	clientRect;
    	static int	cxClient;
    	static int	cyClient;
    
    	switch (message)
    	{
    	case WM_CREATE:
    		{
    			hButNeu = CreateWindow(TEXT("button"), TEXT("Neu"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    								0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    
    			hButAbort = CreateWindow(TEXT("button"), TEXT("Abbrechen"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    								0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    
    		return 0;
    		}
    
    	case WM_COMMAND:
    		{
    			if(lParam == (LPARAM)hButNeu)
    			{
    				if(HIWORD(wParam) == BN_CLICKED)
    				{
    					hWndNeu = CreateWindow(TEXT("SUB"), TEXT("PoP"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 320, 240, CW_USEDEFAULT, CW_USEDEFAULT,
    											NULL, NULL, NULL, NULL);
    
    				}
    			}
    
    			if(lParam == (LPARAM)hButAbort)
    				if(HIWORD(wParam) == BN_CLICKED)
    					MessageBox(hWnd, TEXT("Abbruch"), TEXT("Wird schon fertig..."), MB_OK);
    
    			return 0;
    		}
    	case WM_SIZE:
    		{
    		cxClient = LOWORD(lParam);
    		cyClient = HIWORD(lParam);
    
    		MoveWindow(hButNeu, 10, 10, cxClient / 8, cyClient / 12, TRUE);
    		MoveWindow(hButAbort, 10, 70, cxClient / 8, cyClient / 12, TRUE);
    		return 0;
    		}
    
    	case WM_PAINT:
    		{
    			hDC = BeginPaint(hWnd, &ps);
    
    			hBrush = CreateSolidBrush(RGB(130,0,130));
    			GetClientRect(hWnd, &clientRect);
    			HRGN hRgn = CreateRectRgnIndirect(&clientRect);
    			FillRgn(hDC,hRgn,hBrush);
    
    			SelectObject(hDC,GetStockObject(LTGRAY_BRUSH));
    			Rectangle(hDC, 0, 0, cxClient / 4, cyClient);
    			EndPaint(hWnd, &ps);
    
    			DeleteObject(hBrush);
    			DeleteObject(hRgn);
    
    			return 0;
    		}
    		case WM_ERASEBKGND:
    			return(1);
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    LRESULT CALLBACK ChildProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    { 
    	switch(message)
    	{
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
         return (0);
    	}
    
       return DefWindowProc (hwnd, message, wParam, lParam); 
    }
    


  • CodeFinder schrieb:

    @sclearscreen: Meinst du nicht, dass ein bis zwei Posts genügt hätten 😮

    Also dann noch was zum eigentlichen Thema 👍 :

    1. Tipp:

    WNDCLASSEX	wndclex;
    // ...
    wndclex.cbSize = sizeof(WNDCLASSEX);
    wndclex.style  = 0; // kein: CS_VREDRAW | CS_HREDRAW
    // ...
    

    2. Tipp:
    DoubleBuffering... siehe: 💡 Hier! 💡

    3. Tipp:

    case WM_ERASEBKGND:
          return (1);
    

    Hoffe ich konnte helfen 😉

    🤡 jo sicherlich hmm entschuldigung @Threadersteller das ich Dich zugeschüttet habe!

    @CodeFinder bin kein WinAPI-Guru
    deshalb Leak bei HRGN jo aber klar wirkt sich auf Dauer übel aus, jo man lernt nie aus. Dann noch zu so später Stunde 😮
    neb



  • @sclearscreen: Kein Problem 😉 👍

    _________________________________________________________________________

    Oder Verbesserungsvorschläge für den Stil? Ich möchte mir nichts unschönes angewöhnen, das wird man später immer so schwer wieder los 😉

    Jo, das ist gut...Also:

    1.:
    Du hast bei jedem Case klammern gesetzt...kann man machen...ist aber nicht unbedingt nötig...vllt ohne sogar übersichtlicher:

    switch (message)
        {
        case WM_CREATE:
            // ...
            return 0;
    
        case WM_COMMAND:
            // ...
            return 0;
    
    // usw.
        }
    

    2.:
    Du hast fast alle Variablen static gemacht...glaub das ist bspw. bei

    RECT clientRect;
    

    überflüssig...
    Musst du mal durchgehen. 😉

    3.:
    Weiterhin würde ich dir bei WM_COMMAND ein switch der Control IDs empfehlen...das kannst du dann auch ein Switch einbauen...ist übersichtlicher...so: 💡 ➡

    // ...
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case BTN_BUTTON1:
                    // ...
                    break;
                // usw.
            }
            return 0;
    // weitere Nachrichten...
    

    Mir fällt gerade auf...das du die gar nicht festgelegt hast...also das geht entweder direkt bei CreateWindow(Ex):

    hButNeu = CreateWindow(TEXT("button"), TEXT("Neu"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                           0, 0, 0, 0, hWnd, (HMENU)NUMMER, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    // z.B.: const int BTN_START =  7000; // C++
    // z.B.: #define BTN_START      7000; // C
    //  dann schreibst du statt NUMMER einfach BTN_START (nat. vorher deklarieren)
    

    oder nachträglich (hier nicht empfehlenswert):

    SetWindowLong(hButton, GWL_ID, NUMMER); // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    

    Sonst ist der Code vollkommen in Ordnung 👍



  • [quote="CodeFinder"]

    3.:
    Weiterhin würde ich dir bei WM_COMMAND ein switch der Control IDs empfehlen...das kannst du dann auch ein Switch einbauen...ist übersichtlicher...so: 💡 ➡

    // ...
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case BTN_BUTTON1:
                    // ...
                    break;
                // usw.
            }
            return 0;
    // weitere Nachrichten...
    

    Mir fällt gerade auf...das du die gar nicht festgelegt hast...also das geht entweder direkt bei CreateWindow(Ex):

    in LWORD(wParam) steht die ID des jeweiligen Fensters? Kann ich diese Idee beliebig vergeben oder werden die durch windows automatisch hochgezählt?



  • in LWORD(wParam) steht die ID des jeweiligen Fensters? Kann ich diese Idee beliebig vergeben oder werden die durch windows automatisch hochgezählt?

    Idee oder ID ? 😃

    In LOWORD von wParam steht die ID, ja...aber nur unter WM_COMMAND! Ja du kannst die ID beliebig vergeben, Windows wird dir da nicht reinfuschen^^:

    Das hab ich dir doch schon geschrieben:

    CodeFinder schrieb:

    Mir fällt gerade auf...das du die gar nicht festgelegt hast...also das geht entweder direkt bei CreateWindow(Ex):

    hButNeu = CreateWindow(TEXT("button"), TEXT("Neu"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                           0, 0, 0, 0, hWnd, (HMENU)NUMMER, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    // z.B.: const int BTN_START =  7000; // C++
    // z.B.: #define BTN_START      7000; // C
    //  dann schreibst du statt NUMMER einfach BTN_START (nat. vorher deklarieren)
    

    oder nachträglich (hier nicht empfehlenswert):

    SetWindowLong(hButton, GWL_ID, NUMMER); // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    

    :



  • CodeFinder schrieb:

    in LWORD(wParam) steht die ID des jeweiligen Fensters? Kann ich diese Idee beliebig vergeben oder werden die durch windows automatisch hochgezählt?

    Idee oder ID ? 😃

    In LOWORD von wParam steht die ID, ja...aber nur unter WM_COMMAND! Ja du kannst die ID beliebig vergeben, Windows wird dir da nicht reinfuschen^^:

    Das hab ich dir doch schon geschrieben:

    CodeFinder schrieb:

    Mir fällt gerade auf...das du die gar nicht festgelegt hast...also das geht entweder direkt bei CreateWindow(Ex):

    hButNeu = CreateWindow(TEXT("button"), TEXT("Neu"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                           0, 0, 0, 0, hWnd, (HMENU)NUMMER, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    // z.B.: const int BTN_START =  7000; // C++
    // z.B.: #define BTN_START      7000; // C
    //  dann schreibst du statt NUMMER einfach BTN_START (nat. vorher deklarieren)
    

    oder nachträglich (hier nicht empfehlenswert):

    SetWindowLong(hButton, GWL_ID, NUMMER); // NUMMER ist eine ganzzahle Konstante = ID des Buttons
    

    :

    Hm......... bei mir klappts nicht :(, wenn ich jetzt auf den Button klicke passiert nichts mehr.

    Noch eine Frage, ich caste ja die ID(ee) 😉 mit (HMENU), was ist den wenn ich jetzt mal ein menu angeben möchte? Wie vergebe ich den dann die ID des Steuerelements.

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC			hDC;
    	PAINTSTRUCT ps;
    	HBRUSH	hBrush;
    	RECT	clientRect;
    	HDC		hDCBkBuf;
    	HBITMAP hBM;
    	HRGN	hRgn;
    	static HWND	hButNeu;
    	static HWND	hButAbort;
    	static HWND	hWndNeu;
    	static int	cxClient;
    	static int	cyClient;
    
    	switch (message)
    	{
    	case WM_CREATE:
    		{
    			hButNeu = CreateWindow(TEXT("button"), TEXT("Neu"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    				0, 0, 0, 0, hWnd, (HMENU) 700, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    
    			hButAbort = CreateWindow(TEXT("button"), TEXT("Abbrechen"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    								0, 0, 0, 0, hWnd, (HMENU) 2, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    
    		return 0;
    		}
    
    	case WM_COMMAND:
    		{
    
    		if(LOWORD(wParam) == 700)
    		{
    			if(HIWORD(wParam) == BN_CLICKED)
    				{
    					hWndNeu = CreateWindow(TEXT("SUB"), TEXT("Erfassung der Mitarbeiterdaten"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 320, 240, CW_USEDEFAULT, CW_USEDEFAULT,
    											NULL, (HMENU) 3, NULL, NULL);
    
    				}
    		}
    return 0;
    


  • Olaf323 schrieb:

    Noch eine Frage, ich caste ja die ID(ee) 😉 mit (HMENU), was ist den wenn ich jetzt mal ein menu angeben möchte? Wie vergebe ich den dann die ID des Steuerelements.

    Du erzeugst doch ein Child-Fenster, eben einen Button; Die haben keine Menüs!

    Dann:

    Lass das:

    if(HIWORD(wParam) == BN_CLICKED)
    

    mal weg...vllt. gehts dann

    Olaf323 schrieb:

    Hm......... bei mir klappts nicht :(, wenn ich jetzt auf den Button klicke passiert nichts mehr.

    Bau da mal ne MessageBox(...) ein, um zu checken, ob dein Klick überhaupt ankommt 😉

    case WM_COMMAND:
        {
    
            if(LOWORD(wParam) == 700)
            {
                        MessageBox(0,"Button-ID: 700",0,0);
                        hWndNeu = CreateWindow(TEXT("SUB"), TEXT("Erfassung der Mitarbeiterdaten"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 320, 240, CW_USEDEFAULT, CW_USEDEFAULT,
                                                NULL, (HMENU) 3, NULL, NULL);
            }
        }
    


  • Olaf323 schrieb:

    Noch eine Frage, ich caste ja die ID(ee) 😉 mit (HMENU), was ist den wenn ich jetzt mal ein menu angeben möchte? Wie vergebe ich den dann die ID des Steuerelements.

    Wer möchte denn einem BUTTON (falls das überhaupt möglich ist - ich bezweifle es) ein Menü verpassen!?

    Greetz, Swordfish


Log in to reply