Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: Invalidate, Repaint, Refresh, Update, Paint... ?

  Alt 14. Sep 2009, 14:34
Letzter Beitrag. Das Problem mit der Z-Order und nicht eigenen Komponenten lässt sich durch eine kleine nette Rekursion ja doch recht elegant lösen. Anbei die etwas bereinigte und rekusrsive Form:

Delphi-Quellcode:
procedure TMyGraphObject.RepaintOverlapping(item: TControl);
var
  i, itemIndex: Integer;
begin
  itemIndex := High(Integer);
  for i := 0 to Parent.ControlCount-1 do
  begin
    if (Parent.Controls[i] = item) then itemIndex := i;
    if (i > itemIndex) and (Parent.Controls[i] is TGraphicControl) and (Parent.Controls[i].Visible) and
      (((item.Top+item.Height) >= Parent.Controls[i].Top) and (item.Top <= (Parent.Controls[i].Top+Parent.Controls[i].Height)) and
      ((item.Left+item.Width) >= Parent.Controls[i].Left) and (item.Left <= (Parent.Controls[i].Left+Parent.Controls[i].Width))) then
    begin
      TMyGraphObject(Parent.Controls[i]).Paint;
      RepaintOverlapping(Parent.Controls[i]);
    end;
  end;
end;
Aufgerufen wird es aus der eigenen Komponente mit dem Parameter "self".

Die Rekursion terminiert, weil man keinen "Ring" aus sich jeweils an einer Stelle überlappenden Controls erzeugen kann, da sonst einem Control mehrere Z-Orders zukommen müssten. Daher ist dieses Vorgehen sicher.

Edit: Prüfung auf TGraphicControl eingebracht. Somit knallt man auch bei überlappenden WinControls nicht in eine Wand, da sie eben keine Paint-Methode haben. Diese sind zudem ohnehin kein Problem, da sie einen eigenen Canvas haben, der immer über GraphicControls des darunter befindlichen Parents gezeichnet wird.
Der Cast muss allerdings so bleiben, da TGraphicControl Paint ja noch nicht implementiert. D.h. man muss in seiner Komponente dies auf jeden Fall machen. Ich hab's mal mit diversen 3rd-Party Komponenten auf Basis von TGraphicControl probiert, und es ging mit bisher jedem.

Edit2: Bedingungen umgestellt. Ist jetzt noch eine kleine Ecke performanter durch Z-Order abfrage vor Überlappungstest, und ein paar Verschachtelungsebenen durch kombinierte Bedingungen gespart.
Vielleich wäre das ja sogar was für die CodeLib. Ich frage mich grad eh, warum Delphi das selbst nicht in ähnlicher Weise implementiert hat, und statt dessen da so sperrig mit DCs erzeugen und diversem anderen Overhead dran geht. Der Laufzeitunterschied ist ausgesprochen gewaltig.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat