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 12 von 13   « Erste     2101112 13      
torud

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 20:04
Zitat von oki:
Um das noch mal in Erinnerung zu bringen, hier der Code den ich gepostet habe
Das was Tom macht ist den letzten Teil meines (auch hier dem Forum entlehnt) Codes herauszunehmen. Der Anfangs- und Mittelteil fehlt völlig und der Rest ist inkorrect!

Kein Wunder, dass nichts mehr geht.
Gruß oki
Hallo Oki,

ich war eigentlich ziemlich froh, dass Du mir so derart unter die Arme gegriffen hast und mir so viel Code zur Verfügung gestellt und erklärt hast. Um so enttäuschter bin ich selbst von meiner eigenen Leistung. Was ich aber nicht ganz verstehen kann ist Deine Behauptung, dass ich irgendwelchen Code weglassen würde. Dies war nämlich nicht der Fall! Ich will hier nicht rumzicken, möchte aber durchaus unterstreichen, dass ich eigentlich immer recht sorgsam mit externem Code umgehe! So, dass dazu...

Ich bin sicher keine grosse Leuchte, aber ich bin durchaus versucht das zu verbessern und das Problem, auch wenns mir keiner mehr glaubt, zu lösen, denn ich will das Ergebnis auch mal sehen. Will sagen, nach weiteren Versuchen läuft es immer noch nicht. Ich habe zwischenzeitlich mal den angerundeten Border schimmern sehen - mehr nicht. Ich habe DoVisible mal im Create gehabt, mal im Paint am Anfang, aber es wird nicht wirklich was. Nun dachte ich mir, dass es vielleicht günstig wäre es im Create und OnResize zu haben!? Aber dazu müsste ich OnResize erstmal haben in der Komponente. Falls das Sinn macht, würde ich mich über ein Wink freuen. Ich weiss, dass ich manchmal nervig bin und nen dummen Eindruck hinterlasse, aber ich würde mich freuen nochmals eine Antwort zu erhalten.

Ich poste jetzt nicht den Ganzen Code, weil ich weiss, dass sich das eh keiner ansieht...

Ich finds nur komisch, dass der "Alte Mann" einen Code postet, der bei Dir "Oki" zu funktionieren scheint, bei mir aber wirkungslos bleibt.

Steht denn dieser Code im Zusammenhang mit den proceduren DoVisible und DoInvisible?
Du schriebst, du würdest DoInvisible im CreateWnd aufrufen? Was meinst Du damit? Es im OnCreate der Komponente selbst aufrufen? Das habe ich ja versucht...

Ich weiss nicht wirklich weiter...
Danke
Tom
  Mit Zitat antworten Zitat
oki

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 20:21
Hi Tom,

erst mal sorry, wenn sich mein letzter Beitrag so abfällig angehört hat. Das war nicht meine Absicht !!!!

Ich erkläre es noch mal Stück für Stück so wie ich es verstanden habe (mache das nämlich auch erst seit kurzem).
Ich leg dir mal ein Beispielprojekt in den Anhang das ich selber mal gezogen hab.

DoVisible ist dafür, um alles wieder sichtbar zu machen.

Eigentlich interessiert nur DoInvisible. Glaub ich jedenfalls. Jetzt werd ich auch schon unsicher.

Ich hab noch mal nachgeschaut. DoVisible muß vor der Neuberechnung nicht aufgerufen werden.
Schau dir mal das Beispiel im Anhang an. Dann ist bestimmt einiges klarer.

Gruß oki
Angehängte Dateien
Dateityp: zip tranform_151.zip (2,1 KB, 16x aufgerufen)
42
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

Registriert seit: 17. Sep 2006
Ort: Sonnensystem, Zentral
1.522 Beiträge
 
Delphi 5 Standard
 
#113

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 20:23
Im Create Constructor macht es wenig Sinn, da das Fenster Handle noch nicht da is.
Es wäre zu empfehlen, die Methode Loaded zu überschreiben und es da zu machen, bzw., auch im Resize;

Edit: Rote Kästen wären Toll

Hab mal reingeguckt:

Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender: TObject);
begin
  //Clean up the regions we created
  DeleteObject(ClientRgn);
  DeleteObject(FullRgn);
  DeleteObject(CtlRgn);
end;
DeleteObject(FullRgn) nicht löschen, auch net im Desctructor;

Noch eine Anmerkung, es macht einen Unterschied, ob Du auf einem FOrmular, oder in einer Komponente programmierst.
Zb ist FormCreate <> constructor Create...
Windows: Ja - Microsoft: Nein -> www.ReactOS.org
  Mit Zitat antworten Zitat
oki

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 20:44
Hi sunlight,

zum Thema OnCreate habe ich mich schon weiter vorne geäußert und dort immer von CreateWnd gesprochen. Das Beispiel soll Tom nur zeigen wie es geht und ihm ein funzendes Bsp. in die Hand geben, mit dem er testen kann.

Nochmal, das Bsp. ist nicht von mir!!!

@Tom:

