Warum flackert mein Dialog, wenn ich ihn größer ziehe?
-
Tja, ich weiß nicht so genau was da flackert! Alles irgendwie

-
Und wenn Du jetzt auch in OnEraseBkgnd der Buttons FALSE zurückgibst? Kann sein das Du dafür noch 'Benachrichtigen' einschalten musst.
-
Dann flackert immer noch alles

Trotzdem vielen Dank fürs viele Antworten, irgendeine Lösung finde ich sicher noch!
-
Lass es uns aber wissen

Sorry, ich bin mit meinem Latein am Ende, vieleicht hilft ja wirklich nur noch ein MemDC
-
Das Flackern beim Dialog Resize lässt sich nicth mit Double Buffering lösen, denn jedes Fenster hat seinen eigenen DC!
Besser WS_CLIPCHILDREN für den Dialog setzen!
-
Ich hab auch noch mal nachgeschaut und glaube, daß das hier genau das richtige für Dich ist:
http://www.codeproject.com/buttonctrl/NoFlicker.asp?df=100&forumid=151835&exp=0&select=1036290
Dort wird, wie schon von Martin vorgeschlagen, WS_CLIPCHILDREN benutzt.
-
Hallo!
Ihr seid echt klasse
Das flackern ist jetzt endlich weitgehend weg. Jetzt hab ich noch das Problem, dass ein Button nicht immer richtig gezeichnet wird. Aber das liegt vermutlich eher an meinem Code 
Vielen vielen Dank nochmal!
-
Hm, also ich hab mir das nochmal genauer angeschaut und getestet.
Wenn ich das Fenster schön ganz langsam größer ziehe, funktioniert alles super. Mache ich jetzt mit der Maus eine ganz schnelle Bewegung beim Fenster größer ziehen, bleibt einer der Buttons an der alten Stelle stehen. Ohne das Flag WS_CLIPCHILDREN passiert das nicht. Wie kann ich das jetzt noch abfangen?
-
Ist denn das ein besonderer Button?
-
Nein, der ist genauso angelegt wie die anderen auch. Das einzige "besondere" daran ist die Tatsache, dass er als letzter angelegt wird und nicht trapezförmig ist wie die anderen, sondern achteckig in der Mitte aller anderen Buttons

