Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Benötige Hilfe beim Entwickeln einer Komponente (https://www.delphipraxis.net/98560-benoetige-hilfe-beim-entwickeln-einer-komponente.html)

torud 29. Aug 2007 06:11


Benötige Hilfe beim Entwickeln einer Komponente
 
Hallo Wissende,

ich möchte/muss eine eigene Komponente entwickeln, die im Prinzip wie ein Panel aufgebaut ist, nur etwas anders aussieht und etwas mehr zu bieten hat. Dazu möchte/muss ich wohl nun erstmalig eine eigene Komponente entwickeln. Das einzige Tutorial was bisher finden konnte, war hier zu finden. http://www.dsdt.info/tutorials/kompentwickeln/?page=1 Ich finde, dass es dort eingermaßen gut erläutert wurde und suche hier keinen, der mir die komplette Arbeit abnimmt, sondern nur hin und wieder jemand, der mir zeigt, wo ich wie was zu tun habe, damit es klappen kann.

Als Add-On benötige ich folgendes.
einen Border mit abgerundeten Ecken
Hintergrund einfarbig oder als Gradient horizontal, vertikal oder diagonal
Aufname eine Bildes mit den abgerundeten Ecken als Rahmen
ODER
Aufnahme, Anzeige von formtaierten Text (es wird beides NIE gleichzeitig benötigt)

Da ich das Tutorial gelesen aber nicht alles verstanden habe und auch hier im Forum schon etwas gesucht und gelesen habe, bin ich auf den Dreh gekommen, dass ich die neue Komponente von TCustomControl ableiten müsste. Folgendes habe ich derzeit erstellt, aber leider funktioniert so gut wie nichts. Warum weiss ich leider nicht.

Delphi-Quellcode:
unit myPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TbdStyle    = (bdSolid, bdDashed, bdClear, bdDotted);
  TGdDirection = (gdHorizontal, gdVertical, gdDiagonal);

type
  TmyPanel = class(TCustomControl)

  private
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    FPaintGradient : Boolean;
    FGradientDirection : TGdDirection;
    FBorderColor:TColor;
    FBorderStyle:TbdStyle;
    FBorderWidth:integer;
    FRoundEdges:boolean;
    FCornerWidth:integer;
    procedure SetBGColor(Value: TColor);
    { Private-Deklarationen }

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }

  published
    property BgColorFrom : TColor  read FBgColorFrom  write FBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write FBgColorTo;
    property PaintGradient : boolean read FPaintGradient  write FPaintGradient;
    property GradientDirection : TGdDirection read FGradientDirection  write FGradientDirection;
    property BorderColor : TColor read FBorderColor  write FBorderColor;
    property BorderStyle : TbdStyle read FBorderStyle  write FBorderStyle;
    property BorderWidth : integer read FBorderWidth  write FBorderWidth;
    property RoundEdges : boolean read FRoundEdges  write FRoundEdges;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;
    { Published-Deklarationen }

  end;

procedure Register;
 
implementation

procedure Register;
begin
  RegisterComponents('Beispiel', [TmyPanel]);
end;

constructor TmyPanel.Create(AOwner: TComponent);
begin
  //Canvas  := TCanvas.Create;
  inherited Create(AOwner);
end;

destructor TmyPanel.Destroy;
begin
  inherited;
  Canvas.Free;
end;

procedure TmyPanel.SetBGColor(Value: TColor);
var
  Rect : TRect;
  notUsed : HWND;
begin
  Rect := GetClientRect;
  Canvas.Handle := GetDeviceContext(notUsed);
  if ColorToRGB(Value) > -1 then
  begin
    Canvas.Brush.Color := Value;
    Canvas.FillRect(Rect);
    FBGColorFrom := Value;
    FBgColorTo := Value;
  end;
  Canvas.Refresh;
end;

end.
Also wie Ihr sehen könnt, habe ich die ersten Schritte getan. Nun frage ich mich aber, wann und wo ich endlich was mit den ganzen Eigenschaften etwas anfangen kann!? Also so wie ich es sehe, müsste ich doch OnPaint irgendwo und irgendwie überschreiben und dann dort die Eigenschaften einfach nur auswerten.

Könnte mir bitte jemand mitteilen, wo und wie ich das realisieren muss? Also nur den Code, den ich benötige, damit OnPaint zur DesignTime und zur Laufzeit aufgerufen wird. Den Code werde ich dann selbste einpflegen, so weit und so gut es geht und hier wieder vorstellen....

Es könnte sein, dass in dem bisherigen Code schon ein Fehler ist, da mir jedes mal, nach dem Testen der Komponente mein Delphi abschmiert. SetBgColor kann, glaube ich raus. Das ist noch aus einem Beispiel eines anderen Users hier im Forum.

torud 29. Aug 2007 06:37

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ich habe die Komponente jetzt dahingehend geändert, dass ich SetColor entfernt habe und OnPaint eingefügt habe. Leider bringt das gar nix, da die procedure scheinbar NIE aufgerufen oder ausgelöst wird. Warum nur?

Delphi-Quellcode:
unit myPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TbdStyle    = (bdSolid, bdDashed, bdClear, bdDotted);
  TGdDirection = (gdHorizontal, gdVertical, gdDiagonal);

type
  TmyPanel = class(TCustomControl)

  private
    Canvas  : TCanvas;
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    FPaintGradient : Boolean;
    FGradientDirection : TGdDirection;
    FBorderColor:TColor;
    FBorderStyle:TbdStyle;
    FBorderWidth:integer;
    FRoundEdges:boolean;
    FCornerWidth:integer;
    { Private-Deklarationen }

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }

  published
    property BgColorFrom : TColor  read FBgColorFrom  write FBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write FBgColorTo;
    property PaintGradient : boolean read FPaintGradient  write FPaintGradient;
    property GradientDirection : TGdDirection read FGradientDirection  write FGradientDirection;
    property BorderColor : TColor read FBorderColor  write FBorderColor;
    property BorderStyle : TbdStyle read FBorderStyle  write FBorderStyle;
    property BorderWidth : integer read FBorderWidth  write FBorderWidth;
    property RoundEdges : boolean read FRoundEdges  write FRoundEdges;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;
    procedure OnPaint;
    { Published-Deklarationen }

  end;

procedure Register;
 
implementation

procedure Register;
begin
  RegisterComponents('Standard', [TmyPanel]);
end;

constructor TmyPanel.Create(AOwner: TComponent);
begin
  Canvas  := TCanvas.Create;
  inherited Create(AOwner);
end;

destructor TmyPanel.Destroy;
begin
  inherited;
  Canvas.Free;
end;

procedure TmyPanel.OnPaint;
begin
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.TextOut(1,1,'Test');
    Canvas.Refresh;
end;

end.

Ghostwalker 29. Aug 2007 07:48

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Schnipps:

Delphi-Quellcode:
   :
   Procedure Paint;override;
   :
   :
   procedure TMyPanel.Paint;override;
   begin
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.TextOut(1,1,'Test');
    Canvas.Refresh;
   end;
Also im Prinzip aus onPaint, paint machen. :)

semo 29. Aug 2007 07:58

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
als ergänzung zu Ghostwalker:

da du von tcustomcontrol ableitest musst du in dieser komponente oder deren vorfahren gucken wo und wie das onpaint event deklariert ist.

du musst dann genau die gleiche deklaration der methode in deiner komponente dann per override kennzeichnen und die methode deinen wünschen entsprechend implementieren

torud 29. Aug 2007 08:01

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Unbekannte Anweisung 'override' erhalte ich vom Debugger als Meldung.

In diese Zeile springt der Kollege:

Delphi-Quellcode:
procedure TmyPanel.Paint; override;
in published habe ich

Delphi-Quellcode:
procedure Paint; override;
Also wo liegt nun das Problem???

oki 29. Aug 2007 08:02

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Nein, Paint ist eine Virtuelle Methode, die du überschreiben kannst. Paint wird jedesmal aufgerufen, wenn dein Control neu gezeichnet wird. Somit ist das die ideale Stelle um eigene Ausgaben (zeichnen, Text) vorzunehmen.

Der Ansatz ist richtig!

Gruß oki

torud 29. Aug 2007 08:03

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Zitat:

Zitat von M. Hassmann
als ergänzung zu Ghostwalker:

da du von tcustomcontrol ableitest musst du in dieser komponente oder deren vorfahren gucken wo und wie das onpaint event deklariert ist.

Vielleicht wäre es einfach von einem anderen Vorfahren abzuleiten? Ich habe aber immer wieder gelesen, dass es günstiger und einfacher sein soll von TCustomcontrol abzuleiten. Warum auch immer!?

oki 29. Aug 2007 08:06

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
grrr* roter Kasten!

Die Procedure Paint wird nur in der Klassendeklaration mit override deklariert. Im Implementation-Teil nicht.
Delphi-Quellcode:
:
   Procedure Paint;override;
   :
   :
   procedure TMyPanel.Paint;override;
   begin
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.TextOut(1,1,'Test');
   end;
und dann kein refresh, denn es wird ja schon gezeichnet. Sonst wird es rekursiv!!!

Gruß oki

[edit] Mann schon wieder roter Kasten. ich bin heut zu langsam! [/edit]

oki 29. Aug 2007 08:06

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
TCustomControl ist ok.

torud 29. Aug 2007 08:13

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok, ich habe es nun so wie von Dir empfohlen geändert, aber jetzt ist leider kein Zeichnen auf Leinwand mehr erlaubt...Scheinbar doch nicht alles so einfach, wie erwartet. Ein Buch ist bestellt, aber trotzdem will ich nicht warten :-) hier nochmal der gesamte Code:

Delphi-Quellcode:
unit myPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TbdStyle    = (bdSolid, bdDashed, bdClear, bdDotted);
  TGdDirection = (gdHorizontal, gdVertical, gdDiagonal);

type
  TmyPanel = class(TCustomControl)

  private
    Canvas  : TCanvas;
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    FPaintGradient : Boolean;
    FGradientDirection : TGdDirection;
    FBorderColor:TColor;
    FBorderStyle:TbdStyle;
    FBorderWidth:integer;
    FRoundEdges:boolean;
    FCornerWidth:integer;
    { Private-Deklarationen }

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }

  published
    property BgColorFrom : TColor  read FBgColorFrom  write FBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write FBgColorTo;
    property PaintGradient : boolean read FPaintGradient  write FPaintGradient;
    property GradientDirection : TGdDirection read FGradientDirection  write FGradientDirection;
    property BorderColor : TColor read FBorderColor  write FBorderColor;
    property BorderStyle : TbdStyle read FBorderStyle  write FBorderStyle;
    property BorderWidth : integer read FBorderWidth  write FBorderWidth;
    property RoundEdges : boolean read FRoundEdges  write FRoundEdges;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;
    procedure Paint; override;
    { Published-Deklarationen }

  end;

procedure Register;
 
implementation

procedure Register;
begin
  RegisterComponents('Standard', [TmyPanel]);
end;

constructor TmyPanel.Create(AOwner: TComponent);
begin
  Canvas  := TCanvas.Create;
  inherited Create(AOwner);
end;

destructor TmyPanel.Destroy;
begin
  inherited;
  Canvas.Free;
end;

procedure TmyPanel.Paint;
begin
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.TextOut(1,1,'Test');
end;

end.

