Delphi-PRAXiS
Seite 10 von 13   « Erste     8910 1112     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)

oki 7. Sep 2007 06:10

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

also wenn schon im OnPaint, dann sind imho die anderen Stellen überflüssig. Wenn sich aber das "ParentWindow" der Panels mittels Überzeichnen um die runden Ecken der Panels kümmert (und nicht die Panels selber), ist es einfach nur entscheidend, was sich im Fenster ändern kann. Ist kein Splitter oder ähnliches im Fenster und somit eine andere Positionnierung der Panels nur bei Größenänderung möglich, so würde ich es ins OnCreate (oder OnShow) und OnResize legen.

Mein Vorschlag:

OnCreate

OnResize

oder ausschließlich

OnPaint

Da torud aber an einer neuen Komponente bastelt frage ich mich, was daran schlecht ist, der Kompo selber runde ecken mit Transparenz außerhalb dieser zu verpassen. Hätte halt den Vorteil, dass sich die Kompos selbst um ihr Aussehen kümmern und man das nicht von oben im Form machen muß.

Gruß oki

[edit] Viele Edits, ist für korrekte Rechtschreibung noch zu früh :oops: [/edit oki]

torud 7. Sep 2007 07:09

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Liste der Anhänge anzeigen (Anzahl: 1)
Erstmal vielen Dank für den Code. Ich habe es mir angesehen und getestet, aber nicht wirklich für gut befunden. Ich habe in die Procedure noch eine Variable für Rundung der Ecken eingefügt, um besser damit spielen zu können und diese Einstellung schneller ändern zu können.

Leider gibt es auch hier das Problem der Kantenglättung, für das scheinbar noch keiner eine Lösung gefunden hat, denn wenn man eine grössere abgerundete Ecke vorgibt, sieht es nicht wirklich schön aus.

Desweiteren habe ich ja in meiner Komponente die Möglichkeit ein Bild zu laden, einen Gradienten zu zeichnen oder einen Text anzeigen zu lassen. Ich habe es nicht hinbekommen, den Canvas transparent zeichnen zu lassen. Ich dachte, dass es damit gehen könnte:

Delphi-Quellcode:
img[i].Canvas.Brush.Style := bsClear;
img[i].Canvas.Brush.Color := clNone;
Dem war aber nicht so. Also wenn ich das so in meinen Code übernehme, müsste es zum einen transparent sein und zum anderen müsste eine Kantenglättung durchgeführt werden. Hierzu habe ich einen Thread bei der Konkurrenz gefunden.

http://www.delphi-forum.de/viewtopic...751&highlight=

Dort gibt es zum einen die Möglichkeit eine Line zu glätten, oder aber auch eine Ellipse. Vielleicht könnte man das noch etwas verfeinern...!? Aber der Thread scheint dort auch tot zu sein...

Auf jeden Fall danke ich Euch sehr für Eure Ideen und Mitwirkung!
Im Anhang mal ein Bild mit den bisherigen Möglichkeiten.

torud 7. Sep 2007 09:08

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Ich habe mal einfacherweise versucht folgenden Code in die Komponente zu implemtieren, da es mir als passend erschien, um die runden Ecken zu realisieren. Aber soo einfach solls wohl doch nicht sein :) , denn leider werden die runden Ecken zum einen nicht realisiert und zum anderen hat die Komponente natürlich dann Probleme beim zeichnen des Borders.

Delphi-Quellcode:
private
    FCornerUse:boolean;
    FCornerWidth:integer;
published
    property CornerUse : boolean read FCornerUse  write FCornerUse;
    property CornerWidth : integer read FCornerWidth  write FCornerWidth;

procedure TmyPanel.Paint;
var
  reg: hrgn;
begin
  .....
    if CornerUse and (CornerWidth > 0) then
      begin
        reg := CreateRoundRectRgn(0,0,self.Width,
          self.Height, CornerWidth,CornerWidth);
        setwindowrgn(self.Handle, reg, True);
        deleteobject(reg);
      end;
  .....
