Bildzittert & Backgroundfarbe ändern klappt nicht
-
Hi,
hab folgende 2 probleme:
-
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?
-
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. beiRECT 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