DoubleBuffer im Panel aktivieren [gelöst]



  • Hi

    tut mir leid das ich wiedermal nerve, aber ich habe mal wieder ein problem das mir die hier die suche und google nicht "lösen" konnte.

    ich habe mit der GDI+ eine kleine grafik einen Panel eines Splitcontainers gezeichnet. Es flackert nur ab und zu 😞

    also habe ich ein wenig gelesen, und festgestellt ich müsste double Buffer anschalten.

    dann habe ich

    this->SetStyle(ControlStyles::DoubleBuffer|ControlStyles::UserPaint|ControlStyles::AllPaintingInWmPaint,true);
    

    eingegeben. damit habe ich für die Form doublebuffer und den empfohlenden anderen kram angeschalten.
    leider scheid das nur für die Form selber zu gelten.

    splitcontainer1->Panel1->SetStyle(ControlStyles::DoubleBuffer|ControlStyles::UserPaint|ControlStyles::AllPaintingInWmPaint,true);
    

    geht leider nicht, weil SetStyle eine geschütze funktion ist. um genau zu sagen, sie ist wohl protekted. Wie komme ich jetzt an das Panel rann? oder besser an die geschütze funktion?

    der Compiler meldet mir netter weise.

    Form1.h(32) : error C3767: "System::Windows::Forms::Control::SetStyle": Auf mögliche Funktion(en) kann nicht zugegriffen werden.
    

    fals das noch hilfreich ist.

    danke schonmal das ihr es gelesen habt.
    Grüße
    LoM



  • Du musst das Panel ableiten und dann im Konstruktor das setzen!



  • danke für die anwort.

    ich musste erstmal ein wenig lesen, habe noch nie eine klasse abgeleitet. Ich gebe zu eine sehr interesante möglichtkeit. das werde ich wohl demnächst häufiger verwenden 🙂

    ich weiß nicht ob ich das richtig gemacht habe (also der ansatz richtig ist). ich habe eine klasse geschrieben die panel ableitet und im konstruktor doublebuffer angeschalten.
    dieses abgeleitete panel habe ich dann ÜBER das panel vom splitcontainer gelegt. und die graphic darauf gezeichnet. leider flaktert es immernoch 😞

    ich habe irgendwas falsch gemacht, komme aber seit 2 tagen an der stelle nicht weiter 😞
    hilfe



  • schuldigung wenn ich nochmal nerve 😞

    ich habe jetzt mal den splitcontainer abgeleitung und in diesen das doublebuffer aktiviert.
    es flackert leider immernoch so unangenehm, man muss doch da bestimmt nochmehr beachten damit es nichtmehr so unangenehm blinkt oder?



  • So hab ich die SplitContainer-Klasse abgeleitet, ist das richtig?

    public ref class sContainer : public System::Windows::Forms::SplitContainer
    {
    public:
    	sContainer()
    	{
    		this->SetStyle(ControlStyles::DoubleBuffer|ControlStyles::UserPaint|ControlStyles::AllPaintingInWmPaint,true);
    	}
    };
    


  • xlomx schrieb:

    dieses abgeleitete panel habe ich dann ÜBER das panel vom splitcontainer gelegt. und die graphic darauf gezeichnet. leider flaktert es immernoch

    Wieso legst Du sowas ÜBER ein anderes Fenster? Damit wird es nie korrekt funktionieren. Du musst schon den gesamten Bereich kontrollieren können, damit Du das Flackern in Griff bekommst. Was Du machst führt eher zu noch mehr flackern. Wenn zwei Controls in den gleichen Bereich (selbstständig) zeichnen, dann führt das zwangsläufig zu Flackern, egal ob Du in jedem Control (einzeln) das Double-Buffer aktiviert hast oder nicht.
    Warum willst Du überhaupt zwei Controls überlagern?



  • Hi

    das war doch nur ein test mit den panel.
    ich habe die splitcontainer jetzt durch meine eigenen ersetzt. die haben eingeschaltete doublebuffer.

    ich habe zwei splitcontainer benutzt um die oberfläche zu dritteln. also ein splitcontainer der die oberfläche vertikal teilt und einen der das rechte splitcontainer-panel horizontal teilt.
    ist das keine so gute idee? sollte ich das lieber anders machen?



  • Und was geht dann jetzt nicht? Sollte doch alles gehen, oder?



  • es flackert noch 😞

    ich werde mal den teil des codes hier reinsetzten.

    dieses Stück wird beim onpaint-event ausgeführt.

    private: void DatenAnzeigenGrafik()
    		 {
    			int h=0;
    			Graphics^ g=this->splitContainer2->Panel2->CreateGraphics();
    		//	Graphics^ g=this->PanelAnzeige->CreateGraphics();
    			Rectangle Rechteck=this->splitContainer2->Panel2->ClientRectangle;
    		//	Brush^ b=gcnew Drawing::Drawing2D::LinearGradientBrush(splitContainer2->Panel2->ClientRectangle,Color::LightBlue,Color::Blue,135.0f);
    			Brush^ b=gcnew Drawing::Drawing2D::LinearGradientBrush(Rechteck,Color::LightBlue,Color::Blue,135.0f);
    		//	g->FillRectangle(b,splitContainer2->Panel2->ClientRectangle);
    			g->FillRectangle(b,Rechteck);
    			Pen^ p=gcnew Pen(Color::Black,3);
    		//	g->DrawRectangle(p,splitContainer2->Panel2->ClientRectangle);
    			g->DrawRectangle(p,Rechteck);
    			double x=splitContainer2->Panel2->ClientRectangle.Left+10;
    			double y=splitContainer2->Panel2->ClientRectangle.Top+10;
    			double x_Relativ=splitContainer2->Panel2->ClientRectangle.Right;
    			double y_Relativ=splitContainer2->Panel2->ClientRectangle.Bottom;
    			double Größe;
    			if ((y_Relativ/8)>(x_Relativ/12))
    				Größe=(x_Relativ/12);
    			else
    				Größe=(y_Relativ/8);
    			double Zeilenabstand=Größe*1.2;
    
    			//---Strom---
    			StringZeichnen(g,"current Ix",Größe/2,x, y+(h++*Zeilenabstand));
    			double MessStromA=MOTOEinstellungen->MeStrom();
    			Wert_in_Zeichen_m_Einheit(g, MessStromA,"Amp.",Größe, Color::LightGreen, x, y+(h++*Zeilenabstand)-Größe*0.4);
    			//---MessSpannung---
    			double MessSpannungA=MOTOEinstellungen->MeSpannung();
    			StringZeichnen(g,"voltage Vm",Größe/2,x, y+(h++*Zeilenabstand));
    			Wert_in_Zeichen_m_Einheit(g, MessSpannungA,"Volts",Größe, Color::LightGreen, x, y+(h++*Zeilenabstand)-Größe*0.4);
    			//---Widerstand---
    			StringZeichnen(g,"resistance Rx",Größe/2,x, y+(h++*Zeilenabstand));
    			double MessWiderstanda=MOTOEinstellungen->MeWiderstand();
    			if (MessSpannungA<=0)
    				ZeichenInRechteck(g,"      ",Größe,Color::LightSkyBlue,x, y+(h++*Zeilenabstand)-Größe*0.4);
    			if (MessWiderstanda<0)
    				ZeichenInRechteck(g,"deload",Größe,Color::LightSkyBlue,x, y+(h++*Zeilenabstand)-Größe*0.4);
    			if (MessWiderstanda>0)
    				Wert_in_Zeichen_m_Einheit(g, MessWiderstanda,"Ohm",Größe, Color::LightGreen, x, y+(h++*Zeilenabstand)-Größe*0.4);
    			delete(g);
    		 }
    

    die Klasse für den neuen splitcontainer

    public ref class sContainer : public System::Windows::Forms::SplitContainer
    {
    public:
    	sContainer()
    	{
    		this->SetStyle(ControlStyles::DoubleBuffer|ControlStyles::UserPaint|ControlStyles::AllPaintingInWmPaint,true);
    	}
    };
    

    Das sind die Funktionen zum zeichnen der Zeichen.

    void StringZeichnen(Graphics^ g,String^ S,double Schriftgröße,double x, double y)
    		 {
    			Drawing::Font^ sch=gcnew Drawing::Font( "Arial",(float)Schriftgröße );
    			SolidBrush^ drawBrush = gcnew SolidBrush( Color::Black );
    			g->DrawString(S,sch,drawBrush,(float)x,(float)y);
    		 }
    //
    //-----Zeichnet ein Rechteck mit Farbverlauf ins Weiße-----
    //
    		 void RechteckZeichnen(Graphics^ g,Color Farbe, double x, double y, double breite, double höhe)
    		 {
    			//Brush^ Pinsel=gcnew SolidBrush(Farbe);
    			Brush^ Pinsel=gcnew Drawing::Drawing2D::LinearGradientBrush(PointF((float)x,(float)y),PointF((float)(x+breite),(float)(y+höhe)),Color::White,Farbe);
    			g->FillRectangle(Pinsel,(float)x,(float)y,(float)breite,(float)höhe);
    			Pen^ p=gcnew Pen(Color::Black,1);
    			g->DrawRectangle(p,(float)x,(float)y,(float)breite,(float)höhe);
    		 }
    //
    //-----Zeichnet einen String mit der Größe 20 in Rechtecke-----
    //
    		 void ZeichenInRechteck(Graphics^ g, String^ S, Color Farbe, double x, double y)
    		 {
    			 for (int i=0;i<S->Length;i++)
    			 {
    			 RechteckZeichnen(g,Farbe,x+i*Zeichenabstand,y,30,45);
    			 StringZeichnen(g,S->Substring(i,1),30,x+i*Zeichenabstand-2,y);
    			 }
    		 }
     //
     //-----Zeichnet einen String mit variabler Größe in Rechecken
     //
    		 void ZeichenInRechteck(Graphics^ g, String^ S,double Größe, Color Farbe, double x, double y)
    		 {
    			 for (int i=0;i<S->Length;i++)
    			 {
    			 RechteckZeichnen(g,Farbe,x+i*(Größe*1.133),y,Größe,Größe*1.5);
    			 StringZeichnen(g,S->Substring(i,1),Größe,x+i*(Größe*1.133)-(Größe*0.0667),y);
    			 }
    		 }
    
    //-----Zeichnet einen Doublewert in Rechecke-----
    //-----Zeichnet einen Doublewert in Rechecke mit Einheit-----
    //
    		 void Wert_in_Zeichen_m_Einheit(Graphics^ g, double wert,String^ einheit,double Größe, Color Farbe, double x, double y)
    		 {
    			 int potenz;
    			 Potenz_dreier(&wert,&potenz);
    			 String^ WerteString=String::Format("{0,6:F}",wert);
    			 int i=0;
    			 ZeichenInRechteck(g,WerteString->Substring(0,6),Größe,Farbe,x,y);
    			 i+=6;
    			 switch (potenz)
    			 {
    			 case -15:
    				 StringZeichnen(g,"f",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case -12:
    				 StringZeichnen(g,"p",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case -9:
    				 StringZeichnen(g,"n",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case -6:
    				 StringZeichnen(g,"µ",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case -3:
    				 StringZeichnen(g,"m",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 0:
    				 StringZeichnen(g," ",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 3:
    				 StringZeichnen(g,"k",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 6:
    				 StringZeichnen(g,"M",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 9:
    				 StringZeichnen(g,"G",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 12:
    				 StringZeichnen(g,"T",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 case 15:
    				 StringZeichnen(g,"P",Größe,x+(i++)*(Größe*1.133),y);
    				 break;
    			 }
    			 Drawing::Font^ sch;
    			 if (einheit=="W")
    			 {
    				 sch=gcnew Drawing::Font( "Symbol",(float)Größe );
    				 StringZeichnen(g,einheit,sch,x+(i++)*(Größe*1.133),y);
    			 }
    			 else
    			 {
    				 sch=gcnew Drawing::Font( "Arial",(float)Größe );
    				 StringZeichnen(g,einheit,sch,x+(i++)*(Größe*1.133),y);
    			 }
    		 }
    //
    //-----gibt den Wert von 1-1000*10^ Potenz zurück-----
    //
    		 void Potenz_dreier(double *wert, int *potenz)
    		 {
    			 int x;
    			 x=(int)(System::Math::Log10(System::Math::Abs(*wert))-0);
    			 if (x<=0)
    				 x=x-3;
    			 x=x/3;
    			 if (x>=0)
    				 x=(x-0)*3;
    			 else
    				 x=x*3;
    			 *potenz=x;
    			 *wert=*wert/(System::Math::Pow(10,(double)x));
    		 }
    

    Die SplitContainer sind alle sContainer von meiner Klasse abgeleitet. Beim Form ist auch DoubleBuffer wie oben erwähnt aktiviert.

    schuldigung das ich so nerve, aber möchte das gerne hinbekommen und komme leider nicht weiter



  • Zeichnen darfst Du *nur* in OnPaint!!!



  • Hi

    ok, das funktioniert danke.

    zeichnen darf man nur in OnPaint.
    außerdem musste ich die vom Event mitgegebene Grafik benutzen, sonst hat es bei mir auch nicht funktioniert.

    Beispiel an einen Panel

    protected: virtual void PanelG::OnPaint (PaintEventArgs^ e) override
    {
    	this->System::Windows::Forms::Panel::OnPaint(e);
    
    	Graphics^ g=e->Graphics;    //zum Zeichnen benutzen
    //
    //...
    //
    
    };
    

Anmelden zum Antworten