AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Transparente Komponente - Flackern

Ein Thema von crypti · begonnen am 9. Nov 2006 · letzter Beitrag vom 13. Nov 2006
Antwort Antwort
crypti

Registriert seit: 12. Feb 2005
43 Beiträge
 
#1

Transparente Komponente - Flackern

  Alt 9. Nov 2006, 18:20
hi!

Ich hab mal wieder eine Frage und ich hoffe das mir jemand weiterhelfen kann.

Ich habe eine Komponente welche von CustomControl abgeleitet ist, da ich ein Handle brauche. Da ich diese auch auf Bilder o.ä. legen möchte, muss diese so wie standardmäßig ein GraphicControl transparent sein.
Das lässt sich ja über WS_EX_TRANSPARENT realisieren, kein Problem.

Nur wenn ich jetzt in der Paint Funktion Bilder o.ä. zeichnen möchte, dann kommt es natürlich zum Flackern. Eigentlich macht man da das DoubleBuffered an und gut ist. Jedoch funktioniert das bei einem Transparenten Fenster ja nicht.
Wenn ich DoubleBuffered:=true mache, dann ist der Bereich meiner Komponente Schwarz und nicht mehr transparent.

Nun dachte ich, man könnte die Zeichnungsaktivitäten erst in einem Bild (Bitmap) machen und dann am Ende der Paint Funktion einfach mit dem Original Canvas zusammenmergen, jedoch funktioniert das nicht.

Hat vielleicht einer ne Idee was man da noch machen kann?

Ich danke euch schon mal!!!!
  Mit Zitat antworten Zitat
Benutzerbild von chaosben
chaosben

Registriert seit: 27. Apr 2005
Ort: Görlitz
1.358 Beiträge
 
Delphi XE2 Professional
 
#2

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 06:16
Hi!
Zitat von crypti:
jedoch funktioniert das nicht.
Das ist zu ungenau. Was funktioniert nicht? Welche Fehlermeldungen?

Zitat von crypti:
Nun dachte ich, man könnte die Zeichnungsaktivitäten erst in einem Bild (Bitmap) machen und dann am Ende der Paint Funktion einfach mit dem Original Canvas zusammenmergen,
Das ist genau das, was du tun musst, um das Flackern zu beseitigen. Hier ein Beispiel:
Delphi-Quellcode:
var
  Buffer : TBitmap;
begin
  Buffer:=TBitmap.Create;
  Buffer.Width:=Self.Width //...usw
  
  //Transparenz entsteht, wenn man das anzeigt, was hinter dem Control ist
  //also fordern wir unseren Parent auf, genau das zu zeichnen
  DrawParentBackground(Buffer.Canvas.Handle);

  //Jetzt das malen, was wir wollen
  
  //Danach den Buffer ins Control malen
  BitBlt(Self.Canvas.Handle,
         0,0,
         Self.Width, Self.Height,
         Buffer.Canvas.Handle,
         0,0,
         SRCCOPY);
  
  Buffer.Free;
end;

//leider weiß ich nicht mehr, von wem die Prozedur war :(
procedure TMyControl.DrawParentBackground(AToDC : HDC);
var
  SaveIndex: Integer;
  Position: TPoint;
begin
  SaveIndex := SaveDC(AToDC);
  GetViewportOrgEx(AToDC, Position);
  SetViewportOrgEx(AToDC, Position.X - Left, Position.Y - Top, nil);
  IntersectClipRect(AToDC, 0, 0, Parent.ClientWidth, Parent.ClientHeight);
  Parent.Perform(WM_ERASEBKGND, AToDC, 0);
  Parent.Perform(WM_PAINT, AToDC, 0);
  RestoreDC(AToDC, SaveIndex);
end;
Benjamin Schwarze
If I have seen further it is by standing on the shoulders of Giants. (Isaac Newton)
  Mit Zitat antworten Zitat
martin-sun

Registriert seit: 11. Aug 2004
Ort: Weinheim
15 Beiträge
 
Delphi 2005 Professional
 
#3

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 09:13
Hallo,

das Flackern liegt IMHO daran, dass Windows trotz transparentem Style die WM_ERASEBKGND message sendet und das Control demnach den Hintergund löscht, bevor es sich selbst neu (transparent) zeichnet.
Bin gerade nicht zu Hause zum probieren, aber entweder kann man das Zeichnen des Hintergrunds mit einem zusätzlichen Style Flag verhindern, oder aber durch das überschreiben der Message.

Gruß
Martin
  Mit Zitat antworten Zitat
crypti

Registriert seit: 12. Feb 2005
43 Beiträge
 
#4

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 10:07
Hi!

Zitat von chaosben:
Zitat von crypti:
Nun dachte ich, man könnte die Zeichnungsaktivitäten erst in einem Bild (Bitmap) machen und dann am Ende der Paint Funktion einfach mit dem Original Canvas zusammenmergen,
Das ist genau das, was du tun musst, um das Flackern zu beseitigen. Hier ein Beispiel:
Delphi-Quellcode:
var
  Buffer : TBitmap;
