AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Benötige Hilfe beim Entwickeln einer Komponente
Thema durchsuchen
Ansicht
Themen-Optionen

Benötige Hilfe beim Entwickeln einer Komponente

Ein Thema von torud · begonnen am 29. Aug 2007 · letzter Beitrag vom 17. Jul 2013
Antwort Antwort
Seite 6 von 13   « Erste     456 78     Letzte »    
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#1

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 20:19
Hier nun nochmals mein vorläufiges Feedback zur erstellten Komponente.

Ich kann mit der komponente fast das tun, was ich wollte. Ein Bild laden, optional einen Gradienten drauf zeichen oder nur eine Hintergrundfarbe anzeigen lassen, einen Text draufschreiben und einen Rahmen mit eigener Farbe darstellen.

Nun zu den Punkten, die mich noch umtreiben.

1. Wenn ich den Rahmen mit einem 1 Pixel Stärke angeben, sind die Linien links und oben ok. Rechts und unten ist keine sichtbar. Gebe ich eine Rahmenstärke von 9 ein, habe ich links und oben 5 und rechts und unten nur 4. hier stimmt was nicht...Nur was?

2. Eigentlich wollte ich auch RoundedCorners haben, aber da fehlt mir leider der Mathematische Hintergrund (schon 20 Jahre aus der Schule) und die Programmierkenntnisse lassen auch zu wünschen übrig, denn ich lerne das alles nur aus diesem Forum und diversen Büchern nebenbei. Immerhin habe ich schon mal eine eigene Kompoente erstellt. Hoch die tassen! Aber die gerundeten Ecken sind einfach zu viel für mich und konnte auch im www nichts dazu finden.

3. Ich habe zwar etwas mit den Codes und den Hinweisen gespielt, aber ich habe es leider nicht hinbekomme, den Text so ausrichten zu lassen, dass ich es angeben kann. Vielleicht gibts da noch den ein oder anderen WINK?

Vielleicht hat der ein oder andere von Euch wieder einen hilfreichen Tipp für mich oder Codeschnipsel oder nen Link?

Hier nochmal der aktuelle Code der Kompo:

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:TAlignment;
    FPicture:TPicture;
    FTextWordwrap:Boolean;
    FTextVCenter:Boolean;
    procedure SetBgColorFrom(Value : TColor);
    procedure SetBgColorTo(Value : TColor);
    procedure SetGradientStatus(Value: Boolean);
    procedure SetBorderWidth(Value: integer);
    procedure SetBorderColor(Value : TColor);
    //procedure SetPicture(Pic : TPicture);
    procedure PictureChanged (Sender: TObject);
    procedure SetPicture (aValue: TPicture);
    procedure SetText(Content : String);
    procedure SetTextAlign(Alignment : TAlignment);
    procedure SetGradientDirection(Direction:TGradientOrientation);
    procedure SetTextWordwrap(WrapIt:Boolean);
    procedure SetTextVCenter(VCenter:Boolean);

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

  published
    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 : TAlignment read FTextAlign write SetTextAlign;
    property TextWordwrap : Boolean read FTextWordwrap write SetTextWordwrap;
    property TextVCenter : Boolean read FTextVCenter write SetTextVCenter;
    property Picture: TPicture read FPicture write SetPicture;
    { Published-Deklarationen }

  end;

procedure Register;

implementation

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

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

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

procedure TmyPanel.PictureChanged (Sender: TObject);
begin
  Invalidate;
end;

procedure TmyPanel.SetPicture (aValue: TPicture);
begin
  FPicture.Assign (aValue); // KEINE Zuweisung, sondern Assign!
end;

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

procedure TmyPanel.SetTextVCenter(VCenter:Boolean);
begin
  If VCenter = FTextVCenter then Exit; // wenn gleicher Status nichts tun
  FTextVCenter := VCenter; // Status abspeichern
  Invalidate; // Control neu zeichnen
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 : TAlignment); // 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 bildes, wenn vorhanden
    if Picture <> nil then
      Canvas.StretchDraw(myRect,Picture.Graphic);

    //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);

    //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.