DeddyH 29. Aug 2007 08:17

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
TCustomControl verfügt bereits über einen Canvas, Du musst also keinen eigenen erzeugen.

oki 29. Aug 2007 08:41

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Verschiebe die Procedure Paint; override; in der Klassendeklaration in den Bereich protected. Hat aber nichts mit der Fehlermeldung zu tun. Darauf hat schon DeddyH geantwortet.

Wie gesagt, keinen neuen Canvas erzeugen; einfach in den vorhandenen Canvas zeichnen self.canvas. ...

Gruß oki

torud 29. Aug 2007 09:06

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok das funktioniert jetzt schon mal. Allerdings wird mir der Hintergrund nur dann eingefärbt, wenn ich den Text schreibe. Und dann auch nur in dem Teil, wo ich den Text schreibe. hat das einen Grund?

Ich habe den Code mal so abgeändert, da ich dachte, dass das was bringen könnte...Muss ich vielleicht den Bereich noch definieren, in dem gezeichnet werden soll?

Delphi-Quellcode:
procedure TmyPanel.Paint;
begin
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;
    //Canvas.TextOut(1,1,'Test');
end;
Ich hoffe ihr entschuldigt meine teilweise laienhaften Fragen...

torud 29. Aug 2007 11:05

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok, damit gehts jetzt. Werde mich also weiter mit Canvas und der Erstellung von Komponenten beschäftigen...

Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  Rect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;
    //Canvas.TextOut(1,1,'Test');
end;
Könnte man auch schon im Vorfeld feste Bilder mit in die Komponente einpflegen, die man dann einfach nur noch auswählen müsste?

stahli 29. Aug 2007 11:36

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hallo Torud,

Du kannst der Komponente z.B. ein TImage hinzufügen und im Contructor dieses erzeugen und positionieren. Wenn Du es unter public definierst kannst Du jederzeit darauf zugreifen:

MyPanel1.Image.Picture.LoadFromFile...

Dann hat Dein Bild ein eigenes Handle und "überlagert" quasi Dein Panel. Es fängt dann auch Mausklicks ab und die kannst z.B. auf das OnClick-Ereignis reagieren.

Die andere Variante ist, irgendwelche Bilddaten (wo immer Dui die herholst) einfach auf das Canvas Deines Panels zu kopieren. (Geht, glaube ich mit Canvas.CopyRect oder so)
Dann gehört das Bild unmittelbar zu Deinem Panel und ein Klick darauf entspricht einem Klick auf Deinem Panel. Der Zeiuchenfläche ist es ja egal, ob Du irgendwechsen Text darauft abbildest oder irgendwelche Punkte eines Bildes...

Stahli

oki 29. Aug 2007 11:42

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Text hat andere Hintergrundfarbe:
entweder du weist dem Canvas generell die Hintergrundfarbe deines Controls zu
Delphi-Quellcode:
procedure TBaseCustomControl.Paint;
begin
  inherited;
  Canvas.Font.Assign(self.Font);
end;
oder du machst den Hintergrund des Textes transparent.
Delphi-Quellcode:
    TextRect := Rect(2, 2, self.Width-2, TitleHeight-2);
    SetBkMode(Canvas.Handle, TRANSPARENT);
    DrawText(self.Canvas.Handle, PChar(FCaption), -1, TextRect,
      DT_CENTER or DT_VCENTER or DT_SINGLELINE);
Gruß oki

torud 30. Aug 2007 05:56

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hallo Wissende,

ich habe nun noch folgendes versucht und weiters noch diese Probleme:

-Die Farben sind noch nicht vorbelegt, sondern einfach alle mit clBlack...
-Wenn ich die Farben zur Designzeit im OI ändere, passiert rein gar nichts in der Komponente...Paint wird also nicht ausgelöst
-Ich habe FAlign : TAlign; hinzugefügt, damit ich auch diese Eigenschaft nutzen kann, aber wenn ich im OI diese Eigenschaft ändere reagiert wie Komponente auch nicht. Muss ich dass selbst implementieren? Wenn ja, wie kann ich dass Ereignis abfangen, dass ich da im OI von alNone auf alClient gewechselt habe?

oki 30. Aug 2007 06:09

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Moin Torud,
nichts leichter als das. Verpasse dem Property eine Setter-Methode und lasse beim Setzen das Control neu zeichnen.
Delphi-Quellcode:
type
  TmyPanel = class(TCustomControl)
  private
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    procedure SetBgColorFrom(Value : TColor);
    procedure SetBgColorTo(Value : TColor);
  published
    property BgColorFrom : TColor  read FBgColorFrom  write SetBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write SetBgColorTo;
  end;

procedure TmyPanel.SetBgColorFrom(Value : TColor); // Settermethode
begin
  If Value = FBgColorFrom then Exit; // wenn gleiche Farbe nichts tun
  FBgColorFrom := Value;             // Farbe abspeichern
  Invalidate;                        // Control neu zeichnen
end;

procedure TmyPanel.SetBgColorTo(Value : TColor);
begin
  If Value = FBgColorTo then Exit;
  FBgColorFrom := Value;
  Invalidate;
end;
Praktisch heisst das jetzt, immer wenn du dein Property BgColorFrom veränderst, wird nicht direkt in FBgColorFrom geschrieben, sondern die Settermethode SetBgColorFrom aufgerufen und der neue Farbwert übergeben. Das läuft übrigens automatisch.
Sind die Farben unterschiedlich, so wird FBgColorFrom gesetzt und mit Invalidate das Control veranlasst sich neu zu zeichnen.

Gruß oki

torud 30. Aug 2007 06:27

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Geiler Effekt. :-D

Er zeigt mir jetzt immer die vorletzte Farbe an. Ich schaue nochmal drüber. Ich wollte da eh noch was mit Const vorbelegen, wenns geht. Ich suche mal weiter...Aber ansonsten hast du mit Deiner Antwort schon arg geholfen. Ich werde den Tipp direkt versuchen wür das Aligner-Problem zu benutzen...

oki 30. Aug 2007 06:42

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi,

mit dem Align bin ich mir jetzt nicht sicher wie weit TCustomControl das umsetzt. Wenn du die Eigenschaft öffentlich machen möchtest reicht folgendes:
Delphi-Quellcode:
published
  property Align;
end;
Das mit der vorletzten Farbe kann ich nicht nachvollziehen.
Ach ja, Farbe vorbelegen: im Constructor
Delphi-Quellcode:
  FBgColorFrom := clblue;
Gruß oki

torud 30. Aug 2007 07:05

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Jo das mit dem Align funktioniert super. Ich hatte da den Fehler drin, dass ich das selbst noch als eigene Eigenschaft deklariert hatte, was wohl gar nicht nötig ist.

Habe sogar noch nen Fehler in deinem Code gefunden:

Delphi-Quellcode:
procedure TmyPanel.SetBgColorTo(Value : TColor);
begin
  If Value = FBgColorTo then Exit;
  //FBgColorFrom := Value; //empfohlem by OKI
  FBgColorTo := Value;
  Invalidate;
end;
Habs aber hinbekommen. So lernt man wenigstens was dabei...

oki 30. Aug 2007 07:21

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Richtig,

üblicherweise werden die Eigenschaften protected oder public deklariert und erst für die entsprechende abgeleitete Klasse die als Komponente integriert wird unter published veröffentlicht. Mit der vorhergehenden Deklaration wird somit nur die Sichtbarkeit verändert, aber nicht die Eigenschaft. deklariert man diese neu, so wird die vorherige Eigenschaft überschrieben.

Gruß oki

torud 30. Aug 2007 07:52

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Also jetzt gehts schon mal ganz gut. Sogar mit dem gradient klppts. Was leider noch nicht funktioniert ist der Border.

Kein Ahnung warum, aber er wird NOCHT nicht gezeichnet.

Ich hänge mal nur die Paint an, da dort ja der Border abgehandelt wird.

Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  Rect,TextRect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, Rect, goVertical);
end;
Ich habe schon versucht den Pen nach dem Gradient zu übergeben, aber auch das brachte nichts.
Hm, und wenn das klappt, würde mich noch interessieren, wie ich eventuell die Ecken abgerundet zeichnen lassen kann...

DeddyH 30. Aug 2007 07:56

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ehrlich gesagt sehe ich nicht, wo hier eine Border gezeichnet wird :gruebel:

torud 30. Aug 2007 08:30

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Zitat:

Zitat von DeddyH
Ehrlich gesagt sehe ich nicht, wo hier eine Border gezeichnet wird :gruebel:

Hm, ich hatte mir die TShape angesehen und ging davon aus, dass dies hier dafür zuständig sei nen Boder zu zeichnen:

Delphi-Quellcode:
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;
Zumindest klappt das bei einem Shape so. Definiert ist auch alles...

DeddyH 30. Aug 2007 08:45

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Mal zum Testen:
Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  Rect,TextRect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, Rect, goVertical);
    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Right,Rect.Bottom);
end;

torud 30. Aug 2007 10:24

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok, das geht. Ich habe es soweit angepasst, dass ich die Linien vorerst von Links Oben nach unten und nach rechts gezogen habe. Leider wird dabei bisher die Linienstärke noch nicht berücksichtigt. Ich habe mal bei Canvas nachgesehen, aber leider nichts finden können, wie ich die Stiftdicke einstellen kann.

Der Code sieht derzeit nun so aus:

Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  Rect,TextRect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;

    Canvas.Pen.Mode   := pmCopy;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;
   
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, Rect, goVertical);

    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Left,Rect.Bottom);
    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Right,Rect.Top);
end;

DeddyH 30. Aug 2007 10:28

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Zitat:

Canvas.Pen.Width := BorderWidth;
Hier setzt Du doch die Stiftbreite.

torud 30. Aug 2007 20:21

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Danke für die Antwort.

Damit ich hier nicht nur als NEHMER dastehe, poste ich mal den bisherigen Code für diejenigen, die selbst solch ein Panel wollen, aber es nicht programmieren können. Da kann man sicher auch diverses verbessern, aber dafür, dass es meine erste selbst geschriebene Komponente ist, bin ich ziemlich stolz.

2 Dinge, die ich eigentlich noch einbinden will, brennen mir noch auf den Nägeln.

1. Die Beschriftung für das Panel soll in einem TStrings stehen, damit ich mehr als nur eine Caption oder Text aufnehmen und anzeigen kann.

2. Ich will eigentlich abgerundete Eckten. Hat jemand einen Tipp hierfür parat?

Delphi-Quellcode:
unit myPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TbdStyle    = (bdNone, bdSolid, bdDashed, bdClear, bdDotted);
  TGdDirection = (gdHorizontal, gdVertical, gdDiagonal);
  TGradientOrientation = (goVertical, goHorizontal);

type
  TPixelRec = packed record
    case Boolean of
      true: (Color: TColor);
      false: (r, g, b, Reserved: Byte);
  end;

