Einzelnen Beitrag anzeigen

sintronic86

Registriert seit: 7. Dez 2009
Ort: Barsinghausen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: [FMX] eigene Komponente (Aufbau & Performance)

  Alt 14. Dez 2016, 08:29
Hallo Leute,

bitte entschuldigt die verspätete Antwort.

Ich habe jetzt für alle meine genannten Probleme eine Lösung gefunden und möchte euch und natürlich auch allen, die evtl. nach mir an diesem Thema interessiert sind, meine Ergebnisse nicht vorenthalten.

1. Zu der Autosize-Property des TFlowLayouts:
Ich habe einen Nachfahren von TFlowLayout erstellt und diesem die gewünschte Property einfach selbst mitgegeben. Natürlich muss ich dann alle proceduren überschreiben, in denen eine Neuberechnung der Größe erforderlich ist:
- DoAddObject() - sobald dem FlowLayout ein Object hinzugefügt wird
- DoRemoveObject() - sobald vom FlowLayout ein Object entfernt wird
- Resize() - sobald sich die Größe des FlowLayouts ändert (bspw. durch vergrößern der Form, etc.)
Code:
  TFlowLayout = class(FMX.Layouts.TFlowLayout)
    private
      FAutoSize          : Boolean;
      FIsInAddRemoveObject: Boolean;

      procedure SetAutoSize(AAutoSize: Boolean);
    protected
      procedure DoAddObject(const AObject: TFmxObject); override;
      procedure DoAutoSize; virtual;
      procedure DoRemoveObject(const AObject: TFmxObject); override;
      procedure Resize; override;
    public
      constructor Create(AOwner: TComponent); override;

      property AutoSize: Boolean read FAutoSize write SetAutoSize;
  end;
Bisher funktioniert das wirklich einwandfrei!


2. Zu der Problematik meiner Komponente:
Ich habe jetzt eine wirklich performante Lösung gefunden, mit der ich mehr als zufrieden bin.
Meine Komponente ist ein Nachfahre von TControl. Und das ist auch das einzige Object, welches pro Komponente verwaltet werden muss, da ich die Oberfläche vollständig selbst zeichne.
Ich hatte anfänglich ja einige Schwierigkeiten mit der Paint-Procedure und den Entscheidungen, was genau neugezeichnet werden muss. Als ich mir dann aber das TImage genauer angesehen habe, habe ich festgestellt, dass dieses bei jedem Aufruf der Paint-Methode IMMER seinen GESAMTEN Bereich erneuert.
Es läuft jetzt folgendermaßen ab:
- Die Komponente hält ein "temporäres" TBitmap vor, auf das alle Sachen gezeichnet werden. Da dieses ja nicht sichtbar ist, gehen die Zeichen-Routinen sehr schnell von der Hand.
- Es gibt auslösende Events (mal von außen, mal von innen), die der Komponente mitteilen, das zumindest ein gewisser Bereich neugezeichnet werden muss
- Diese "Änderung" speichere ich innerhalb der Komponente und sage dann
Code:
Self.InvalidateRect(<< ein RectF >>);
Dadurch weiß die Komponente, dass sie neugezeichnet werden muss, wenn es soweit ist.
- Das daraus resultierende Aufrufen der "Paint"-Methode erfolgt erst dann, wenn die Komponente tatsächlich im sichtbaren Bereich ist. Das wird vom Framework gesteuert, muss ich mich also nicht drum kümmern.
- In der Paint-Methode gehe ich dann meine Änderungen durch, zeichne die entsprechenden Bereiche auf mein temporäres TBitmap und kopiere dieses am Ende IMMER auf das Canvas meiner Komponente.

So habe ich jetzt mal einen kleinen Test gemacht:
1000 * meine Komponente (wobei aus Platzgründen nur ca. 70 zeitgleich zu sehen sind) => neuzeichnen eines Bereichs alle 200ms => und es läuft, und es läuft, und es läuft....



Ich hoffe, ich konnte verständlich erklären, wie ich das jetzt gelöst habe. Wenn nicht, fragt einfach!
Und nochmal vielen Dank an alle, die sich die Mühe gemacht haben, mir Ideen zu liefern.
Björn
  Mit Zitat antworten Zitat