Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Eigene Komponente X-beliebiges Aussehen (https://www.delphipraxis.net/210885-eigene-komponente-x-beliebiges-aussehen.html)

MarcRB75 26. Jun 2022 11:03

Eigene Komponente X-beliebiges Aussehen
 
Hallo,
ich habe eine Frage:
Kann man eine Komponente entwickeln, die z.B. wie ein Stern, wie eine Kurve oder sonst beliebig aussieht.
Man sollte dann, wenn man während der Laufzeit daran "zieht" die Komponentenform verändern können.
Die Komponente soll genau in dieser Zackenform (Ränder sind direkt an den Linien des Sterns) sein.

Also ein Beispiel: ein Stern hat X-Zacken.
Wenn man an einem Zacken nach rechts/links/oben/unten zieht, dann verändert sich das Aussehen.
Die Ränder der Komponente passen sich dann genau an der neuen Linie an, die man verschoben hat.

Geht das, kann man das überhaupt realisieren?

Vorab vielen Dank für Tipps oder Hilfe, denn ich weiß nicht weiter und weiß auch nicht wie ich ansetzen soll
bzw. wie ich das machen könnte.

stahli 26. Jun 2022 11:21

AW: Eigene Komponente X-beliebiges Aussehen
 
Schau mal, ob Dir das etwas hilft:
https://www.delphipraxis.net/185374-...ml#post1304439
https://www.delphipraxis.net/159798-...-mit-loch.html

MarcRB75 26. Jun 2022 11:24

AW: Eigene Komponente X-beliebiges Aussehen
 
Oh Danke für die schnelle Antwort. Das muss ich mir mal gleich ansehen. :-D

MarcRB75 26. Jun 2022 11:49

AW: Eigene Komponente X-beliebiges Aussehen
 
Also Dein Video hab ich mir angesehen.

Jaaaaaa so etwas möchte ich gerne machen. :thumb::spin2:

Nur, dass ich Quasi an den Ecken ziehen kann und dass sich dann die Größe des Bereichs verändert.

Ist es richtig, hab ich das richtig verstanden: ein Control bestimmt qusi das Aussehen, die Form?

Ich schau mir mal Deine Links näher an und versuche zu verstehen, was gemacht wird und welchen Effekt das hat.

Ich hoffe, ich blick da durch, denn wenn ich ehrlich bin, so richtig weiß ich nicht, wie ich überhaupt beginnen soll :roll:

TurboMagic 26. Jun 2022 12:37

AW: Eigene Komponente X-beliebiges Aussehen
 
Hallo,

ein Control ist, wenn es von der entsprechenden Klasse abgeleitet ist, für sein
eigenes Aussehen zuständig, d.h. muss sich selber zeichnen.

Ich gehe ja mal von VCL aus.
Wenn du dir die "Standard" Controls anschaust sind das i.d.R. die, die Windows
bereits bereit stellt und die VCL bedient sich derer. Wenn du unter "Zusätzlich"
schaust, sind das i.d.R. Controls die sich selber zeichnen, da es kein äquivalentesw
Windows Control davon gibt (oder dieses erst später in Windows eingeführt wurde).

Und falls dein Control nicht in einer "Closed source" Anwendung vorkommt, darfst du
es ruhig veröffentlichen. ;-)
Die Allgemeinheit freut sich ganz bestimmt über ein solches neues Steuerelement. :-)
Veröffentlichung kann gerne auch per GetIt erfolgen. Da kann ich dann evtl. etwas helfen,
ist aber eigentlich nicht kompliziert.

Grüße und viel Erfolg damit
TurboMagic

MarcRB75 26. Jun 2022 12:53

AW: Eigene Komponente X-beliebiges Aussehen
 
Hallo,
ja das würde ich gerne auch machen, aber wenn ich ehrlich bin, ich verstehe die Zusammenhänge nicht,
da aus den gesamten Codes nur Teile vorhanden sind.

z.B.

procedure Txxx.CalcPolygon(...; aBitmap: TBitmap;
aRect: TRect);
var
NewRegion: Boolean;
L: Integer;
I: Integer;

procedure SetPoint(Polygon: TPolygon; var I: Integer; X, Y: Integer;
var NewRegion: Boolean);
begin
if (Polygon[I].X <> X) or (Polygon[I].Y <> Y) then
NewRegion := true;
Polygon[I] := Point(X, Y);
Inc(I);
end;


Bei: Txxx.CalcPolygon(...; --->>> Da weiß ich z.B. nicht, was da im Ursprung deklariert wurde, bzw. bei den ... stehen muss.
oder procedure SetPoint(Polygon: TPolygon; ---> da wurde zuvor das TPolygon erzeugt, aber ich weiß nicht wie das geschehen ist.
oder var NewRegion: Boolean ... da muss ja auch eine Funktion/Prüfung vorliegen ...

ich weiß ja gds., wie man eigene Komponenten erstellt und die Ereignisse ect nach den Bedürfnissen anpasst.
Auch wie man ein Polygon zeichnet, oder generell zeichnet, weiß ich.
Mir ist schon bewusst, dass man Points, Arrays einsetzen muss... aber wann und wie...

Aber wie das mit der neuen Komponente, mit einer X-belieben Form, die sich dann anpasst ... funktionieren soll?? ...
Ich bin ehrlich, ich weiß nicht mal, wie ich anfangen soll. :oops::wall:

ach ... ich würde das Thema ja wirklich gerne angehen, würde mir aus einem gesamten Code schon das rauspicken, versuchen, umwandeln und Testen,
damit ich das Prinzip verstehe, ...:coder: ... aber so ...:roll:

TurboMagic 26. Jun 2022 13:01

AW: Eigene Komponente X-beliebiges Aussehen
 
Naja, deine Komponente bräuchte eine Angabe der Anzahl der Ecken.
Dann stelle dir den Stern mal so vor, dass alle Eckpunkte auf einer Kreisbahn liegen.
Aus der Eckenzahl wäre dann auszurechnen bei Welchem Winkel jeweils ein Eckpunkt auf
der Kreisbahn sein müsste und dann kann man bestimmt per Trigenometrie und unter Angabe
eines Radius ausrechnen wo die jeweilige X/Y Koordinate liegen müsste. Damit hättest du
alle Punkte des Polygons.

Das würde ich dann malk einfach mit einer TPaintBox zeichnen, noch ohne viel an eine
Komponente zu denken. Wenn du dann eine Methode hast die Radius und Eckenzahl als
Parameter bekommt und das auf der Paintbox zeichnen kann, dann hast du ja schon die
wesentliche Grundlage dafür.

Grüße
TurboMagic

MarcRB75 26. Jun 2022 13:46

AW: Eigene Komponente X-beliebiges Aussehen
 
Ich verstehe. Also einen Stern kann ich ja zeichnen.
Dann muss ich quasi alle Punkte, die aus dem Stern bestehen, auch die Spitzpunkte
als Variable/Array deklarieren.

Aber wenn ich diese Koordinaten habe/hätte, wie kann ich diese Komponente so "angleichen", dass die Komponente nicht im Quadrat oder nur im Rechteck
ist, sondern an den Sternlinien entlanggeht? Geht das überhaupt??

Eine andere Überlegung von mir war... ..........(geht nicht Überlastung des Arbeitsspeichers ....naja... war eine Überlegung wert....)
Ich fange an zu Zeichnen:
Irgenwo ... auf einem Pixel.
Die Maustaste ist gedrück.
Wenn ich mich der Maus mich bewege, wird für jeden einzelnen Punkt ein neues Image (1 Pixel) erzeugt, das eine X-beliebige Farbe hat.
Gehe ich mit gedrückter Maus zurück, werden die Pixel, dessen Koordinaten ich ja kenne, gelöscht bzw. mit der Hintergrundfarbe überzeichnet.

Lasse ich die Maustaste los, entsteht mein Bild aus den einzelnen Punkten.
Bei Bedarf, kann ich diese Punkte/Linien löschen, durch überzeichnen...

Das wäre doch aus was für den Anfang oder?

stahli 26. Jun 2022 14:13

AW: Eigene Komponente X-beliebiges Aussehen
 
Du musst Deine Zielstellung am besten in kleinere Teilbereiche zerlegen.

Zunächst würde ich einfach mal ein leeres Formular nehmen und darauf Figuren zeichnen ermöglichen.
Also im Grunde Objekte, die Du dann in der Größe verändern kannst.
Das wird schon eine ordentliche Aufgabe.

Später kannst Du das dann versuchen so anzupassen, dass Du tatsächliche Windows-Controls "ausstanzt".
Schwierig wird es sicherlich, diese dann noch Größenänderbar zu gestalten (womöglich wird das auch kaum umsetzbar).

Erkläre doch nochmal, wie Du diese "Controls" dann benutzen willst. Mit anderen Schaltern, Edits und Memos zusammen in einem Formular?
Wie und wann soll die Größe der Controls geändert werden?


In meinem Beispiel mit dem Schatten benutze ich kein Standardcontrols sondern zeichne alles selbst in ein Formular und merke mir alles, was ich wo gezeichnet habe.
Das zweite Beispiel schneidet einfach Teile eines normalen Panels weg.
Das sind sehr unterschiedliche Ansätze. Welcher davon möglicherweise für Dich passt, kann ich noch nicht so recht einschätzen.

MarcRB75 26. Jun 2022 15:09

AW: Eigene Komponente X-beliebiges Aussehen
 
Liste der Anhänge anzeigen (Anzahl: 5)
Also ich habe man einen Anhang gemacht, vielleicht versteht dann jeder besser was ich meine.
Also, es geht um Kurven, aber auch Sterne und sonstige Formen:

Der Anhang besteht aus:
a) Entwickler-Ebene / Bild
b) Code
c) Laufzeit - Anfang sowie wenn man die Punkte verschiebt.