type
  TmyPanel = class(TCustomControl)

  private
    FAlign : TAlign;
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    FPaintGradient : Boolean;
    FGradientDirection : TGdDirection;
    FBorderColor:TColor;
    FBorderStyle:TPenStyle;
    FBorderWidth:integer;
    FRoundEdges:boolean;
    FCornerWidth:integer;
    procedure SetBgColorFrom(Value : TColor);
    procedure SetBgColorTo(Value : TColor);
    procedure SetGradientStatus(Value: Boolean);
    procedure SetBorderWidth(Value: integer);
    procedure SetBorderColor(Value : TColor);

    { Private-Deklarationen }
  protected
  { Protected-Deklarationen }
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }

  published
    //property Align : TAlign  read FAlign  write FAlign;
    property Align;
    property BgColorFrom : TColor  read FBgColorFrom  write SetBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write SetBgColorTo;
    property PaintGradient : boolean read FPaintGradient  write SetGradientStatus;
    property GradientDirection : TGdDirection read FGradientDirection  write FGradientDirection;
    property BorderColor : TColor read FBorderColor  write SetBorderColor;
    property BorderStyle : TPenStyle read FBorderStyle  write FBorderStyle;
    property BorderWidth : integer read FBorderWidth  write SetBorderWidth;
    property RoundEdges : boolean read FRoundEdges  write FRoundEdges;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;
    { Published-Deklarationen }

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TmyPanel]);
end;

constructor TmyPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Align      := alNone;
  BgColorFrom := clWhite;
  BgColorTo  := clSilver;
  BorderColor := clGray;
  BorderStyle := psSolid;
  BorderWidth := 2;
end;

destructor TmyPanel.Destroy;
begin
  inherited;
end;

procedure TmyPanel.SetGradientStatus(Value:Boolean);
begin
  If Value = FPaintGradient then Exit; // wenn gleicher Status nichts tun
  FPaintGradient := Value;             // Status abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure TmyPanel.SetBorderWidth(Value:integer);
begin
  If Value = FBorderWidth then Exit; // wenn gleicher Status nichts tun
  FBorderWidth := Value;             // Status abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure TmyPanel.SetBorderColor(Value : TColor); // Settermethode
begin
  If Value = FBorderColor then Exit; // wenn gleiche Farbe nichts tun
  FBorderColor := Value;             // Farbe abspeichern
  Invalidate;                        // Control neu zeichnen
end;

procedure TmyPanel.SetBgColorFrom(Value : TColor); // Settermethode
begin
  If Value = FBgColorFrom then Exit; // wenn gleiche Farbe nichts tun
  FBgColorFrom := Value;             // Farbe abspeichern
  Invalidate;                        // Control neu zeichnen
end;

procedure TmyPanel.SetBgColorTo(Value : TColor);
begin
  If Value = FBgColorTo then Exit;
  FBgColorTo := Value;
  Invalidate;
end;

procedure DrawGradient(const Canvas: TCanvas; Color1, Color2: TColor;
                       ARect: TRect; GradientOrientation: TGradientOrientation);
var
  c1, c2, c: TPixelRec; //for easy access to RGB values as well as TColor value
  x, y: Integer;        //current pixel position to be set
  OldPenWidth: Integer; //Save old settings to restore them properly
  OldPenStyle: TPenStyle;//see above
begin
  c1.Color := ColorToRGB(Color1); //convert system colors to RGB values
  c2.Color := ColorToRGB(Color2); //if neccessary
  OldPenWidth := Canvas.Pen.Width; //get old settings
  OldPenStyle := Canvas.Pen.Style;
  Canvas.Pen.Width:=1;            //ensure correct pen settings
  Canvas.Pen.Style:=psInsideFrame;

  case GradientOrientation of
    goVertical:
    begin
      for y := 0 to ARect.Bottom - ARect.Top do
      begin
        c.r := Round(c1.r + (c2.r - c1.r) * y / (ARect.Bottom - ARect.Top));
        c.g := Round(c1.g + (c2.g - c1.g) * y / (ARect.Bottom - ARect.Top));
        c.b := Round(c1.b + (c2.b - c1.b) * y / (ARect.Bottom - ARect.Top));
        Canvas.Brush.Color := c.Color;
        Canvas.FillRect(Classes.Rect(ARect.Left, ARect.Top + y,
                                     ARect.Right, ARect.Top + y + 1));
      end;
    end;
    goHorizontal:
    begin
      for x := 0 to ARect.Right - ARect.Left do
      begin
        c.r := Round(c1.r + (c2.r - c1.r) * x / (ARect.Right - ARect.Left));
        c.g := Round(c1.g + (c2.g - c1.g) * x / (ARect.Right - ARect.Left));
        c.b := Round(c1.b + (c2.b - c1.b) * x / (ARect.Right - ARect.Left));
        Canvas.Brush.Color := c.Color;
        Canvas.FillRect(Rect(ARect.Left + x, ARect.Top,
                             ARect.Left + x + 1, ARect.Bottom));
      end;
    end;
  end;
  Canvas.Pen.Width := OldPenWidth; //restore old settings
  Canvas.Pen.Style := OldPenStyle;
end;

procedure TmyPanel.Paint;
var
  Rect,TextRect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;

    Canvas.Pen.Mode   := pmCopy;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;
   
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, Rect, goVertical);

    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Left,Rect.Bottom);
    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Right,Rect.Top);

    Canvas.MoveTo(self.Width,0);
    Canvas.LineTo(Rect.Right,Rect.Bottom);
    Canvas.MoveTo(0,self.Height); //links unten
    Canvas.LineTo(Rect.Right,Rect.Bottom);
    //Canvas.MoveTo(Rect.Right,0);
    //Canvas.LineTo(Rect.Right,Rect.Bottom);


    //TextRect := Rect(2, 2, self.Width-2, TitleHeight-2);
    //SetBkMode(Canvas.Handle, TRANSPARENT);
    //DrawText(self.Canvas.Handle, PChar(FCaption), -1, TextRect,
    //         DT_CENTER or DT_VCENTER or DT_SINGLELINE);
    //Canvas.TextOut(1,1,'Test');
end;

end.

oki 30. Aug 2007 20:31

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi torud,

sieht doch schon gut aus.
Warum willst du unbedingt TStrings für den Text verwenden. Ein String tut es doch auch. Mit DrawText kannst du auch multiline realisieren. Schau einfach mal in der Hilfe nach, da sind alle Flags beschrieben.

Leider hab ich im Moment auch keine einfache Lösung. Nur ne komplizierte und die hab ich auch noch nicht ausprobiert.

Gruß oki

torud 30. Aug 2007 20:46

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok, ich werde erstmal Text als String nehmen, aber ich habe mit Deinem Code noch etwas Probleme, da der Debugger schimpft und mir mitteilt, dass ein Operator oder Semikolon fehlt. In der Codezeile davor ist aber definitiv ein Semikolon. Woran kann denn nun dieser Fehler liegen?

Delphi-Quellcode:
    TextRect := Rect(2, 2, self.Width-2, self.Height-2);

oki 30. Aug 2007 20:58

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Da ist nichts schlechtes zu erkennen. Mault der Compiler in der Zeile mit der TextRect-Zuweisung? Zeig mal kurz den ganzen Abschnitt und die original Fehlermeldung.

Gruß oki

torud 30. Aug 2007 21:04

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Er springt mit dem Cursor an zwischen diese Zeichen: (2 aus der Zeile

Delphi-Quellcode:
TextRect := Rect(2, 2, self.Width-2, self.Height-2);
gesamte procedure:
Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  Rect,TextRect : TRect;
begin
  Rect := GetClientRect;
    Canvas.FillRect(Rect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;

    Canvas.Pen.Mode   := pmCopy;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;

    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, Rect, goVertical);

    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Left,Rect.Bottom);
    Canvas.MoveTo(0,0);
    Canvas.LineTo(Rect.Right,Rect.Top);

    Canvas.MoveTo(self.Width,0);
    Canvas.LineTo(Rect.Right,Rect.Bottom);
    Canvas.MoveTo(0,self.Height); //links unten
    Canvas.LineTo(Rect.Right,Rect.Bottom);

    TextRect := Rect(2, 2, self.Width-2, self.Height-2);
    SetBkMode(Canvas.Handle, TRANSPARENT);
    DrawText(self.Canvas.Handle, PChar(FText), -1, Rect,
             DT_CENTER or DT_VCENTER or DT_SINGLELINE);
end;
Originale Fehlermeldung:
[Fehler] myPanel.pas(207): Operator oder Semikolon fehlt
[Hinweis] myPanel.pas(24): Das private-Symbol 'FAlign' wurde deklariert, aber nie verwendet
[Fataler Fehler] test_mypanel.dpk(32): Verwendete Unit '..\..\Lib\myPanel.pas' kann nicht compiliert werden

torud 30. Aug 2007 21:08

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Keine Ahnung ob es denn noch der Fall ist, wenn DrawText ginge, aber mit der TextOut gibts keinen Zeilenumbruch...

Hawkeye219 30. Aug 2007 21:23

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hallo Tom,

du definierst eine lokale Variable Rect und möchtest gleichzeitig die Funktion Rect() verwenden. Kein Wunder, daß der Compiler da etwas verwirrt ist. Entweder benennst du die lokale Variable um oder du versuchst es so:

Delphi-Quellcode:
TextRect := Types.Rect(2, 2, self.Width-2, self.Height-2);
Voraussetzung ist dann allerdings die Aufnahme der Unit Types in die USES-Anweisung.

Gruß Hawkeye

torud 30. Aug 2007 21:25

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Sorry, ich habe den Fehler auch gerade bemerkt und aus der lokalen Variable Rect => myRect gemacht. Nun funzt es.

Offen bleibt, wie man den Text umbrechen kann...!?

Sorry, aber Dein Beitrag war ca. 2 Minuten früher drin...

oki 30. Aug 2007 21:37

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi, dann klappts auch mit DrawText, oder mit dem Nachbarn :lol:

Für automatischen Zeilenumbruch musst du DT_SINGLELINE gegen DT_WORDBREAK tauschen.

Gruß oki

torud 31. Aug 2007 04:50

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hello Again,

darf ich Euch nochmals um Rat bitten?

Ich würde nun gern die Ausrichtung des Textes als Eigenschaft verpacken und habe nun folgendes gemacht:

Delphi-Quellcode:
  private
    .....
    procedure SetText(Content : String);
    procedure SetTextAlign(Alignment : Cardinal);
  published
    .....
    property Text : String read FText  write SetText;
    property TextAlign : Cardinal read FTextAlign  write SetTextAlign;

procedure TmyPanel.SetTextAlign(Alignment : Cardinal); // Settermethode
begin
  If Alignment = FTextAlign then Exit; // wenn gleicher Inhalt nichts tun
  FTextAlign := Alignment;             // Inhalt abspeichern
  Invalidate;                          // Control neu zeichnen
end;

    DrawText(self.Canvas.Handle, PChar(FText), -1, TextRect,
             DT_VCENTER or DT_VCENTER or DT_WORDBREAK);
Meine Frage lautet nun, wie kann ich das Ganze sinnvoll kombinieren? Bzw. was soll ich als Eigenschaftsvorgabewert für das Alignment benutzen? Kann ich die Cardinals, die für DrawText vorgegeben sind einfach durchreichen? Wenn ja wie? Oder muss ich mir eigene Eigenschaften schaffen, die ich dann übersetze?

Also mit:
Delphi-Quellcode:
  TalText    = (alLeft, alTop, alBottom, alRight, alTopLeft);
Und dann müsste ich wohl aus alLeft DT_Left machen?! Aber in der Routine werden Möglichkeiten angeboten. Also wie könnte ich das jetzt sinvoll gestalten, denn ich will natürlich mehrere Möglichkeiten der Textausrichtung haben...Das versteht ihr doch...Oder... :-D

oki 31. Aug 2007 06:29

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Moin torud,

nichts leichter als das.
Du mußt dir nun nur überlegen, wie du diese setzt. Das kannst du in der üblichen Art und Weise tun. Bsp.:
-Links-/Rechtsbündig und zentriert über Radiobutton,
-vertikal zentriert und Zeilenümbruch als Checkboxen.

Dabei kannst du für deine published-Deklaration ruhig bekannte Eigenschaften einführen:
Delphi-Quellcode:
  protected
    property TextPropertys : UINT read FTextPropertys write SetTextPropertys;
  published
    property TextAlignment : TAlignment read FTextAlignment write SetTextAlignment;
    property TextVCenter : UINT read FTextVCenter write SetTextVCenter;
Somit ist das auch im OI anwählbar.

Bei Änderungen änderst du dementsprechend deine Eigenschaft FTextPropertys in den Setter-Methoden und läßt das Panel neu zeichnen.

Delphi-Quellcode:
  DrawText(self.Canvas.Handle, PChar(FText), -1, TextRect, FTextPropertys);
Gruß oki

P.S. hab jetzt geschlagene 20 min für das bischen gebraucht. :| Ist echt noch zu früh

torud 31. Aug 2007 06:40

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ok, da Du hier Mentortauglich zu sein scheinst, habe ich hier noch was kniffliges. Ich finde den Fehler einfach nicht. ich habe also noch eine Möglichkeit eingabut, um auch ein Bild anzeigen lassen zu können. Das Ganze ist mit dem Rahmen noch nicht abgestimmt und auch den Gradienten muss man nicht zeichnen, wenn man ein Bild drauf zeichnet, aber das Problem ist, dass mir mein Delphi direkt abschmiert, wenn ich ein Bild ausgesucht und im OI hinzufügt habe und er versucht die TGraphic mittels StretchDraw zu zeichnen. Ich poste mal wieder den gesamten Code. Deine Infos aus Deinem letzten Post sind noch nicht mit eingeflossen...Hier und da habe ich schon einiges gerade gezogen und ich bin begeistert, auch wenn es noch nicht ganz das ist, was ich will....Aber der Weg stimmt...

Delphi-Quellcode:
unit myPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TbdStyle    = (bdNone, bdSolid, bdDashed, bdClear, bdDotted);
  TGradientOrientation = (goVertical, goHorizontal);

type
  TPixelRec = packed record
    case Boolean of
      true: (Color: TColor);
      false: (r, g, b, Reserved: Byte);
  end;

type
  TmyPanel = class(TCustomControl)

  private
    FBgColorFrom : TColor;
    FBgColorTo : TColor;
    FPaintGradient : Boolean;
    FGradientDirection : TGradientOrientation;
    FBorderColor:TColor;
    FBorderStyle:TPenStyle;
    FBorderWidth:integer;
    FRoundEdges:boolean;
    FCornerWidth:integer;
    FText:String;
    FTextAlign:Cardinal;
    FPicture:TGraphic;
    procedure SetBgColorFrom(Value : TColor);
    procedure SetBgColorTo(Value : TColor);
    procedure SetGradientStatus(Value: Boolean);
    procedure SetBorderWidth(Value: integer);
    procedure SetBorderColor(Value : TColor);
    procedure SetPicture(Pic : TGraphic);
    procedure SetText(Content : String);
    procedure SetTextAlign(Alignment : Cardinal);
    procedure SetGradientDirection(Direction:TGradientOrientation);

    { Private-Deklarationen }
  protected
  { Protected-Deklarationen }
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Public-Deklarationen }

  published
    //property Align : TAlign  read FAlign  write FAlign;
    property Align;
    property BgColorFrom : TColor  read FBgColorFrom  write SetBgColorFrom;
    property BgColorTo : TColor  read FBgColorTo  write SetBgColorTo;
    property PaintGradient : boolean read FPaintGradient  write SetGradientStatus;
    property GradientDirection : TGradientOrientation read FGradientDirection  write SetGradientDirection;
    property BorderColor : TColor read FBorderColor  write SetBorderColor;
    property BorderStyle : TPenStyle read FBorderStyle  write FBorderStyle;
    property BorderWidth : integer read FBorderWidth  write SetBorderWidth;
    property RoundEdges : boolean read FRoundEdges  write FRoundEdges;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;
    property Picture : TGraphic read FPicture  write SetPicture;
    property Text : String read FText  write SetText;
    property TextAlign : Cardinal read FTextAlign  write SetTextAlign;
    { Published-Deklarationen }

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TmyPanel]);
end;

constructor TmyPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Align      := alNone;
  BgColorFrom := clWhite;
  BgColorTo  := clSilver;
  BorderColor := clGray;
  BorderStyle := psSolid;
  BorderWidth := 2;
end;

destructor TmyPanel.Destroy;
begin
  inherited;
end;

procedure TmyPanel.SetPicture(Pic : TGraphic);
begin
  If Pic = FPicture then Exit; // wenn gleicher Status nichts tun
  FPicture := Pic;             // Status abspeichern
  Invalidate;                  // Control neu zeichnen
end;

procedure TmyPanel.SetGradientStatus(Value:Boolean);
begin
  If Value = FPaintGradient then Exit; // wenn gleicher Status nichts tun
  FPaintGradient := Value;             // Status abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure TmyPanel.SetGradientDirection(Direction:TGradientOrientation);
begin
  If Direction = FGradientDirection then Exit; // wenn gleicher Status nichts tun
  FGradientDirection := Direction;             // Status abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure TmyPanel.SetBorderWidth(Value:integer);
begin
  If Value = FBorderWidth then Exit; // wenn gleicher Status nichts tun
  FBorderWidth := Value;             // Status abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure TmyPanel.SetBorderColor(Value : TColor); // Settermethode