begin
  Buffer:=TBitmap.Create;
  Buffer.Width:=Self.Width //...usw
  
  //Transparenz entsteht, wenn man das anzeigt, was hinter dem Control ist
  //also fordern wir unseren Parent auf, genau das zu zeichnen
  DrawParentBackground(Buffer.Canvas.Handle);

  //Jetzt das malen, was wir wollen
  
  //Danach den Buffer ins Control malen
  BitBlt(Self.Canvas.Handle,
         0,0,
         Self.Width, Self.Height,
         Buffer.Canvas.Handle,
         0,0,
         SRCCOPY);
  
  Buffer.Free;
end;

//leider weiß ich nicht mehr, von wem die Prozedur war :(
procedure TMyControl.DrawParentBackground(AToDC : HDC);
var
  SaveIndex: Integer;
  Position: TPoint;
begin
  SaveIndex := SaveDC(AToDC);
  GetViewportOrgEx(AToDC, Position);
  SetViewportOrgEx(AToDC, Position.X - Left, Position.Y - Top, nil);
  IntersectClipRect(AToDC, 0, 0, Parent.ClientWidth, Parent.ClientHeight);
  Parent.Perform(WM_ERASEBKGND, AToDC, 0);
  Parent.Perform(WM_PAINT, AToDC, 0);
  RestoreDC(AToDC, SaveIndex);
end;
Die Lösung kenne ich schon, jedoch bringt einen diese nicht ans Ziel. Wenn ich in der Paint Funktion über die DrawParentBackground arbeite, dann wird bei mir nicht der Hintergrund des Controls in das temporäre Bitmap gezeichnet, sondern es ist schlichtweg einfach nur weiß. Man kann das Bitmap ja nach der Erzeugung mit DrawParentBackground einfach mal abspeichern, aber es ist wirklich weiß.
Ich habe auch gesehen das diese Funktionen beim FlatPanel mit zum Einsatz kommen. Jedoch habe ich dort genau den gleichen Effekt. Es wird nicht transparent, sondern ist einfach nur weiß.

Aus diesem Grund habe ich oben auch geschrieben das es nicht funktioniert.


Was mit mitlerweile aufgefallen ist.

Wenn ich das Control mit WS_EX_TRANSPARENT zeichne, dann wird bei einem Zeichnen die Zeichenfläche nicht aktualisiert. Dies bedeutet, wenn ich in das Control ein Label o.ä. reinpacke, dann überdecken sich die Texte. Man muss hier im Paint ein zusätzliches Repaint auf das Parent des Controls ausführen. Wenn ich dieses Paint weglasse, dann flackert auch nichts mehr. Aber wenn ich ein Transparentes PNG o.ä. dort mit reinpacken will, dann brauche ich ja exakt den Hintergrund um immer die gleiche Darstellung zu erhalten. Sonst wird ein Grau nach der dritten Aktualisierung zu einem Grau.

Wenn man die Transparenz nur "simulieren" will und zwar über ein Bitmap das aus dem Hintergrund immer wieder neu entsteht, dann brauchen wir das WS_EX_TRANSPARENT ja überhaupt nicht. Wahrscheinlich ist diese Funktionsweise sogar die schnellste.

Ich danke euch das ihr euch meiner Fragen annehmt.

tschöööö
  Mit Zitat antworten Zitat
Benutzerbild von chaosben
chaosben

Registriert seit: 27. Apr 2005
Ort: Görlitz
1.358 Beiträge
 
Delphi XE2 Professional
 
#5

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 10:14
Ich nehme genau diese von mir oben beschriebe Methode um die CarbonCopy-Controls zu malen und diese sind transparent. Wenn das bei dir nicht funktioniert, dann deshalb weil du etwas anderes falsch machst. Lass zum Beispiel mal das WS_EX_TRANSPARENT weg.
Benjamin Schwarze
If I have seen further it is by standing on the shoulders of Giants. (Isaac Newton)
  Mit Zitat antworten Zitat
crypti

Registriert seit: 12. Feb 2005
43 Beiträge
 
#6

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 10:58
Kann es sein das es hier Unterschiede zwischen Delphi7 und Delphi 2005/2006 gibt? Weil wenn ich testweise exakt deinen Source verwende, dann isses trotzdem weiß.
  Mit Zitat antworten Zitat
Benutzerbild von chaosben
chaosben

Registriert seit: 27. Apr 2005
Ort: Görlitz
1.358 Beiträge
 
Delphi XE2 Professional
 
#7

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 11:38
Guck dir mal die Sourcen hier an. Vielleicht hilfts
Benjamin Schwarze
If I have seen further it is by standing on the shoulders of Giants. (Isaac Newton)
  Mit Zitat antworten Zitat
crypti

Registriert seit: 12. Feb 2005
43 Beiträge
 
#8

Re: Transparente Komponente - Flackern

  Alt 10. Nov 2006, 13:46
OK, mein Fehler.

Ich hatte im Formular noch ein DoubleBuffered:=true drin. Wenn man das hat und die Zeichnungsaktionen mit dem Bitmap dann versucht, dann kommt man zum weißen Bereich.

Das muss dann natürlich nur in der jeweiligen Komponente machen.
  Mit Zitat antworten Zitat
crypti

Registriert seit: 12. Feb 2005
43 Beiträge
 
#9

Re: Transparente Komponente - Flackern

  Alt 13. Nov 2006, 15:28
Gibt es hier noch eine effektivere Methode? Zum Beispiel mit dem WS_EX_TRANSPARENT?

Das was ich allerdings benötige, ist beim Paint immer ein sauberes abbild vom Hintergrund.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz