![]() |
Eigenes Shape anklickbar machen
Hallo Zusammen,
ich habe ein für mich mächtiges Problem zu lösen und bitte um Hilfe. Es sollen Bogensegmente gezeichnet werden die Anklickbar sind wie etwa ein Button. Mit Bogensegmente meine ich, wenn man eine CD durch die Mitte in vier gleiche stücke schneiden würde, hätte man vier 90-Grad Bögen. Ich möchte gerne um 360-Grad mehrere Bogensegmente mit unterschiedlichen Öffnungswinkel aneinanderreihen. Jedes Bogensegment soll eine Farbe bekommen und soll einen Event OnClick haben. Das ist die komplette Anforderung. Kennt jemand so eine Komponente, oder noch besser gibt es irgendwo eine Anleitung wie aus einer gezeichnete, geschlossenen Fläche aus Linien und Bögen eine Schaltfläche erzeugt werden kann? Die Komponente selbst zu erzeugen würde mir sehr zusagen, doch leider habe ich mich damit noch nicht beschäftigt und hab keine Ahnung wo ich Ansetzen muss, und auch leider keine Ahnung nach was ich suchen sollte. Ich bin sicher im Forum wird der eine oder andere Hinweis dabei sein. Die Komponenten muss auch gar nicht auf der Delphi Komponentenpalette erscheinen. Ich benötige sie nur in meiner Anwendung. Gruß Kostas |
Re: Eigenes Shape anklickbar machen
Du könntest das "OnMouseDown"-Event des TShape verwenden und mit den Variablen X und Y der Funktion herausfinden, an welche Stelle des Shapes der Klick ausgeführt wurde. Dann könntest du prüfen, ob diese Punkte innerhalb eines bestimmten Halbkreises liegen.
|
Re: Eigenes Shape anklickbar machen
Zitat:
sorry, ich habe im Titel Shape erwähnt. Ich habe noch kein Shape. Ich stehe also noch bei 0,0. Das OnMouseDown und Koordinaten abfragen scheint etwas heftig zu sein. Ich meinte eigentlich eher die Technik wie ein Button funktioniert. Es gibt ja Komponenten die aus einer bmp Maske mit einer beliebigen Kontur ein Button erstellen. Die gesamte Fläche innerhalb der Kontur ist dann anklickbar. Diese Komponente kann ich nicht verwenden da der Bogen variabel im Öffnungswinkel sein soll. Die Kontur des Bogens kann ich recht einfach mit etwas Geometrie Zeichnen. Doch per Mathematischen weg herausfinden ob die aktuelle Mauskoordinate innerhalb des Bogens ist, ist sehr schwer. Gibt es wirklich keine andere Möglichkeit die Bogenfläche zu erkennen? Mann könnte mit dem Gedanken spielen die Anklickfläche Rechteckig zu halten, das ist in meinem Fall auch nicht anwendbar da die Bogensegmente auf 360Grad aneinandergereiht werden sollen. Welche Basiskomponente könnte für mein Vorhaben am besten sein, ist das Shape oder Button? Gruß Kostas |
Re: Eigenes Shape anklickbar machen
Zitat:
Eine andere Idee habe ich spontan nicht... :? //Edit: Gute Frage, nächste Frage... :stupid: |
Re: Eigenes Shape anklickbar machen
Hallo Kostas,
wenn du in die Abgründe des Windows-API hinabsteigen möchtest, kannst du dein Problem vielleicht lösen. Ein Tortenstück läßt sich mit dem Befehl ![]() ![]() ![]() ![]()
Delphi-Quellcode:
Für das Zeichnen der Tortenstücke hast du nun mehrere Möglichkeiten. Du kannst sie ganz normal mit den TCanvas-Methoden zeichnen oder mit
var
Region : HRGN; begin BeginPath(Canvas.Handle); Pie(Canvas.Handle, X1, Y1, X2, Y2, X3, Y3, X4, Y4); EndPath(Canvas.Handle); Region := PathToRegion(Canvas.Handle); end; ![]() ![]()
Delphi-Quellcode:
Zum Schluß solltest du nicht vergessen, die Region mit
if PtInRegion(Region, X, Y) then
// Punkt ist innerhalb des Tortenstücks else // Punkt ist außerhalb ![]() Gruß Hawkeye |
Re: Eigenes Shape anklickbar machen
Hallo Hawkeye219,
das mit dem BeginPath und EndPath klingt sehr vielversprechend. Pie hatte ich mir schon angeschaut. Es passt noch nicht so ganz denn, Pie zeichnet eine komplettes Tortenstück ab Zentrum. Ich habe jedoch ein "Loch" in der Mitte. Wie eine CD eben, und benötige nur ein Teilstück. Also "Bogen aussen, gerade, Bogen innen, gerade". Aber ich denke die Richtung ist schon mal sehr gut. Besten Dank und schöne Grüße Kostas |
Re: Eigenes Shape anklickbar machen
Also wenn ich das richtig verstanden hab, malst du deinen Kuchen mit TCanvas (wahrscheinlich auf eine Paintbox).
Jetzt kannst du doch im OnMouseMoveEvent der Paintbox mit etwas Mathematik den Winkel zwischen dem Vektor der die x- Achse beschreibt (1|0) und dem Vektor von dem Mittelpunkt des Kuchens bis zur Mauskoordinate (MausX-MX|MausY-My) berechnen. Und mit etwas anderer Mathematik kannst du auch berechnen wieweit der Mauszeiger von dem Mittelpunkt entfernt ist. Wenn du jetzt weisst von welchem Winkel bis zu welchem Winkel ein Kuchenstück recht (bspw. 0° bis 90°) kannst du schonal prüfen ob der WInkel des Mauscursors passt. Jetzt guckst du dir die länge an. DU weisst den radius des Kuchens, und auch der Radius des inneren Kreises dürfte bekannt sein. Jetzt schaust du ob die ENtfernun Mittelpunkt-Mauscursor genau zwischen den beiden Radien liegt. Diese Überprüfung führst du mit jedem Teilstück durch. Wenn du erkannt hast auf welchem Kuchensstück du bist, kannst du es ja auch irgendwie farbig hervorgehoben zeichnen, und auf einen Klick zu reagieren sollte auch kein Problem sein. SO würd ich da jedenfalls rangehen. Dürfte aber etwas Arbeit sein. |
Re: Eigenes Shape anklickbar machen
Hallo Zusammen,
also ich habe jetzt mal den Bogen fertig. Über zwei TrackBars kann der Öffnungswinkel und die Position von 0-360 Grad bestimmt werden. Wenn mann genauer hinschaut, sieht mann das durch Rundungsfehler wegen integer Pixel-Koordinate die Schnittpunkte nicht genau auftreffen. Vermutlich wird genau dass das Problem sein warum keine Region erzeugt erzeugt werden kann. Denn genau das ist mein Problem, es wird keine Region erzeugt. Lauf Doku können zwischen BeginPath und EndPath mehrere Zeichenwerkzeuge verwendet werden. Und wie könnte ich bitte den Bogen mit Farbe füllen? Gruß Kostas
Delphi-Quellcode:
var
offset,p1,p2,p3,p4,s1,e1,s2,e2:TPoint; R1,R2:integer; Alpha,Alpha2:real; Region : HRGN; begin //Zentrum des Bogens offset.x:=300; offset.y:=300; R1:=200; //Äußerer Bogen R2:=140; //Innerer Bogen //Eckpunkt links-oben der Äußeren Ellipse p1.x := offset.x - (R1 div 2); p1.y := offset.y - (R1 div 2); //Eckpunkt rechts-unten der Äußeren Ellipse p2.x := offset.x + (R1 div 2); p2.y := offset.y + (R1 div 2); //Eckpunkt links-oben der Inneren Ellipse p3.x := offset.x - (R2 div 2); p3.y := offset.y - (R2 div 2); //Eckpunkt rechts-unten der Inneren Ellipse p4.x := offset.x + (R2 div 2); p4.y := offset.y + (R2 div 2); Alpha := DegToRad(TrackBar2.position); //Startwinkel Alpha2 := DegToRad(TrackBar2.position + TrackBar1.position); //Öffnungswinkel //Startpunkt der Schnittpunktlinie Bogen außen s1.x := offset.x + Round((r1 div 2) * (cos(Alpha))); s1.y := offset.y + Round((r1 div 2) * (sin(Alpha))); //Endpunkt der Schnittpunktlinie Bogen außen e1.x := offset.x + Round((r1 div 2) * (cos(Alpha2))); e1.y := offset.y + Round((r1 div 2) * (sin(Alpha2))); //Startpunkt der Schnittpunktlinie Bogen innen s2.x := offset.x + Round((r2 div 2) * (cos(Alpha))); s2.y := offset.y + Round((r2 div 2) * (sin(Alpha))); //Endpunkt der Schnittpunktlinie Bogen innen e2.x := offset.x + Round((r2 div 2) * (cos(Alpha2))); e2.y := offset.y + Round((r2 div 2) * (sin(Alpha2))); //canvas refreshen canvas.FillRect(canvas.ClipRect); // BeginPath(Canvas.Handle); Arc(Canvas.Handle, p1.x, p1.y, p2.x, p2.y, e1.x, e1.y, s1.x, s1.y); //Bogen außen Arc(Canvas.Handle, p3.x, p3.y, p4.x, p4.y, e2.x, e2.y, s2.x, s2.y); //Bogen innen canvas.MoveTo(s1.x,s1.y); canvas.LineTo(s2.x,s2.y); //Verbindungslinie 1 zwischen den Bögen canvas.MoveTo(e1.x,e1.y); canvas.LineTo(e2.x,e2.y);//Verbindungslinie 2 zwischen den Bögen // EndPath(Canvas.Handle); // FillPath(Canvas.Handle); // Region := PathToRegion(Canvas.Handle); // // if (Region<>0) then // begin // ShowMessage('gültige Region'); // DeleteObject(Region); // end;{if} Edit: Ich denke mittlerweile ist das eine Frage für Multimedia gewortden. Da ich den Beitrag selbt nicht verschieben kann, werde ich die Frage Region... neu erstellen. Ich hoffe das ist so in Ordnung. |
Re: Eigenes Shape anklickbar machen
So, jetzt wird der Bogen gezeichnet, und ist innerhalb der Region anklickbar.
Gruß Kostas
Delphi-Quellcode:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); begin if PtInRegion(Region, X, Y) then bsm('gefunden'); end;
Delphi-Quellcode:
procedure TForm1.Bogen;
var offset,s:TPoint; R1,R2:integer; Alpha:real; FillColor:TBrush; begin //Zentrum des Bogens offset.x:=300; offset.y:=300; R1:=200; //Äußerer Bogen R2:=140; //Innerer Bogen Alpha := DegToRad(TrackBar2.position); //Startwinkel //Startpunkt der Schnittpunktlinie Bogen innen s.x := offset.x + Round((r2 div 2) * (cos(Alpha))); s.y := offset.y + Round((r2 div 2) * (sin(Alpha))); canvas.brush.Color:=clWhite; canvas.FillRect(canvas.ClipRect); Canvas.brush.Color:=clRed; BeginPath(Canvas.Handle); MoveToEx(Canvas.Handle, s.x, s.y, nil); AngleArc(Canvas.Handle, offset.x, offset.y, r1 div 2, -TrackBar2.Position, -TrackBar1.Position); AngleArc(Canvas.Handle, offset.x, offset.y, r2 div 2, -(TrackBar2.Position + TrackBar1.Position), TrackBar1.Position); EndPath(Canvas.Handle); Region := PathToRegion(Canvas.Handle); PaintRgn(Canvas.Handle, Region); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:21 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