![]() |
Linien Komponente
Hi!
Ich hab mal wieder ein Problem: Ich suche ein Linien-Komponente. Im Internet hab ich gefunden das man die am besten selber macht und von TShapes ableitet. Ich hab sowas aber noch nie gemacht und weiß nicht wie's geht. :?: Ich bräuchte das so: x1,y1,x2,y2 als Punkte und dazwischen eine Linie (vielleicht noch mit Breiten-änderung). (Wie das mit der Linie geht weiß ich auch nicht) Ich brauch sozugen nur ein Starthilfe. :) Achso wenn es sowas schon gibt dann brauch ich das nicht selber programmieren. Aber ich hab schonmal geguckt und nichts gefunden.) |
Re: Linien Komponente
Hi,
was genau verstehst du denn unter einer Linien Komponente? Also am einfachsten ist es, wenn du die Linie selbst zeichnest. Dazu brauchst du einen Canvas, das ist die Zeichenfläche. So ein Canvas ist etwas, was du nie direkt selbst erzeugst, du verwendest vielmehr immer einen, der dir zur Verfügung gestellt wird. Typsiche Beispiele sind hier alle Fenster von Windows. Die Zeichenroutine bekommt einfach deren Canvas übergeben und die zeichnet dann darauf. Das was die zeichnet ist dann das, was du siehst. Auch dein Formular hat einen Canvas. Auf den könntest du direkt zeichnen (was aber nicht so wirklich schön ist). Am einfachsten kannst du selbst zeichnen, wenn du eine Bitmap verwendest. TBitmap kapselt alles was du brauchst, da gibt es dann sogar schon eine Funktion für das was du vor hast:
Delphi-Quellcode:
Ok, hier fehlt natürlich als erstes mal die Größe der Bitmap. Da musst du schauen, welche Größe du brauchst. Dann fehlt auch noch das Anzeigen. Der einfachste Weg ist, dass du ein TImage nimmst. Um hier ein Bitmap anzuzeigen musst du (vor dem Bitmap.Free) der Eigenschaft Image.Picture das Bitmap zuweisen.
procedure drawLine(const x1, y1, x2, y2 : Integer);
var bitmap : TBitmap; begin bitmap := TBitmap.Create; // wichtig Größe setzen bitmap.Width := xxx; bitmap.Height := xxx; // das eigentliche Zeichnen bitmap.Canvas.MoveTo(x1, y1); bitmap.Canvas.LineTo(x2, y2); bitmap.Free; end; Gruß Der Unwissende |
Re: Linien Komponente
Hi Unwissender (da war er wieder :stupid: )
warum redest du immer von Bitmap und Image. Halinchen will doch nur eine Linie. Ich dächte TBevel währe da doch schon mal was. wenn die Linie dann noch was anderes können muß außer eine Linie zu sein, dann können wir ja noch mal schauen. :stupid: gruß oki |
Re: Linien Komponente
Hi Oki,
ja hast schon recht, ich dachte nur wenn man zwei x,y Tupel angibt, dann doch eigentlich weil man nicht langweilig gerade Linien möchte (also senkrecht zu den Seiten des Fensters). Ansonsten fehlt (soweit ich weiß) dem TBevel die Möglichkeit die Dicke der Linie zu verändern. Bei einem Canvas gibt es einen Strift, mit dem die Linie gezeichnet wird (Eigenschaft Pen des Canvas), dieser hat dann eine Farbe und eine Dicke. Für Shapes gibt es einen ähnlichen Grund, aus dem ich sie ausgeschlossen hatte. Einem TShape fehlt die Linie (oder irre ich mich auch da?). Gruß Der Unwissende |
Re: Linien Komponente
Erstmal danke für die Antworten!
Mit Canvas kenn ich mich nicht so aus, aber ich wollte die Linie zur Laufzeit immer wieder wo anders hinsetzen und länger oder kürzer machen. Außerdem sollte die Linie auch diagonal sein können. Das geht zwar alles mit Canvas, aber ich hätte das lieber als Object, da ich mich da besser auskenne. Bevel und Shape-Control können nicht diagonal sein. (Wenn man Shape auf Rechteck setzt und Height auf 1 setzt hat man waagerechte Linie, aber keine diagonale.) |
Re: Linien Komponente
Ein Canvas ist doch auch ein Objekt. da man auf dem Canvae zeichen kann, ist diese Lösung doch flexibel. Es gibt verschiedene Komponenten, welche einen Canvas anbieten z.B. TImage, TPaintBox, ...
|
Re: Linien Komponente
Ich hab das alles nochmal überdacht. Es gibt eigentlich 1 gute Möglichkeiten.
Ich mache eine Komponente oder ein Objekt mit den vier Punkten als Property. Wenn die Propertys berabeitet werden mach ich eine Line dazwischen. Dann muss ich aber vorher refresh aufrufen, da sonst die alte Linie erhaltenbleibt. Die anderen Linien die die gezeichnet worden (Im falle von mehreren Variablen des Linien-Objekts) sind dann aber auch weg. Da scheib ich eine Prozedur die alle Linien Objekte durchgeht und die dann neuzeichnet. Kann mir vielleicht jemand sagen wie das bei TShapes geht? Die werden ja automatisch neugezeichnet. Das könnte ich vielleicht bei mir einbauen.) :-D |
Re: Linien Komponente
Das mit einer festen Anzahl von Properties für die Punkte ist aber schlecht. Nimm lieber eine dynamische Anzahl von Punkten so kannst du statt Linien auch komplexere Linienzüge zeichen ( Polyline, Polygone)
|
Re: Linien Komponente
Hi hallinche,
klar, bei diagonalen Linien ist es natürlich vorbei mit den Bevels. Also mußt du dir wirklich ein geeignetes Basisobjekt suchen und deine eigenen Zeichenroutinen schreiben. Achte aber darauf, das es von TComponent abgeleitet ist. Dann nehme z.B. bei einem Panel nicht TPanel, sondern TCustomPanel... Als nächstes würde ich erst mal genau sortieren, was du mit deiner neuen Komponente alles machen möchtest. Diese Idee ist nicht schlecht: Zitat:
das automatische Zeichnen ist nicht weiter schlimm. Hier vererbst du die Paint-Methode via override und implementierst deine eigene Zeichenmethode.
Delphi-Quellcode:
In MyPaint schreibst du alles was du für dein Zeichen brauchst.
procedure TMyObject.Paint;
begin inherited; MyPaint; end; gruß oki |
Re: Linien Komponente
Das klingt gut, da weiß ich jetzt was ich machen muss.
:-D Danke für die vielen Antworten. :party: |
Re: Linien Komponente
Hi!
Das hab ich jetzt im Quelltext stehen. (Hab mich erstmal nur für die einfache Linie entschieden.)
Delphi-Quellcode:
Meine Fragen:
unit Line;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TLine = class(TComponent) private A,E:TPoint; //Anfang+Ende W:Integer; //Width C:TColor; //Color Can:TCanvas; /Canvas { Private-Deklarationen } protected { Protected-Deklarationen } public procedure Draw; { Public-Deklarationen } published property X1:Integer read A.X write A.X; property X2:Integer read A.Y write A.Y; property Y1:Integer read E.X write e.X; property Y2:Integer read E.Y write E.Y; property Witdth:integer read W write W; property Color:TColor read C write C; property Canvas:TCanvas read Can write Can; { Published-Deklarationen } end; procedure Register; implementation procedure Tline.Draw; begin Can.PenPos := A; Can.Pen.Width := W; Can.Pen.Color := C; Can.LineTo(E.X,E.Y); end; procedure Register; begin RegisterComponents('Zusätzlich', [TLine]); end; end. 1. Can := Form1.Canvas; geht nicht. (Geht schon aber da ist das ja kein Verweis auf Form1.Canvas sondern nur eine Wertübergabe. Und ich möchte einen Verwies. 2.Wie mach ich ein Ereignis? Im meinem Buch steht: type TEreignis = procedure (Sender: TComponent;var I: Integer) of object; und dann in der Klasse:
Delphi-Quellcode:
Aber wie mach ich, dass das Programm OnEreignis aufruft, wenn irgentwas passiert ist (überzeichnet, geklickt)?
private
FEreignis: TEreignis; published property OnEreignis: TEreignis read FEreignis write FEreignis; |
Re: Linien Komponente
1. Du kannst auf das Canvas der Form zugreifen mit
Delphi-Quellcode:
2. Dort wo das Ereignis ausgelöst werden soll
If Assigned(AOwner) then
if (AOwner is TForm) then TForm(AOwner).Canvas.LineTo ... // Besser wäre noch statt TForm TWinControl zu verwenden. If Assigned(AOwner) then if (AOwner is TWinControl) then TWinControl(AOwner).Canvas.LineTo ...
Delphi-Quellcode:
If Assigned(FEreignis) then
FEreignis; // Besser statt TEreignis TNotifyEvent // Dann aber If Assigned(FEreignis) then FEreignis(Self); // Damit kannst Du im OnEreignis abfragen (Sender) welche Komponente das Ereignis ausgelöst hat. // z.B. If Sender=LineControl2 then TueIrgendwas; |
Re: Linien Komponente
Hi halinchen,
@ Sunlight7: Vorsicht, TWincontrol besitzt keinen Canvas. Der ist erst ab TCustomcontrol dabei. @ Halinchen: Ich würde an deiner Stelle nicht auf dem Canvas des Parents malen. Sicher ist das Ansichtssache, aber mit einer visuellen Componente ist das Platzieren meiner Meinung nach einfacher. Somit würde ich die Kompo folgendermaßen aufbauen:
Delphi-Quellcode:
o.k., jetzt gibt das natürlich wenig Sinn mit den Koordinaten. so lange du hier keine Polygone zeichen möchtest, die du in einer Funktion abbilden kannst, reicht es hier eine Eigenschaft für die Linienart aufzunehmen. In einer visuellen Kompo nimmst du als koordinaten dann die entsprechenden eigenen Dimensionen wie self.left usw.
unit Line;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TLine = class(TCustomControl) private A,E:TPoint; //Anfang+Ende W:Integer; //Width C:TColor; //Color Can:TCanvas; //Canvas { Private-Deklarationen } protected { Protected-Deklarationen } procedure Draw; procedure Paint; override; public { Public-Deklarationen } published property X1:Integer read A.X write A.X; property X2:Integer read A.Y write A.Y; property Y1:Integer read E.X write e.X; property Y2:Integer read E.Y write E.Y; property Witdth:integer read W write W; property Color:TColor read C write C; property Canvas:TCanvas read Can write Can; { Published-Deklarationen } end; procedure Register; implementation procedure Tline.Draw; begin self.canvas.PenPos := A; self.canvas.Pen.Width := W; self.canvas.Pen.Color := C; self.canvas.LineTo(E.X,E.Y); end; procedure Register; begin RegisterComponents('Zusätzlich', [TLine]); end; procedure TLine.Paint; begin inherited; Draw; end; end. Bsp.:
Delphi-Quellcode:
Hier kannst du dann auch noch weitere typen aufnehmen wie Diagonalen usw.
type
TLineType = (ltNone, // keine Linie ltLeft, // Linie links ltRight, // Linie rechts ltTop, // Linie oben ltBottom, // Linie unten ltVCenter, // Mitte vertikal ltHCenter // Mitte horizontal ); weitere Eigenschaften für Linienenden (Pfeile, kreise ...) kannst du natürlich genauso einbinden. Diverse Graphikprogramme bitten da einen guten Überblick über probate Linieneigenschaften (vorallem vektor orientierte wie CorelDraw usw.). In deiner Draw Methode kannst du dann mit Case of in die entsprechenden Zeichenmethoden verzweigen. Gruß oki |
Re: Linien Komponente
@oki
Danke für den Hinweis. Eigentlich sollte ich das ja Wissen, aber auch nach 10 Jahren falle ich immer wieder auf TWinControl rein :oops: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 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