Ich habe es mir deswegen soo einfach gemacht, weil dieser Code bei dem Beispiel mit dem Panel aich ohne Image funktioniert hatte. Vielleicht muss man ja doch den Umweg mit dem Image in Kauf nehmen oder es so angehen, wie von OKI angedacht!? Ich spiele noch ein wenig mit dem Code rum.

BTW. Schatten um die Komponente waäre auch "cool"...

torud 7. Sep 2007 10:58

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
So, die Version mit dem Panel-BeispielCode lief also gar nicht! Wahrscheinlich lags daran, dass es ein TCustomControl ist...

Nun habe ich OKI´s Code mal implementiert und sehe zumindest transparenzen...Allerdings keine runden Ecken. Ich habe den Code so wie er war eingebunden und völlig sorgenfrei in OnPaint einfach aufgerufen...(war vielleicht etwas blauäugig :shock: )

DoVisible habe ich nicht angerührt, aber in DoInvisible habe ich folgendes versucht...
Delphi-Quellcode:
procedure TmyPanel.DoInvisible;
begin
  //gesamten Clientbereich erfassen
  if FullRgn <> 0 then
    DeleteObject(FullRgn);
  FullRgn := CreateRectRgn(0, 0, Width, Height);
  //'Mask' alles unsichtbar
  CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

  // alle sichtbaren Bereiche einblenden
  PointRgn := CreateRectRgn( CornerWidth, CornerWidth, Width, Height);  // aus 0 wurde CornerWidth
  CombineRgn( FullRgn, FullRgn, PointRgn, RGN_OR );
  DeleteObject(Pointrgn);

  // alles Kombiniert und fertig
  SetWindowRgn(Handle, FullRgn, TRUE);
end;
Also ich glaube, dass ich es nicht einfach beides im OnPaint aufrufen sollte, da es selbst schon zur DesignTime einiges an Ressourcen zu fressen scheint... => naja und so wie ich es jetzt versucht habe, funzt es auch noch nicht...ich bleibe am Ball...

oki 7. Sep 2007 12:09

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hi, also ich denke immer noch, dass Doinvisible ab besten im createWnd und in den Ereignissen für Rezise aufgehoben ist. Zu den runden Ecken; das ist sicher etwas anspruchsvoller da den "rahmenden" Bereich zu finden.

aber deshalb bin ich ja auch an dem Code interessiert. :wink:

Gruß oki

Alter Mann 7. Sep 2007 14:46

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

reicht das hier:
Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  R     : TRect;
  Region : hRgn;
begin
  R := GetClientRect;
  with Canvas do
  begin
    Pen.Color := FBorderColor;
    Region := CreateRoundRectRgn(0, 0, R.Right, R.Bottom, 20, 20);
    FrameRgn(Canvas.Handle, Region, Canvas.Pen.Handle, R.Right, R.Bottom);
    SetWindowRgn(Handle, Region, True);
    DeleteObject(Region);

    Region := CreateRoundRectRgn(FBorderWidth, FBorderWidth, R.Right - FBorderWidth, R.Bottom - FBorderWidth, 20, 20);
    FillRgn(Canvas.Handle, Region, Canvas.Brush.Handle);
    SetWindowRgn(Handle, Region, True);
    DeleteObject(Region);
  end;
end;
Gruß

oki 7. Sep 2007 15:08

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

CreateRoundRectRgn müßte es bringen. Kannst du mal einen ScreenShot liefern wie es damit aussieht?

Gruß oki

Alter Mann 7. Sep 2007 15:34

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier das Bild

oki 7. Sep 2007 15:45

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Liste der Anhänge anzeigen (Anzahl: 1)
Jo,

ich denk mal, damit kann man doch für's erste leben.
Also wenn Tom das nicht reicht, dann weis ich auch nicht.

[OT] Bei mir ist es etwas komplizierter. Meine Verbinder sind in allen Bereichen zur Laufzeit änderbar. Alles neben den Linien ist transparent und durchklickbar. (Bild im Anhang) [/OT]

Gruß oki

torud 7. Sep 2007 18:39

Re: Benötige Hilfe beim Entwickeln einer Komponente
 
Hätte mich gewundert, wenn ich es hinbekommen hätte. :shock:

In meinem ersten Versuch waren die Ecken abgerundet, aber der normale Border war auch noch da. Alles was ich danach geändert habe hatte nur noch zum Erfolg, dass jetzt gar nichts mehr zu sehen ist, wenn ich mein Beispielprojekt öffne.

Mein Code im OnPaint sieht nun so aus. Da ich morgen nach Österreich muss, kann ich noch etwas im stillen Kämmerlein probieren, bevor ich mir den Strick nehme. Dabei das es schon soo gut aus auf dem Bild vom "Jungen Freund"...

Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  myRect,TextRect,CalcRect,R : TRect;
  myBorderWidth,myBorderWidthRightBottom:Integer;
  myAlignment : Cardinal;
  Region: hrgn;
begin
    if CornerUse and (CornerWidth > 0) then
      begin
        R := GetClientRect;
        with Canvas do
        begin
          Pen.Color := FBorderColor;
          Region := CreateRoundRectRgn(0, 0, R.Right, R.Bottom, 20, 20);
          FrameRgn(Canvas.Handle, Region, Canvas.Pen.Handle, R.Right, R.Bottom);
          SetWindowRgn(Handle, Region, True);
          DeleteObject(Region);

          Region := CreateRoundRectRgn(FBorderWidth, FBorderWidth, R.Right - FBorderWidth, R.Bottom - FBorderWidth, 20, 20);
          FillRgn(Canvas.Handle, Region, Canvas.Brush.Handle);
          SetWindowRgn(Handle, Region, True);
          DeleteObject(Region);
        end;
        DoVisible;
        DoInvisible;
      end;

  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;
    self.Canvas.Font.Assign(Font);

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

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

    //berechnen und zeichnen des rahmens
    if BorderWidth > 0 then
      begin
        case BorderWidth of
          1    : begin
                   myBorderWidth := 0;
                   myBorderWidthRightBottom := 1;
                 end;
          else  begin
                   myBorderWidth := BorderWidth div 2;
                   myBorderWidthRightBottom := BorderWidth div 2;
                 end;
        end;

        Canvas.MoveTo(0 + myBorderWidth,0);
        Canvas.LineTo(myRect.Left + myBorderWidth,myRect.Bottom);

        Canvas.MoveTo(0,0 + myBorderWidth);
        Canvas.LineTo(myRect.Right,myRect.Top + myBorderWidth);

        Canvas.MoveTo(self.Width-myBorderWidthRightBottom,0);
        Canvas.LineTo(myRect.Right-myBorderWidthRightBottom,myRect.Bottom);

        Canvas.MoveTo(0,self.Height-myBorderWidthRightBottom);
        Canvas.LineTo(myRect.Right,myRect.Bottom-myBorderWidthRightBottom);
      end;

    //schreiben des textes
    TextRect := Rect(BorderWidth + TextMargin, BorderWidth + TextMargin, self.Width-BorderWidth - TextMargin, self.Height-BorderWidth - TextMargin);
    SetBkMode(Canvas.Handle, TRANSPARENT);

    //init
    myAlignment := 0;

    case TextAlign of
      taCenter      : myAlignment := DT_CENTER;
      taLeftJustify : myAlignment := DT_LEFT;
      taRightJustify : myAlignment := DT_RIGHT;
    end;

    IF FTextWordwrap then myAlignment := MyAlignment or DT_WORDBREAK
    else myAlignment := MyAlignment or DT_SINGLELINE;

    if FLayout <> tlTop then
        begin
          CalcRect := TextRect;
          DrawText(Canvas.Handle, PChar(FText), -1, CalcRect, myAlignment or DT_CALCRECT);
          if FLayout = tlBottom then OffsetRect(TextRect, 0, Height - CalcRect.Bottom)
                                else OffsetRect(TextRect, 0, (Height - CalcRect.Bottom) div 2);
        end;
        DrawText(Canvas.Handle, PChar(FText), -1, TextRect, myAlignment);
end;

Ich weiss, dass da noch ein wenig durcheinander ist und dass ich da durchaus Ordnung schaffen muss, aber ich hatte heute leider nur wenig zeit Zum Testen...Aber ich bring das auch bald in Ordnung...


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:04 Uhr.
Seite 10 von 13   « Erste     8910 1112     Letzte »    

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