Warum flackert mein Dialog, wenn ich ihn größer ziehe?



  • connan schrieb:

    Hihi, sorry, das liegt daran, das wahscheinlich VS hinter dem Dialog liegt und dies als Hintergrund für den Dialog genommen wird. Guck mal genau da müstte auch Text stehen

    Ähm, ja, da steht auch ab und an mal Text 🙄

    Die andere Möglichkeit hab ich mal ausprobiert. Jetzt ist der Hintergrund zwar wieder farbig, aber dafür flackern doch wieder alles beim ziehen. Ich hab auch nochmal zur Kontrolle FALSE zurückgegeben und da flackert das ganze Ding nicht so 😞



  • Ja, man muss, glaube ich, auch FALSE zurückgeben (hab nicht nachgeschaut 🙄 ).
    Aber jetzt dürften zumindest nur noch die Buttons flackern?



  • 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 😕


  • Mod

    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);
    	}
    }
    

  • Mod

    Das kann auch an einem fehlenden WS_CLIPSIBLINGS liegen.



  • Habe ich schon ausprobiert 😞 Vor dem Aufruf

    CDialog::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?


  • Mod

    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() ?


Anmelden zum Antworten