![]() |
Re: Benötige Hilfe beim Entwickeln einer Komponente
Zitat:
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... |
Re: Benötige Hilfe beim Entwickeln einer Komponente
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Tom,
erst mal sorry, wenn sich mein letzter Beitrag so abfällig angehört hat. Das war nicht meine Absicht :oops: !!!! 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. :pale: 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 |
Re: Benötige Hilfe beim Entwickeln einer Komponente
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 :roll: Hab mal reingeguckt:
Delphi-Quellcode:
DeleteObject(FullRgn) nicht löschen, auch net im Desctructor;
procedure TForm1.FormDestroy(Sender: TObject);
begin //Clean up the regions we created DeleteObject(ClientRgn); DeleteObject(FullRgn); DeleteObject(CtlRgn); end; Noch eine Anmerkung, es macht einen Unterschied, ob Du auf einem FOrmular, oder in einer Komponente programmierst. Zb ist FormCreate <> constructor Create... |
Re: Benötige Hilfe beim Entwickeln einer Komponente
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:
Gruß oki
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; |
Re: Benötige Hilfe beim Entwickeln einer Komponente
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... |
Re: Benötige Hilfe beim Entwickeln einer Komponente
Hi Tom,
ja, ja. :lol: 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:
Gruß oki |
Re: Benötige Hilfe beim Entwickeln einer Komponente
Liste der Anhänge anzeigen (Anzahl: 1)
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:
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.
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; 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... |
Re: Benötige Hilfe beim Entwickeln einer Komponente
Hi Tom,
deine letzte Aktion vor dem Text schreiben ist RoundRect. Hier mal ein Auszug aus der Delphi Hilfe: Zitat:
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 |
Re: Benötige Hilfe beim Entwickeln einer Komponente
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? |
Re: Benötige Hilfe beim Entwickeln einer Komponente
vor dem Roundrect mach besser folgendes:
Delphi-Quellcode:
Damit wird keine Füllung gezeichnet. dass da Pixwl hervorstehn liegt vermutlich an unterschiedlichen Radien
Canvas.Brush.Style := bsClear;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:02 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