ungeprüfte Überarbeitung deiner Paint-Procedure. Ich habe nur die Thematik Ausblenden des äußeren Bereiches eingearbeitet. Ums Zeichnen hab ich mich nicht gekümmert!

Delphi-Quellcode:
procedure TmyPanel.Paint;
var
  myRect,TextRect,CalcRect,R : TRect;
  myBorderWidth,myBorderWidthRightBottom:Integer;
  myAlignment : Cardinal;
  Region: hrgn;
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;
    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);

  // und jetzt machen wir den Rahmen unsichtbar
  if CornerUse and (CornerWidth > 0) then begin
    R := GetClientRect;
    FullRgn := CreateRectRgn(0, 0, Width, Height);
    CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

    // alle sichtbaren Bereiche einblenden
    Region := CreateRoundRectRgn(FBorderWidth, FBorderWidth, R.Right - FBorderWidth, R.Bottom - FBorderWidth, 20, 20);
    CombineRgn( FullRgn, FullRgn, Region, RGN_OR );
    DeleteObject(Region);

    // alles Kombiniert und fertig
    SetWindowRgn(Handle, FullRgn, TRUE);
  end else DoVisible;
end;
Gruß oki
42
  Mit Zitat antworten Zitat
torud

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 21:53
Servus Oki,

vielen Dank für Deinen Code. Erstens es läuft!!! Zweitens es fehlt der Rahmen. Kann ich den noch mit in die "if CornerUse and (CornerWidth > 0) then"-Bedingung mit einbauen? Die Antwort wird sicher sein ja, aber wie muss ich das anstellen? soll ich den Code dazu mit in die Bedingung einbringen und über den Canvas zeichnen lassen?

Sicher ja!?

Was mir noch aufgefallen ist, ist das der Radius der Ecken eigentlich immer gleich bleibt, es aber so aussieht, als würde das gesamte Control mit zunehmendem Radius sich verkleinern, so als o man einen Padding angibt, aber keinen Radius. Da scheint noch was nicht ganz korrekt zu sein. Ich spiel wieder etwas mit dem Code, danke Dir aber von Herzen!!!

//edit
Ich habe es mir nochmals angesehen. Ich denke, dass ich "oben" noch eine Bedingung um das Zeichnen des Borders legen sollte, da dieser bis jetzt immer gezeichnet wird, dies aber nicht wirklich nötig ist, wenn der Radius für die abgerundeten Ecken angegeben wurde. Der von mir angesprochene Padding ergibt sich auch aus der angegebenen BorderWidth. Der Radius selbst bleibt bisher starr...
Danke
Tom
  Mit Zitat antworten Zitat
oki

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 8. Sep 2007, 23:01
Hi Tom,

ja,

ja.

Wo du den Code für den Rahmen unter bringst ist eigentlich egal. In der "IF CornerUse" -Anweisung ist es wohl am passensten. Und ja, auf den Canvas zeichnen. Entweder durch eine Canvas- oder Win-API-Methode.

Noch mal Zum Verständnis. Du kannst zeichnen soviel du willst und was du willst. Zuerst ist alles unsichtbar, und jede Region die du mit RGN_OR kombinierst wird sichtbar. Bei dir ist das jetzt so, dass du eine Region als Rechteck mit abgerundeten Ecken in den von dir vorgegebenen Dimensionen creierst und durch die kombination mit deinem FullRgn sichtbar machst. Somit ist also alles innerhalb dieser Region sichtbar, und alles was du in diesen Bereich zeichnest auch.

Zeichne also einen Rahmen mit abgerundeten Ecken innerhalb deiner Region und alles müsste klappen.
Mit CreateRoundRectRgn habe ich leider auch keine Erfahrungen. Die Win32-Hilfe sagt dazu aber folgendes:
Zitat:
The CreateRoundRectRgn function creates a rectangular region with rounded corners.

HRGN CreateRoundRectRgn(

int nLeftRect, // x-coordinate of the region's upper-left corner
int nTopRect, // y-coordinate of the region's upper-left corner
int nRightRect, // x-coordinate of the region's lower-right corner
int nBottomRect, // y-coordinate of the region's lower-right corner
int nWidthEllipse, // height of ellipse for rounded corners
int nHeightEllipse // width of ellipse for rounded corners
);


Parameters

nLeftRect

Specifies the x-coordinate of the upper-left corner of the region.

nTopRect

Specifies the y-coordinate of the upper-left corner of the region.

nRightRect

Specifies the x-coordinate of the lower-right corner of the region.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the region.

nWidthEllipse

Specifies the width of the ellipse used to create the rounded corners.

nHeightEllipse

Specifies the height of the ellipse used to create the rounded corners.
Damit müsste alles klar sein.

Gruß oki
42
  Mit Zitat antworten Zitat
torud

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 9. Sep 2007, 16:11
Hallo Oki,

ich habe jetzt wieder mal mit dem Code etwas experimentiert und versucht...

Das Gute ist, dass der Border nun auch gezeichnet wird. Was allerdings nicht funktioniert und das verstehe ich leider nicht ganz, ist , dass der Gradient nicht mehr gezeichnet wird und auch das Bild nicht mehr gezeichnet wird. Dies passiert nur, wenn ich die Variante mit den abgerundeten Ecken wähle.

