AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eigenes Shape anklickbar machen

Ein Thema von Kostas · begonnen am 26. Jan 2007 · letzter Beitrag vom 28. Jan 2007
Antwort Antwort
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Eigenes Shape anklickbar machen

  Alt 26. Jan 2007, 23:27
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
  Mit Zitat antworten Zitat
Daniel G
(Gast)

n/a Beiträge
 
#2

Re: Eigenes Shape anklickbar machen

  Alt 27. Jan 2007, 09:33
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.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

Re: Eigenes Shape anklickbar machen

  Alt 27. Jan 2007, 20:48
Zitat von Daniel G:
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.
Hallo Daniel G,

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
  Mit Zitat antworten Zitat
Daniel G
(Gast)

n/a Beiträge
 
#4

Re: Eigenes Shape anklickbar machen

  Alt 27. Jan 2007, 20:53
Zitat von Kostas:
Gibt es wirklich keine andere Möglichkeit die Bogenfläche zu erkennen?
Wenn die Farbe immer eine andere ist, könntest du das über diesen Weg versuchen. Sprich', du müsstest gucken, ob die Farbe unter dem Mauszeiger mit Farbe X übereinstimmt.

Eine andere Idee habe ich spontan nicht...

//Edit:
Gute Frage, nächste Frage...
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Eigenes Shape anklickbar machen

  Alt 27. Jan 2007, 22:50
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-Referenz durchsuchenTCanvas.Pie zeichnen, der wiederum die Windows-API-Routine Pie() aufruft. Wenn man den Aufruf dieser Routine mit MSDN-Library durchsuchenBeginPath und MSDN-Library durchsuchenEndPath klammert, dann werden die Zeichenoperationen intern nur gespeichert und nicht auf dem Ausgabegerät ausgegeben. Mit MSDN-Library durchsuchenPathToRegion kann man sie abrufen und in eine Region umwandeln:

Delphi-Quellcode:
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;
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 MSDN-Library durchsuchenFillRegion die soeben ermittelte Region füllen. Die Abfrage, ob ein gegebener Punkt in der Region liegt, läßt sich mit MSDN-Library durchsuchenPtInRegion durchführen:

Delphi-Quellcode:
if PtInRegion(Region, X, Y) then
  // Punkt ist innerhalb des Tortenstücks
else
  // Punkt ist außerhalb
Zum Schluß solltest du nicht vergessen, die Region mit MSDN-Library durchsuchenDeleteObject wieder freizugeben.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

Re: Eigenes Shape anklickbar machen

  Alt 28. Jan 2007, 10:32
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
  Mit Zitat antworten Zitat
Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#7

Re: Eigenes Shape anklickbar machen

  Alt 28. Jan 2007, 11:00
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.
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

Re: Eigenes Shape anklickbar machen

  Alt 28. Jan 2007, 16:21
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.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

Re: Eigenes Shape anklickbar machen

  Alt 28. Jan 2007, 23:06
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;
  Mit Zitat antworten Zitat
Antwort Antwort


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 01:00 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