Und das Ganze möchte ich aber als eigene Komponente machen, mit einem relativ genauen Rahmen um die Kuve und den einzelnen Punkte herum.

P.S. Vielleicht sagt der Eine oder Andere bei meinem Code ... furchtbar ... das könnte man anders machen. Ich weiß,
aber ich hab mir halt alles selber beigebracht, weiß leider auch nicht alles. Und das Ganze in diesem Fall ist halt
ein Versuch und bin eigentlich gds. ganz glücklich, dass das überhaupt so funktioniert.
Aber leider kann ich es nicht als Komponente mit schönem, genauen Rahmen um die Linien manchen. :wall::oops:

Oder zumindest um die eigentliche Kurve herum und die Punkte setze ich einzeln (jeder Punkt ist eine eigene Komponente)...

stahli 27. Jun 2022 09:17

AW: Eigene Komponente X-beliebiges Aussehen
 
Erst mal Respekt. Das sieht schon nicht schlecht aus. :thumb:

Ich gehe davon aus, dass Du Deine "COntrols" somit nur auf einer speziellen Zeichenfläche darstellen willst und nicht mit VCL-Controls zusammen in einem beliebigen Formular.

Dann finde ich Deinen Ansatz schon geeignet. Du kannst das etwa so sehen, wie im Delphi-Designer. Du hast hier im Delphi einen Button auf ein Formular gezogen.
Wenn Du ihn in der Größe ändern willst, musst Du ihn focussieren und erhältst "Anfasser", die Du dann ziehen kannst.
Die sind aber nicht Teil der Komponente sondern werden als Werkzeug von der IDE über dem Button selbst platziert.

Das entspricht Deiner Lösung und ist so auch sehr sinnvoll. Ich würde also grundsätzlich bei Deiner Lösung bleiben und die ggf. nur noch etwas an den Bedarf anpassen.

MarcRB75 27. Jun 2022 14:02

AW: Eigene Komponente X-beliebiges Aussehen
 
Ohhh das freut mich, dass es Dir gefällt.

Ich möchte jedoch statt des Image eine Paintbox verwenden, geht auch, weil diese durchsichtig ist und ich dadurch ggf. andere Linien durchsehen kann.
Denn wenn ich z.B. 2 Images überlagere, ist nur das ganze Front-Image zu sehen, das hintere nicht. Mit Transparent ect ... das funktioniert leider nicht.

Wenn ich Dich richtig verstehe:
Das Ganze (Bogen, alle Punkte) plaziere ich auf einem Image/Paintbox, die ich vorher als neue Komponente mache.
Gut, das geht, das bekomme ich hin.

Ja die Punkte selbst, möchte ich aber auch als "Werkzeug" benutzen, zur Komponente selbst (Bogen mit Anfangs+Endpunkt), wenn diese auf ein Formular gezogen wird. Das bekomme ich auch hin, ist kein Problem.

Aber wie kann ich dann, wie Du mir zuvor geschrieben hast, die Linien/Punkte "Ausstanzen", so dass kein viereckiger Rahmen entsteht, wenn ich
die "Bogen-Komponte" auf ein Formular lege?

Könntest Du mir bitte sagen, wie das geht oder wie ich das machen muss?

Angenommen ich habe alle Punkte des Bogens und die der Punkte ermittelt, wie kann ich dann n diese Form "Ausstanzen", so dass ein schöner Rahmen drumherum entsteht? Könntest Du mir das bitte sagen?

himitsu 27. Jun 2022 14:12

AW: Eigene Komponente X-beliebiges Aussehen
 
Durchsichtig ist sie nicht wirklich.
Aber, die PaintBox ist keine eigeneständiges WinControl, sondern hackt sich in den Parent rein und mals sich auf dessen Desktop ... daher kann der Desktop vorher noch seinen Inhalt da hinmalen, wo sich die PaintBox anschließend hinmalt.

Ebenso machen es TLabel und TBevel. (das "echte" Windows-Label, ist TStaticText ... weil zufällig die "Label"-Klasse "STATIC" heißt)

MarcRB75 27. Jun 2022 14:18

AW: Eigene Komponente X-beliebiges Aussehen
 
also das mit der Paintbox funktioniert sehr gut. Alle Zeichnungen oder sonstiges "schimmert durch" :-)

stahli 27. Jun 2022 14:54

AW: Eigene Komponente X-beliebiges Aussehen
 
Zitat:

Zitat von MarcRB75 (Beitrag 1507944)
Aber wie kann ich dann, wie Du mir zuvor geschrieben hast, die Linien/Punkte "Ausstanzen", so dass kein viereckiger Rahmen entsteht, wenn ich
die "Bogen-Komponte" auf ein Formular lege?

Könntest Du mir bitte sagen, wie das geht oder wie ich das machen muss?

Angenommen ich habe alle Punkte des Bogens und die der Punkte ermittelt, wie kann ich dann n diese Form "Ausstanzen", so dass ein schöner Rahmen drumherum entsteht? Könntest Du mir das bitte sagen?


1) Ausstanzen

Da ist m.E. genau die Frage. Du sagst, Du willst die Bogenkomponente "auf ein Formular legen". Bedeutet das, Du willst sie benutzen wie und neben einem Edit, Panel oder Button?
Oder willst Du sie nur auf der Fläche eines anderen Controls darstellen und benutzbar machen?

Wenn Du sie z.B. wie ein nicht-rechteckiges Panel benutzen willst, dann kannst Du Dir meinen zweiten Link im Beitrag #2 nochmal anschauen. Da werden dann einfach Teile des rechteckigen Controls weggeschnitten bzw. ausgestanzt.
Das Problem ist, dass Du "innerhalb" des Controls keine "Anfasser" positionieren kannst, bzw. damit dann nur eine Verkleinerung machbar wäre. Wenn Du die Anfasser weiter nach außen ziehen willst, wäre das nicht möglich, da das Control ja dort keinen Zugriff mehr auf sein Umfeld hat.
Das heißt, die Anfasser müssen dann immer von einer höheren Ebene (Designer oder Formular) bereitgestellt werden. In dessen Bereich kannst Du dann die Anfasser bewegen - auch außerhalb der Bogenkomponente.

Wenn Du keine Vermischung deiner Bogenkomponente mit anderen VCL-Controls brauchst und Du Dich auf eine individuelle Zeichenfläche beschränken kannst, dann kannst Du Dir das Beschneiden von VCL-Controls ersparen und einfach Deine Bogencontrols auf eine beliebige Zeichenfläche malen.


2) Transparenz

Die VCL unterstützt keine wirkliche Transparenz. Wie himitsu beschrieben hat malt ein Label z.B. einfach seinen Text auf die Zeichenfläche seines Parent. Also malt zuerst der Parent seine Zeichenfläche fertig (z.B. weiße Füllung) und dann malt das Label noch seinen Text darauf. Dadurch scheint das Label transparent zu sein.
Wenn der Parent sich aber neu malt (z.B. wegen einer Größenänderung) ist die Fläche wieder weiß und das Label muss seinen Text erneut zeichnen um wieder sichtbar zu sein.
Ein Label über die gesamte Formularbreite zu setzen und dabei andere Controls zu überdecken ist nicht möglich.
Mit einem Panel geht das, da ist dann aber keine echte Transparenz möglich.
Die VCL ist da also etwas eingeschränkt.

Diese "Pseudotransparenz" kannst Du für Dich natürlich nachbilden.
Du könntest Dein Hintergrundbild auf Deine Zeichenfläche kopieren und dann darauf Deine Bogencontrols zeichnen. Bei jeder Änderung musst Du dann natürlich wieder beides machen.
Je nachdem wie aufwändig diese Aktionen sind, könnte es sinnvoll sein, die neue "Gesamtbildberechnung" (Hintergrund + Bögen) in einen Thread auszulagern und erst das Ergebnis dann tatsächlich auf der Zeichenfläche darzustellen.
Das kann Flackern und/oder ein hängen der Anwendung vermeiden helfen.


Wenn Du ein wenig zu dem Thema stöbern willst, kannst Du Dich hier mal umschauen:
https://www.delphipraxis.net/175033-...-schlecht.html


3) VCL-Control oder eigenständige Zeichenfläche

Also die wichtigste Entscheidung ist wohl zunächst, ob Du mit einer bestimmten Zeichenfläche klar kommst, auf denen alle Deine Figuren bearbeitet und genutzt werden oder ob Du Deine Controls wie ein Edit oder Panel überall in einer Anwendung einsetzen willst...

MarcRB75 28. Jun 2022 09:13

AW: Eigene Komponente X-beliebiges Aussehen
 
Vielen Dank für Deine Antwort.

Ich verstehe das jetzt, mit dem Ausstanzen und dem "Anfasser". Dann ist das wohl doch keine so gute Idee.

Ich werde, wenn ich auf einen "Button" drücke, mir den Bogen und die Punkte erzeugen lassen. Das geht auch.
Naja... ich wollte das zwar "eleganter" lösen ... aber vielleicht kann man doch nicht alles so umsetzen, auch wenn man
es noch so gerne möchte.

Das mit der Transparenz spielt ja dann in diesem Fall auch keine Rolle mehr, weil der Bogen direkt erzeugt und sofort sichtbar ist.

Nochmal vielen Dank an Dich und die anderen, dass Ihr Euch solche Mühe für Eure Antworten gegeben habt.

stahli 28. Jun 2022 09:37

AW: Eigene Komponente X-beliebiges Aussehen
 
Gerne.

Eine andere Lösung könnte noch sein, dass Du einen Bogen mit einem Mausklick darauf selektieren kannst (wie in anderen Grafikprogrammen).
Das wäre intuitiv aber Du musst den Pfad für jeden Bogen in einer eigenen Region verwalten.

Quasi genau das, was Du mit dem Ausstanzen erreichen wolltest, aber "virtuell". Du merkst Dir verschiedene Regionen für Deine Bögen und prüfst bei einem Klick auf die Zeichenfläche, ob dabei eine Bogenregion erwischt wird. Die Regionen könntest Du sogar stapeln (die neueste immer zuerst prüfen und die älteste zuletzt), dann kannst Du sie sogar übereinander legen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:50 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