Danke
Tom
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#2

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 20:38
Einen Punkt meiner Wunsch und Problemliste kann ich nun doch schon FAST streichen. Und zwar gehts um den Border. Ich vermute mal, dass der Stift beim zeichnen zentriert aufgesetzt wird und habe aus dem Grund mal die X-Position um die Hälfte der BoderWidth verschoben und siehe da, wenn ich eine BorderWidth > 1 habe funzt das schon mal. Der Code, der nicht wirklich schön ist, sieht so aus - zumindest bei mir. Werde die Division vorher einmal erledigen und nicht jedesmal neu rechnen lassen und einen Klausel für die BorderWidth 1 einführen.

Delphi-Quellcode:
    //zeichnen des rahmens
    Canvas.MoveTo(0 + (BorderWidth div 2),0); //links oben
    Canvas.LineTo(myRect.Left + (BorderWidth div 2),myRect.Bottom);

    Canvas.MoveTo(0,0 + (BorderWidth div 2));
    Canvas.LineTo(myRect.Right,myRect.Top + (BorderWidth div 2));

    Canvas.MoveTo(self.Width-(BorderWidth div 2),0); //rechts unten
    Canvas.LineTo(myRect.Right-(BorderWidth div 2),myRect.Bottom);

    Canvas.MoveTo(0,self.Height-(BorderWidth div 2)); //links unten
    Canvas.LineTo(myRect.Right,myRect.Bottom-(BorderWidth div 2));
Danke
Tom
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 20:56
Hi torud,

ich bin schon ziemlich k.o. für heute, aber zum Thema Textausrichtung kann ich noch mal was beisteuern. Du übergibst in DrawText als letzten Parameter die Ausrichtungsflags.
Somit definierst du dir eine Variable vom Typ UINT und setzt diese mit MyTextForm := ersteFlag or zweitesFlag or ...
Das mit übergeben, und das wars schon.

Gruß oki
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 20:58
Nachtrag,

Rahmen mit Canvas.FrameRect

Gruß
42
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#5

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 21:39
Moin Moin Oki,

ich bin auch schon ziemlich groggy, aber hier mal mein aktueller Status.

Das mit dem Rahmen passt nun, auch wenn ich NOCH nicht mit FrameRect gemacht habe. Kommt noch.

Dann habe ich mich mal an die Ausrichtung gewagt und siehe da, es gibt einen teilweisen Erfolg.

Folgenden Code habe ich benutzt, um die Ausrichtung zur vollziehen. Dabei hatte ich dass Problem, dass ich eigentlich die bekannte Eigenschaft Layout benutzen wollte, wie sie beim TLabel zum Einsatz kommt, aber dazu war leider nichts in der Hilfe zu finden.

Delphi-Quellcode:
var
  ...
  myFirstAlignment,mySecondAlignment : Cardinal;

    //init
    myFirstAlignment := DT_CENTER;
    mySecondAlignment:= DT_VCENTER;
    
    case TextAlign of
      taCenter : myFirstAlignment := DT_CENTER;
      taLeftJustify : myFirstAlignment := DT_LEFT;
      taRightJustify : myFirstAlignment := DT_RIGHT;
    end; //bis hierher ist alles super

    case Layout of
      tlTop : mySecondAlignment := DT_TOP;
      tlCenter : mySecondAlignment := DT_VCENTER;
      tlBottom : mySecondAlignment := DT_BOTTOM;
    end; //das hier funzt noch nicht

    DrawText(self.Canvas.Handle, PChar(FText), -1, TextRect,
             myFirstAlignment or mySecondAlignment or DT_WORDBREAK);
Folgenden Code benutze ich für das Layout:
Delphi-Quellcode:
type
  TLayout = (tlTop, tlCenter, tlBottom);

private
    FLayout:TLayout;
    procedure SetTextLayout(Layout : TLayout);
published
    property Layout : TLayout read FLayout write SetTextLayout;

procedure TmyPanel.SetTextLayout(Layout:TLayout);
begin
  If Layout = FLayout then Exit; // wenn gleicher Status nichts tun
  FLayout := Layout; // Status abspeichern
  Invalidate; // Control neu zeichnen
end;
Findest Du da einen Fehler? Am liebsten wäre mir ja, wenn ich die originale Eigenschaft LAYOUT nutzen könnte, wie beim Alignment...
Danke
Tom
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 5. Sep 2007, 22:06
Hi,