begin
  If Value = FBorderColor then Exit; // wenn gleiche Farbe nichts tun
  FBorderColor := Value;             // Farbe abspeichern
  Invalidate;                        // Control neu zeichnen
end;

procedure TmyPanel.SetBgColorFrom(Value : TColor); // Settermethode
begin
  If Value = FBgColorFrom then Exit; // wenn gleiche Farbe nichts tun
  FBgColorFrom := Value;             // Farbe abspeichern
  Invalidate;                        // Control neu zeichnen
end;

procedure TmyPanel.SetBgColorTo(Value : TColor);
begin
  If Value = FBgColorTo then Exit;
  FBgColorTo := Value;
  Invalidate;
end;

procedure TmyPanel.SetText(Content : String); // Settermethode
begin
  If Content = FText then Exit; // wenn gleicher Inhalt nichts tun
  FText := Content;             // Inhalt abspeichern
  Invalidate;                   // Control neu zeichnen
end;

procedure TmyPanel.SetTextAlign(Alignment : Cardinal); // Settermethode
begin
  If Alignment = FTextAlign then Exit; // wenn gleicher Inhalt nichts tun
  FTextAlign := Alignment;             // Inhalt abspeichern
  Invalidate;                          // Control neu zeichnen
end;

procedure DrawGradient(const Canvas: TCanvas; Color1, Color2: TColor;
                       ARect: TRect; GradientOrientation: TGradientOrientation);
var
  c1, c2, c: TPixelRec; //for easy access to RGB values as well as TColor value
  x, y: Integer;        //current pixel position to be set
  OldPenWidth: Integer; //Save old settings to restore them properly
  OldPenStyle: TPenStyle;//see above
begin
  c1.Color := ColorToRGB(Color1); //convert system colors to RGB values
  c2.Color := ColorToRGB(Color2); //if neccessary
  OldPenWidth := Canvas.Pen.Width; //get old settings
  OldPenStyle := Canvas.Pen.Style;
  Canvas.Pen.Width:=1;            //ensure correct pen settings
  Canvas.Pen.Style:=psInsideFrame;

  case GradientOrientation of
    goVertical:
    begin
      for y := 0 to ARect.Bottom - ARect.Top do
      begin
        c.r := Round(c1.r + (c2.r - c1.r) * y / (ARect.Bottom - ARect.Top));
        c.g := Round(c1.g + (c2.g - c1.g) * y / (ARect.Bottom - ARect.Top));
        c.b := Round(c1.b + (c2.b - c1.b) * y / (ARect.Bottom - ARect.Top));
        Canvas.Brush.Color := c.Color;
        Canvas.FillRect(Classes.Rect(ARect.Left, ARect.Top + y,
                                     ARect.Right, ARect.Top + y + 1));
      end;
    end;
    goHorizontal:
    begin
      for x := 0 to ARect.Right - ARect.Left do
      begin
        c.r := Round(c1.r + (c2.r - c1.r) * x / (ARect.Right - ARect.Left));
        c.g := Round(c1.g + (c2.g - c1.g) * x / (ARect.Right - ARect.Left));
        c.b := Round(c1.b + (c2.b - c1.b) * x / (ARect.Right - ARect.Left));
        Canvas.Brush.Color := c.Color;
        Canvas.FillRect(Rect(ARect.Left + x, ARect.Top,
                             ARect.Left + x + 1, ARect.Bottom));
      end;
    end;
  end;
  Canvas.Pen.Width := OldPenWidth; //restore old settings
  Canvas.Pen.Style := OldPenStyle;
end;

procedure TmyPanel.Paint;
var
  myRect,TextRect : TRect;
begin
  myRect := GetClientRect;
    Canvas.FillRect(myRect);
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := FBgColorFrom;

    Canvas.Pen.Mode   := pmCopy;
    Canvas.Pen.Style  := BorderStyle;
    Canvas.Pen.Width  := BorderWidth;
    Canvas.Pen.Color  := BorderColor;

    //zeichnen des gradients
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, myRect, GradientDirection);

    //zeichnen des rahmens
    Canvas.MoveTo(0,0);
    Canvas.LineTo(myRect.Left,myRect.Bottom);
    Canvas.MoveTo(0,0);
    Canvas.LineTo(myRect.Right,myRect.Top);
    Canvas.MoveTo(self.Width,0);
    Canvas.LineTo(myRect.Right,myRect.Bottom);
    Canvas.MoveTo(0,self.Height); //links unten
    Canvas.LineTo(myRect.Right,myRect.Bottom);

    //zeichnen des bildes, wenn vorhanden
    if Picture <> nil then
      Canvas.StretchDraw(myRect,Picture);

    //schreiben des textes
    TextRect := Rect(BorderWidth, BorderWidth, self.Width-BorderWidth, self.Height-BorderWidth);
    SetBkMode(Canvas.Handle, TRANSPARENT);
    DrawText(self.Canvas.Handle, PChar(FText), -1, TextRect,
             DT_VCENTER or DT_VCENTER or DT_WORDBREAK);
end;

end.
Der Fehler MUSS eigentlich hier liegen:

Delphi-Quellcode:
    if Picture <> nil then
      Canvas.StretchDraw(myRect,Picture);
da ich den Code soeben testhalber mal deaktiviert habe und da wird ja das Bild nicht gezeichnet. Da war alles ok. Also was mache ich da noch falsch? Denn in meinem Infotool => EasyDelphiHelper stand geschrieben, dass man mit StretchDraw eine TGraphic zeichnen lassen kann und damit fast alles realisieren kann. Also wenigstens Bmp und Jpg. Das würde auch erstmal reichen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:53 Uhr.
Seite 1 von 4  1 23     Letzte »    

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