Folgender Code wird in dem Falle ausgeführt, wobei die Reihenfolge die gleiche ist und myRect des Canvas durch R aus deinem Code ersetzt wurde.

Delphi-Quellcode:
  if CornerUse and (CornerWidth > 0) then begin
    R := GetClientRect;
    FullRgn := CreateRectRgn(0, 0, Width, Height);
    CombineRgn( FullRgn, FullRgn, FullRgn, RGN_DIFF );

    // alle sichtbaren Bereiche einblenden
    Region := CreateRoundRectRgn(0, 0, R.Right, R.Bottom, FCornerWidth, FCornerWidth);
    CombineRgn( FullRgn, FullRgn, Region, RGN_OR );
    DeleteObject(Region);

    // alles Kombiniert und fertig
    SetWindowRgn(Handle, FullRgn, TRUE);

    R := GetClientRect;
    //jetzt bitte Gradient zeichnen
    if PaintGradient then
      DrawGradient(Canvas, BgColorFrom, BgColorTo, R, GradientDirection);

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

    //bitte den border zeichnen
    if BorderWidth > 1 then
      Canvas.RoundRect(0 + (BorderWidth div 2), 0 + (BorderWidth div 2), width - (BorderWidth div 2),height - (BorderWidth div 2),FCornerWidth,FCornerWidth)
    else
      Canvas.RoundRect(0, 0, width-1, height-1,FCornerWidth,FCornerWidth);

    //und zum schluss noch den text drauf
    if FText <> 'then
      DrawText(Canvas.Handle, PChar(FText), -1, TextRect, myAlignment);
  end else DoVisible;
Der Border, wenn auch etwas unsauber ist mit abgerundeten Ecken zu sehen. Der Text ist auch auf dem Control. Es fehlen der Gradient, respektive das Bild. Ist kann ja immer nur eines von beiden zu sehen sein. Es wird aber komischerweise, wenn der Gradient auf True steht nur komplett mit schwarz oder der Farbe aus BGColorTo gefüllt und richtigerweise, wenn PaintGradient auf false steht, mit BgColorFrom gefüllt. Das heisst, dass der Gradient nicht korrekt ausgeführt wird. Ich habe, nur um sicher zu gehen, nochmals R := GetClientRect; ausgeführt, was aber nichts brachte.

Ich vermute mal, dass der Canvas sich irgendwie verändert hat, nach der Modifikation, was zur Folge hat, dass man nicht mehr so einfach ohne weiteres wie vorher drauf rummalen kann. Muss ich hierbei wieder etwas besonderes beachten?

Interessant ist auch, dass der Border bei den abgerundeten Ecken links und rechts oben "ausgefranst" aussieht, wenn ich PaintGradient auf false stehen habe. Ansonsten bin ich einigermaßen zufrieden und werde hier noch versuchen das Beste rauszuholen...Ein Bild hängt an...
Miniaturansicht angehängter Grafiken
gradients_102.png  
Danke
Tom
  Mit Zitat antworten Zitat
oki

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 9. Sep 2007, 18:41
Hi Tom,

deine letzte Aktion vor dem Text schreiben ist RoundRect.

Hier mal ein Auszug aus der Delphi Hilfe:
Zitat:
Mit RoundRect können Sie unter Verwendung des aktuellen Stifts ein Rechteck mit abgerundeten Ecken zeichnen. Das Rechteck wird mit dem aktuellen Pinsel gefüllt.
Das hab ich jetzt direkt aus der Hilfe kopiert. Auch ich habe jetzt erst nachgelesen, was RoundRect macht.

Wenn das Rechteck mit dem aktuellen Pinsel gefüllt wird, dann müssen doch alle vorherigen Zeichenoperationen (Gradient) auf dem Canvas übermalt werden. Oder nicht?

Gruß oki
42
  Mit Zitat antworten Zitat
torud

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

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 9. Sep 2007, 19:12
Ciao Oki,

rum wie nu, würde meine Schwester sagen, denn wenn ich den Gradient nachschiebe, wird er zwar gezeichnet, aber dann ist der Border weg. Ich dachte eigentlich, dass ich den Border zeichnen kann, indem ich nur den Pen benutzen und das Brush auch leer zeichnen kann...!?

Welche Möglichkeiten habe ich jetzt noch?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von cruiser
cruiser

Registriert seit: 23. Dez 2003
Ort: Königsbrück/Sachsen
455 Beiträge
 
Delphi 7 Enterprise
 
#120

Re: Benötige Hilfe beim Entwickeln einer Komponente

  Alt 9. Sep 2007, 19:28
vor dem Roundrect mach besser folgendes:

Canvas.Brush.Style := bsClear; Damit wird keine Füllung gezeichnet. dass da Pixwl hervorstehn liegt vermutlich an unterschiedlichen Radien
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 12 von 13   « Erste     2101112 13      


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 18:35 Uhr.
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