(erledigt) Gesamten Hintergrund beim Ändern der Fenstergröße neu Laden -> WM_PAINT, Bitmap
-
cyberleon schrieb:
WM_SIZE scheint nicht das Richtige zu sein, weil es sich nur auf das Maximieren bzw. Minimieren von Fenstern bezieht.
Wo hast Du das denn her? Sieh mal in die Dokumentation:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632646(v=vs.85).aspx
-
Keks @ Belli!
Sorry, ich habe mich einfach zu sehr von den in WM_SIZE befindlichen Parametern SIZE_MAXHIDE, SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED irritieren lassen, anstatt mir die Remarks durchzulesen!
Remarks
If the SetScrollPos or MoveWindow function is called for a child window as a result of the WM_SIZE message, the bRedraw or bRepaint parameter should be nonzero to cause the window to be repainted.Ich kann also, indem ich in WM_SIZE den Parameter bRepaint = True an die Funktion MoveWindow übergebe das Neuladen meines Hintergrunds erzwingen! Nochmals, vielen lieben Dank!
P.S.
Da ich noch Anfänger in C bin, wüsste ich gerne, wie die Schreibweise ist, um nur das TRUE zu übergeben, das hwnd und die Fenstergrösse/Positionen sollte die Funktion MoveWindow ja schon haben:case WM_SIZE: { MoveWindow(hwnd,300,300,300,300,TRUE); // nur das TRUE für Position6 (bRepaint genannt) soll übergeben werden }
-
cyberleon schrieb:
P.S.
Da ich noch Anfänger in C bin, wüsste ich gerne, wie die Schreibweise ist, um nur das TRUE zu übergeben, das hwnd und die Fenstergrösse/Positionen sollte die Funktion MoveWindow ja schon haben:Woher?
-
Ich gebe zu, das war ein Denkfehler von mir, ich dachte, die Funktion würde standardmäßig beim Ändern der Fenstergröße aufgerufen und würde sich die entsprechenden Werte z.B. von der Mauscursorposition holen. An dieser Stelle wollte ich einschreiten und den Wert von bRepaint auf TRUE setzen, wenn MoveWindow im Falle von WM_SIZE verwendet wird.
EDIT
MoveWindow muss doch Standardmäßig irgendwo aufgeführt sein. Wie kann ich nur einen Wert der Funktion ändern? Und falls das nicht gehen sollte, woher bekomme ich die Werte des in der Größe veränderten Fensters? GetWindoRect liefert ja nur die des aktuellen Fensters, nicht des zukünftigen ...EDIT Update:
gerade nochmal die MoveWindow durchgegangen:bRepaint [in]
Type: BOOL
Indicates whether the window is to be repainted. If this parameter is TRUE, the window receives a message.Gibt es eine Möglichkeit, diese message selbst zu senden?
-
InvalidateRect(hwnd, NULL, true);
-
cyberleon schrieb:
woher bekomme ich die Werte des in der Größe veränderten Fensters?
Die werden Dir mit der Message WM_SIZE in lParam geliefert. Bitte lies doch mal die Dokumentation.
-
Ups, des hatte ich überlesen - also sollte die MoveWindow also mit LOWORD(lParam) und HIWORD(lParam) funktionieren, tut sie aber nicht ... ich habe zum Test mal einfach diese beiden Werte in textboxen ausgegeben, und sie flackern wie wild - offenbar bedeuten sie andauernd was anderes ...
case WM_SIZE: { RECT rect; GetWindowRect(hwnd, &rect); char buffer5[5]; itoa(LOWORD(lParam), buffer5, 10); textBox7 = CreateWindow(TEXT("edit"), TEXT(buffer5), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 245, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); char buffer6[5]; itoa(HIWORD(lParam), buffer6, 10); textBox8 = CreateWindow(TEXT("edit"), TEXT(buffer6), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 285, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); MoveWindow(hwnd, rect.top, rect.left, 500, 500, TRUE); // funktioniert leider noch nicht: // MoveWindow(hwnd, rect.top, rect.left, LOWORD(lParam), HIWORD(lParam), TRUE); }
EDIT: OOOK, OOOK,
break; und
return 0; KÖNNTEN natürlich ETWAS helfen ... aber nur etwas, momentan. Ich bleib dran.
-
Wozu rufst Du GetClientRect auf? Diese Werte bekommst Du über lParam. Und wozu rufst Du überhaupt MoveWindow auf? Wenn Du WM_SIZE bekommst, dann hat Dein Fenster bereits eine neue Position und die willst Du doch nicht verändern!?
Edit:
Okay, Du rufst nicht GetClientRect, sondern GetWindowRect auf ... um dann via MoveWindow das Fenster dahin zu verschieben, wo es sowieso schon ist?
-
Und wieso rufst Du bitte in WM_SIZE MoveWindow noch mal auf. Das ist krank und recursiv.
Ansonsten erfolgt ein Repaint bei der Größenänderung auch nur wenn Du das in der Klasse angegeben hast. Und dann automatisch...
Ich vermute mal Du hast Deine Klase falsch definiert.
-
@ Belli
lParam beinhaltet noch mehr als LOWORD(lParam) und HIWORD(lParam)?Sorry, aber in der WM_SIZE stand davon nichts, nur:
lParam
The low-order word of lParam specifies the new width of the client area.
The high-order word of lParam specifies the new height of the client area.also Breite und Höhe des neuen Fensters - aber für die MoveWindow brauche ich x und y Position des Fensters - und Höhe und Breite des Fensters.
AAAAAH ! Ich sehe gerade, dass lParam NICHT das hat was ich brauche! lParam hat die Breite und Höhe des Clients - ich brauche für Movewindow aber Höhe und Breite des Fensters!Okay, Du rufst nicht GetClientRect, sondern GetWindowRect auf ... um dann via MoveWindow das Fenster dahin zu verschieben, wo es sowieso schon ist?
Quasi richtig. Aber diesmal mit bRepaint = True, damit während des Änderns der Fenstergrösse der gesamte Fensterhintergrund aktualisiert wird, nicht nur der linke und untere Bildschirmrand.
@ Martin
Und wieso rufst Du bitte in WM_SIZE MoveWindow noch mal auf. Das ist krank und recursiv.
Wo rufe ich denn zweimal MoveWindow auf? Das zweite MoveWindow ist ausgequotet.
Wie gebe ich denn in der Klasse mein Repaint an? Du weisst ja, ich bin nub
Ich habe nun meinen Code soweit vervollständigt, dass ich das Fenster korrekt darstellen kann, diesmal garantiert mit bRepaint = True. Leider ist das Resultat das selbe wie komplett ohne alles, der Hintergrund wird einfach nicht repaintet wenn ich die Fenstergröße ändere.
case WM_SIZE: { RECT rect; GetWindowRect(hwnd, &rect); char buffer5[5]; itoa(LOWORD(lParam), buffer5, 10); textBox5 = CreateWindow(TEXT("edit"), TEXT(buffer5), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 165, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); char buffer6[5]; itoa(HIWORD(lParam), buffer6, 10); textBox6 = CreateWindow(TEXT("edit"), TEXT(buffer6), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 205, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); char buffer7[5]; itoa(rect.bottom-rect.top, buffer7, 10); textBox7 = CreateWindow(TEXT("edit"), TEXT(buffer7), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 245, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); char buffer8[5]; itoa(rect.right-rect.left, buffer8, 10); textBox8 = CreateWindow(TEXT("edit"), TEXT(buffer8), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, 110, 285, 50, 20, hwnd, (HMENU) 1, NULL, NULL ); MoveWindow(hwnd, rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top, TRUE); // (hwnd, Fensterpositionx, Fensterpositiony, Fensterbreite, Fensterhöhe, bRepaint break; return 0; }
-
cyberleon schrieb:
Okay, Du rufst nicht GetClientRect, sondern GetWindowRect auf ... um dann via MoveWindow das Fenster dahin zu verschieben, wo es sowieso schon ist?
Quasi richtig. Aber diesmal mit bRepaint = True, damit während des Änderns der Fenstergrösse der gesamte Fensterhintergrund aktualisiert wird, nicht nur der linke und untere Bildschirmrand.
Wenn Du 'nur' erreichen willst, dass Dein Fenster neu gezeichnet wird, dann ist MoveWindow dafür nicht die geeignete Methode.
Die Aufgabe dieser Funktion geht doch schon aus dem Namen hervor!
-
WM_SIZE ist die Antwort auf ein MoveWindow. MoveWndow löst also WM_SIZE aus.
Wen Du eine Klasse registrierst gibt es auch dise Klassen Styles:
CS_HREDRAW und CS_VREDRAW
http://msdn.microsoft.com/en-us/library/aa925944.aspxAnsonsten erzwingt man ein Neuzeichnen durch InvalidateRect und nichts anderes.
Wie wäre es wenn Du ein Tutorial ganz duchliest und dananch anfängst Fragen zu stellen?
-
Keks @ Belli
Danke, ist mir nun aufgefallen - ich wusste vorher nicht das WM_SIZE DURCH Move_Window aufgerufen wird.
Schokokeks @ Martin
Ich habe es nun noch einmal mit InvalidateRect versucht, und es klappt! Mein Problem war, dass WM_SIZE eben nicht NUR durch Move_Window aufgerufen wird, jedenfalls wurde es dauerhaft aufgerufen. daher habe ich mir nun einen if catcher eingebaut (EDIT: ifs NICHT ineinander verschachteln.):
case WM_SIZE: { vergleichswert = jetztwert; vergleichswert2=jetztwert2; RECT rect; GetWindowRect(hwnd, &rect); jetztwert = rect.bottom-rect.top; jetztwert2 = rect.right-rect.left; if (jetztwert != vergleichswert) { del_img(); } if (jetztwert2 != vergleichswert2) { del_img(); } }
mit der vorher definierten Funktion:
int jetztwert; int vergleichswert; int jetztwert2; int vergleichswert2; int del_img() { RECT rc; GetClientRect(0, &rc); InvalidateRect(0, &rc, true); }
Allerdings flackert das Bild noch weiß beim Ändern der Fenstergröße - aber irgendwatt iss ja imma
- Vielen Dank soweit, für das Flackern denke ich lohnt ein neuer Thread
Oh, und Martin, du hast schon recht mit dem komplett Tutorial durcharbeiten, ABER: Wenn ich ein Tutorial durcharbeite, beschäftige ich mein Hirn vielleicht eine Stunde mit dem Problem. Wenn ich auf "gut Glück" versuche, mir selbst ein Problem zu setzen und es zu lösen, beschäftigt mich das den ganzen Tag, ich träume sogar von dem Problem. Bei mir ist der Lerneffekt in diesem Fall einfach größer als bei einem Tutorial - allein dadurch dass ich mich länger mit dem Problem beschäftige.
Außerdem ist es gut und richtig dass du mich immer wieder mal drauf hinweist, mir z.B. die WM_SIZE durchzulesen, weil die Lösung meines Problems ja drinsteht. Beim ersten Lesen der WM_SIZE habe ich nur nach den Parametern geguckt. Als du mich nochmal drauf angestoßen hast, habe ich mir auch die "Remarks" angesehen ... solangsam schwant mir, dass ich mir beim Verwenden einer neuen Funktion (die ich noch nicht kenne) tatsächlich wirklich ALLES doppelt, drei- und vierfach durchlesen muss! Das war (und ist!) ein wichtiger Lerneffekt für mich, vielen Dank dafür
EDIT:
Hier meine Suchergebnisse zum Thema "Flickern", mit denen ich das Flackern des Bildschirms beim Ändern der Fenstergrösse erfolgreich verhindern konnte:http://forums.codeguru.com/showthread.php?t=338319
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648055(v=vs.85).aspxTo completely avoid flickering, I would suggest to handle WM_ERASEBKGND, and return TRUE.
Quote: gsterken
case WM_ERASEBKGND: { return 0; }
An dieser Stelle: Keks @ gsterken ! (= cookie for gsterken !)