warum so kompliziert.
Delphi-Quellcode:
    case TextAlign of
      taCenter : myAlignment := DT_CENTER;
      taLeftJustify : myAlignment := DT_LEFT;
      taRightJustify : myAlignment := DT_RIGHT;
    end;

    case Layout of
      tlTop : myAlignment := myAlignment or DT_TOP;
      tlCenter : myAlignment := myAlignment or DT_VCENTER;
      tlBottom : myAlignment := myAlignment or DT_BOTTOM;
    end;
    
    IF FWordWrap then myAlignment := MyAlignment or DT_WORDBREAK;

    DrawText(self.Canvas.Handle, PChar(FText), -1, TextRect, myAlignment);
und alles ist super.

Um mal kurz auf das Thema runde Ecken zu kommen. Wie es in echt gemacht wird ist mir auch nicht bekannt. Aber such mal CombineRGN und CreateRGN hier im Forum. Da wirst du was zu Transparenz und "Durchklickbar" finden. Ich denke zu zeichnes dann deinen Rahmen mit runden Ecken und kombinierst zwei Ranges miteinander. Einer ist begrenzt durch BoundsRect, der Zweite durch deinen Rahmen. Somit wird der äußere Bereich transparent und Durchklickbar.
guckst du hier hier

Gruß oki
42
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 6. Sep 2007, 06:10
Danke für den Tipp und die Einkürzung des Codes. Die Zusammenstellung ist schon ok, aber leider habe ich immer noch das Problem, dass LAYOUT nicht funktioniert. Das war auch der Grund warum ich den Aufbau in meinem vorherigen Post darlegte.

Irgendwie scheint das was nicht zu stimmen...

Den Rest mit dem Border und Deinen weiteren Hinweisen zu den abgerundeten Ecken werde ich mir nach dem jetzt stattfindenden Wocheneinkauf anschauen.

EDIT
Habe mir FrameRect angesehen und werde es wohl meiden, da es fix einen Border von einem Pixel zeichnet. So wie ich es habe bin ich flexibel und könnte es sogar dahingehend aufboren, dass man jeder Seite seine eigene Rahmenbreite zuweisen kann.
Danke
Tom
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 6. Sep 2007, 06:30
Moin torud,

Zitat von torud:
Habe mir FrameRect angesehen und werde es wohl meiden, da es fix einen Border von einem Pixel zeichnet. So wie ich es habe bin ich flexibel und könnte es sogar dahingehend aufboren, dass man jeder Seite seine eigene Rahmenbreite zuweisen kann.
Klar!

Bei deinem Code mit dem Layout kann ich keinen Fehler finden. Da mußt du an anderer Stelle was falsch machen. Geh mal mit dem Debugger durch den Bereich mit TextDraw und dem Setzen der attribute und sag mal was passiert.

Gruß oki
42
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#9

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 6. Sep 2007, 06:52
Sorry für die Dumme Frage, aber wenn ich in der Komponente F9 drücke und mir vorher einen Stopppunkt setze, funzt das leider nicht, dass ich mir das mit dem Debugger anschauen kann, da ihm wohl noch eine Host-Anwendung fehlt => ist doch meine erste Komponente. Ich weiss es nicht besser. Was muss ich tun?
Danke
Tom
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 6. Sep 2007, 07:59
Hi,

kein Problem.
Eine Compo alleine kannst du nicht debuggen. Ist ja imho nur ne Unit (+Pakage). Du mußt dir eine kleine Testanwendung schreiben. einfach neue Anwendung und deine neue Compo auf der Form platzieren. Dann öffnest du deine Unit (der Compo), compilierst das Projekt und setzt den Brakepoint. Dann anwendung starten. Da dein Brakepoint in der Paint-methode steckt, wird er natürlich sofort angesprungen. Also am Besten Anwendung starten und dann Brakepoint setzen. immer wenn du deine Form in den Vordergrund bringst, schlägt der Debugger zu. Du kannst ja auch Variablen auswerten usw.

Wenn du weitere Fragen hast, keine Scham; her damit.

Gruß oki
42
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 13   « Erste     456 78     Letzte »    


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 10:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz