Hallo Gemeinde,
anhand dieses Artikels in der Hilfe habe ich versucht eine eigene Komponente zu entwickeln:
http://docwiki.embarcadero.com/RADSt...henfl%C3%A4che
Ich bin aber mit der
beschriebenen Lösung unzufrieden!
Auf die Einschränkungen wird zwar dort auch eingegangen, aber vielleicht kennt ihr ja einen Trick für mein Problem.
Ich will bestehende Eigenkomponenten, die über ihren Canvas viel auf sich selber zeichnen auf Direct2D umstellen.
Dazu habe ich mir eine Zwischenklasse erstellt, die sehr ähnlich ist mit dem im Artikel beschriebenen Vorgehen.
Nun ist aber so, dass TCustomCanvas keine Propertys für Font, Pen, Brush und so weiter hat.
Ich möchte jedoch in den bestehenden Eigenkomponenten so wenig wie möglich ändern, also nicht unterscheiden zwischen
GDI- und Direct2D-Canvas wie in dem Beispiel für TCustomAcceleratedPaintBox.Paint:
Delphi-Quellcode:
procedure TCustomAcceleratedPaintBox.Paint;
begin
if FUseD2D then
begin
D2DCanvas.Font.Assign(Font);
D2DCanvas.Brush.Color := Color;
if csDesigning in ComponentState then
begin
D2DCanvas.Pen.Style := psDash;
D2DCanvas.Brush.Style := bsSolid;
D2DCanvas.Rectangle(0, 0, Width, Height);
end;
end else
begin
GDICanvas.Font.Assign(Font);
GDICanvas.Brush.Color := Color;
if csDesigning in ComponentState then
begin
GDICanvas.Pen.Style := psDash;
GDICanvas.Brush.Style := bsSolid;
GDICanvas.Rectangle(0, 0, Width, Height);
end;
end;
if Assigned(FOnPaint) then FOnPaint(Self);
end;
Am liebsten möchte ich einfach nur in der Vererbungslinie meiner Komponenten meine Zwischenklasse einfügen, zum Beispiel:
TMyComponent = class(TCustomPanel) wird zu TMyComponent = class(TD2DCustomPanel) mit class TD2DCustomPanel = class(TCustomPanel).
Da aber, wie gesagt, die wichtigsten Eigenschaften fehlen und man die leider nicht virtual in einer Interceptor-Klasse "faken" kann, sind dann solche Sachen nur möglich, wenn der Typ von Canvas explizit TCanvas oder TDirect2DCanvas ist:
Delphi-Quellcode:
procedure TPanel.Paint;
var
Rect : TRect;
TextWidth : Integer;
TextHeigt : Integer;
const
cHello = 'Hello World!';
begin
Canvas.Brush.Color := clGreen;
Canvas.FillRectangle(ClientRect);
Canvas.Pen.Color := clYellow;
Canvas.Pen.Width := ClientRect.Width div 50;
Rect := ClientRect;
InflateRect(Rect, -20, -20);
Canvas.Ellipse(Rect);
Canvas.Font.Name := 'Segoe UI';
Canvas.Font.Size := Rect.Width div 10;
Canvas.Font.Color := clWebOrange;
TextWidth := Canvas.TextWidth(cHello);
TextHeigt := Canvas.TextHeight(cHello);
Canvas.TextOut((ClientRect.Width - TextWidth) div 2 , (ClientRect.Height - TextHeigt) div 2, cHello);
end;
Hier habe noch mal in Quelltext per Kommentar markiert was mit der Artikel-Vorgehensweise nicht funktioniert und mich stört:
Delphi-Quellcode:
type
// Basisklasse für alle Panel-Komponenten, die anstatt mit GDI-Canvas mit
// Direct2D-Canvas gezeichnet werden sollen
TGNGPanel =
class(TPanel)
strict private
FUseD2D : Boolean;
FD2DCanvas : TDirect2DCanvas;
function CreateD2DCanvas : Boolean;
private
procedure WMPaint(
var Message : TWMPaint);
message WM_PAINT;
procedure WMSize(
var Message : TWMSize);
message WM_SIZE;
procedure SetAccelerated(
const Value : Boolean);
function GetGDICanvas : TCanvas;
function GetD2DCanvas : TDirect2DCanvas;
// TCustomCanvas; <--das geht nicht!
protected
procedure CreateWnd;
override;
procedure DestroyWnd;
override;
public
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
property Accelerated : Boolean
read FUseD2D
write SetAccelerated;
property Canvas : TDirect2DCanvas
// TCustomCanvas <--das geht nicht!
read GetD2DCanvas;
property GDICanvas : TCanvas
read GetGDICanvas;
end;
Hat vielleicht einer eine Idee bzw. eine elegante Lösung für mein Problem?
Ich habe auch ein Beispielprojekt angehangen zum experimentieren.