EDIT: Eine noch genauere Analyse. Vielleicht kann mir ja noch irgendjemand helfen:
Ich denke, es liegt (wie gesagt) am WS_CLIPCHILDREN. Dieser Fensterstil bewirkt ja, dass der Bereich, in dem sich die Child-Windows befinden, ausgespart wird beim neuen Zeichnen. Allerdings werden in der OnSize()-Methode alle Buttons mit neuen Koordinaten belegt und beim langsamen Ziehen ja auch neu gezeichner. Ich verwende auch noch zwei kleine Static-Controls in meinem Dialog, bei denen mit dem Fensterstil WS_CLIPCHILDREN der Hintergrund verschwindet und der Fensterhintergrund erscheint. Das könnte man evtl. mit OnCtlColor lösen, oder?
Ich poste hier mal meine OnSize-Methode hin, vielleicht kann ja jemand meinen Fehler entdecken?void CStartdialog3Dlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); CRect rect; CRgn rgn, rgnDialogZiehen, rgnDialogVergroessern; GetClientRect(&rect); if(rect.Height() < rect.Width()) offset = runden((double)rect.Height() / 3); else offset = runden((double)rect.Width() / 3); rect.SetRect(rect.left, rect.top, rect.left + 3 * offset, rect.top + 3 * offset); x = rect.left; y = rect.top; breite = rect.Width(); hoehe = rect.Height(); // Array für Eckpunkte des Dialogs CPoint p_dialog[8]; // Hilfsvariablen int tmp1 = runden(0.1 * (double)offset); int tmp2 = runden(0.05 * (double)offset); // Größen, die für die Berechnung des Achtecks gebraucht werden kantenlaenge = offset; hilfskante = runden((double)kantenlaenge / sqrt(2)); kantenlaengeInnen = offset - 12 * tmp2; hilfskanteInnen = runden((double)kantenlaengeInnen / sqrt(2)); kantenlaengeRand = offset - 2 * tmp2; hilfskanteRand = runden((double)kantenlaengeRand / sqrt(2)); // Eckpunkte des Dialogs erzeugen CPoint d1(offset, tmp1); CPoint d2(2 * offset, tmp1); CPoint d0(d1.x - hilfskante, d1.y + hilfskante); CPoint d3(d2.x + hilfskante, d2.y + hilfskante); CPoint d4(d3.x, d3.y + kantenlaenge); CPoint d5(d2.x, d4.y + hilfskante); CPoint d6(d1.x, d5.y); CPoint d7(d0.x, d4.y); // Eckpunkte in Array speichern p_dialog[0] = d0; p_dialog[1] = d1; p_dialog[2] = d2; p_dialog[3] = d3; p_dialog[4] = d4; p_dialog[5] = d5; p_dialog[6] = d6; p_dialog[7] = d7; // 8-Eck erzeugen und zwei Regionen zum verschieben/vergrößern dransetzen rgn.CreatePolygonRgn(p_dialog, 8, ALTERNATE); rgnDialogZiehen.CreateEllipticRgn(d1.x - tmp1, 0, d1.x + tmp1, d1.y + tmp1); CombineRgn(rgn, rgn, rgnDialogZiehen, RGN_OR); rgnDialogVergroessern.CreateEllipticRgn(d5.x - tmp1, d5.y - tmp1, d5.x + tmp1, d5.y + tmp1); CombineRgn(rgn, rgn, rgnDialogVergroessern, RGN_OR); SetWindowRgn(static_cast<HRGN>(rgn.GetSafeHandle()), TRUE); if(m_buttonsInitialisiert) { // Innen - Eckpunkte des Achtecks innen erzeugen CPoint b(d1.x + 6 * tmp2, d1.y + 14 * tmp2); CPoint c(d2.x - 6 * tmp2, d2.y + 14 * tmp2); CPoint a(b.x - hilfskanteInnen, b.y + hilfskanteInnen); CPoint d(c.x + hilfskanteInnen, c.y + hilfskanteInnen); CPoint e(d.x, d.y + kantenlaengeInnen); CPoint f(c.x, e.y + hilfskanteInnen); CPoint g(b.x, f.y); CPoint h(a.x, e.y); // Außen - Eckpunkte der Buttons erzeugen CPoint b_(d1.x + tmp2, d1.y + tmp2 + tmp2); CPoint c_(d2.x - tmp2, d2.y + tmp2 + tmp2); CPoint a_(b_.x - hilfskanteRand, b_.y + hilfskanteRand); CPoint d_(c_.x + hilfskanteRand, c_.y + hilfskanteRand); CPoint e_(d_.x, d_.y + kantenlaengeRand); CPoint f_(c_.x, e_.y + hilfskanteRand); CPoint g_(b_.x, f_.y); CPoint h_(a_.x, e_.y); // Vektor anlegen, der die Eckpunkte der Buttons aufnimmt std::vector<CPoint> pts; // Button1 anlegen pts.push_back(b_); pts.push_back(c_); pts.push_back(c); pts.push_back(b); m_button1.SetPoints(pts); m_button1.setRgn(); // Button2 anlegen pts.clear(); pts.push_back(c_); pts.push_back(d_); pts.push_back(d); pts.push_back(c); m_button2.SetPoints(pts); m_button2.setRgn(); // Button3 anlegen pts.clear(); pts.push_back(d); pts.push_back(d_); pts.push_back(e_); pts.push_back(e); m_button3.SetPoints(pts); m_button3.setRgn(); // Button4 anlegen pts.clear(); pts.push_back(e_); pts.push_back(f_); pts.push_back(f); pts.push_back(e); m_button4.SetPoints(pts); m_button4.setRgn(); // Button5 anlegen pts.clear(); pts.push_back(g); pts.push_back(f); pts.push_back(f_); pts.push_back(g_); m_button5.SetPoints(pts); m_button5.setRgn(); // Button6 anlegen pts.clear(); pts.push_back(g); pts.push_back(g_); pts.push_back(h_); pts.push_back(h); m_button6.SetPoints(pts); m_button6.setRgn(); // Button7 anlegen pts.clear(); pts.push_back(a_); pts.push_back(a); pts.push_back(h); pts.push_back(h_); m_button7.SetPoints(pts); m_button7.setRgn(); // Button8 anlegen pts.clear(); pts.push_back(a_); pts.push_back(b_); pts.push_back(b); pts.push_back(a); m_button8.SetPoints(pts); m_button8.setRgn(); // Button9 anlegen pts.clear(); pts.push_back(a); pts.push_back(b); pts.push_back(c); pts.push_back(d); pts.push_back(e); pts.push_back(f); pts.push_back(g); pts.push_back(h); m_button9.SetPoints(pts); m_button9.setRgn(); rcVerschieben.SetRect(d1.x - runden(0.1 * (double)offset), 0, d1.x + tmp1, d1.y + tmp1); rcGroesseAendern.SetRect(d5.x - tmp1, d5.y - tmp1, d5.x + tmp1, d5.y + tmp1); if(symbol_verschieben->m_hWnd) symbol_verschieben->MoveWindow(rcVerschieben, TRUE); if(symbol_groesse_aendern->m_hWnd) symbol_groesse_aendern->MoveWindow(rcGroesseAendern, TRUE); } }
-
Das kann auch an einem fehlenden WS_CLIPSIBLINGS liegen.
-
Habe ich schon ausprobiert
Vor dem AufrufCDialog::OnInitDialog();in OnInitDialog() gibts einen Fehler, wenn ich das Programm starte, und wenn ich es hinter den Aufruf schreibe, ändert sich nichts...
Ich habe vorhin beim suchen was von BeginDeferWindowPos usw. gelesen. Kann mir das weiterhelfen? Wenn ja - wie und wo wird es benutzt?
EDIT: Wenn ich den Dialog schnell vergrößert habe und einer der Buttons nicht auf der aktuellen Position ist, wird er an die aktuelle Position gezeichnet, wenn ich mit der Maus drüberfahre. Kann ich dieses neu zeichnen nach dem resizen irgendwie erzwingen, nachdem ich die Maus wieder losgelassen habe und der Resize beendet ist?
-
Das macht man nicht in dem Dialog in OnInitDialog, sondern man gibt es direkt als Stil bei jedem Control im Dialogeditor an!
-
Hat leider trotzdem nichts gebracht. Ich weiß echt nicht was ich noch machen soll....
-
Hallo zusammen,
ich hab nun auch eine Lösung gefunden für das Problem der Buttons, die teilweise am Ende eines OnSize() nicht nachgezeichnet wurden. Ich rufe jetzt in der OnPaint()-Methode des Dialogs statt
CDialog::OnPaint();einfach
RedrawWindow();auf und schon funktioniert es

-
Glückwunsch!

Genügt evtl. auch ein Invalidate(FALSE)/*oder TRUE*/ am Ende der OnSize() ?