Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   MouseEnter/Leave bei Pie (https://www.delphipraxis.net/174181-mouseenter-leave-bei-pie.html)

Nic2012 8. Apr 2013 15:42

MouseEnter/Leave bei Pie
 
Hallo,
ich möchte eine Komponente implem., das einen Kreis mit gleichgroßen (Kuchen-) Stücken darstellen soll. Wird u.a. verwendet als quasi rundes Menü. Wenn man mit der Mouse über einen der Sektoren fährt, soll z.B. die BackgroundColor des Pie-Stücks neu gesetzt werden und gerendert werden. Das Zeichnen ist nicht das Problem, aber wie bekomme ich heraus ob und über welchem Sektor die Mouse sich befindet ?

Verwende ausschl. D7.

Gruß,
Nic

Bummi 8. Apr 2013 15:45

AW: MouseEnter/Leave bei Pie
 
Du kennst von Deinen Segmenten die Start und Endwinkel, über Mittelpunkt zu Mauskoordinaten kannst Du den Winkel berechnen und kennst somit das Segment.

Bjoerk 8. Apr 2013 15:47

AW: MouseEnter/Leave bei Pie
 
Schau dir eventl. mal die Shapes an, der Quellcode der TShape Klasse ist in der ExtCtrls.pas. Kannst du wahrscheinlich analog machen.

Bummi 8. Apr 2013 16:27

AW: MouseEnter/Leave bei Pie
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ein Vorschlag zur Umsetzung

Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type

  TPie = Record
    StartAngle, EndAngle: Double;
    Color, HighLightColor: TColor;
  End;

  TPieArray = Array of TPie;

  TForm2 = class(TForm)
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure PaintBox1MouseLeave(Sender: TObject);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  private
    FPieArray: TPieArray;
    FMA: Double;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

uses Math;
{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
  SetLength(FPieArray, 4);
  FPieArray[0].StartAngle := 0;
  FPieArray[0].EndAngle := 90;
  FPieArray[0].Color := clBlue;
  FPieArray[0].HighLightColor := clNavy;

  FPieArray[1].StartAngle := 90;
  FPieArray[1].EndAngle := 180;
  FPieArray[1].Color := clRed;
  FPieArray[1].HighLightColor := clMaroon;

  FPieArray[2].StartAngle := 180;
  FPieArray[2].EndAngle := 270;
  FPieArray[2].Color := clLime;
  FPieArray[2].HighLightColor := clGreen;

  FPieArray[3].StartAngle := 270;
  FPieArray[3].EndAngle := 360;
  FPieArray[3].Color := clSilver;
  FPieArray[3].HighLightColor := clGray;

end;

procedure TForm2.PaintBox1MouseLeave(Sender: TObject);
begin
  FMA := -1;
end;

procedure TForm2.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  cx, cy: Integer;
begin
  cx := PaintBox1.Width div 2;
  cy := PaintBox1.Height div 2;
  if SQRT( POWER(Y - cy,2) + POWER(Y - cy,2)) < cy then
     FMA := Round((360 - RadToDeg(ArcTan2(Y - cy, X - cx)))) mod 360
  else FMA := -1;
  PaintBox1.invalidate;
end;

procedure TForm2.PaintBox1Paint(Sender: TObject);
var
  i: Integer;
  DC: HDC;
  X, Y: Integer;

begin
  X := PaintBox1.Width div 2;
  Y := PaintBox1.Height div 2;
  for i := 0 to High(FPieArray) do
  begin
    if (FMA > FPieArray[i].StartAngle) and (FMA < FPieArray[i].EndAngle) then
      PaintBox1.Canvas.Brush.Color := FPieArray[i].HighLightColor
    else
      PaintBox1.Canvas.Brush.Color := FPieArray[i].Color;
    DC := PaintBox1.Canvas.Handle;
    BeginPath(DC);
    MoveToEx(DC, X, Y, nil);
    AngleArc(DC, X, Y, X, FPieArray[i].StartAngle, FPieArray[i].EndAngle - FPieArray[i].StartAngle);
    LineTo(DC, X, Y);
    EndPath(DC);
    StrokeAndFillPath(DC);
  end;

end;

end.

Nic2012 11. Apr 2013 12:19

AW: MouseEnter/Leave bei Pie
 
Besten Dank, aber in das MouseLeave geht der Code bei D7 nicht rein.
Ich habe versucht die PaintBox abzuleiten um MouseLeave/Enter published zu bekommen. Im FormCreate versuche ich auf die abgeleitete PaintBox zu casten, erhalte aber eine ungültige Typumwandlung:
Code:
type

  TPie = Record
    StartAngle, EndAngle: Double;
  ...
  End;
  ...
  TPaintBoxEx = class(TPaintBox)
  private
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    procedure CMMouseEnter (var mMsg : TMessage); message CM_MouseEnter;
    procedure CMMouseLeave (var mMsg : TMessage); message CM_MouseLeave;
  published
    property OnMouseEnter: TNotifyEvent READ FOnMouseEnter WRITE FOnMouseEnter;
    property OnMouseLeave: TNotifyEvent READ FOnMouseLeave WRITE FOnMouseLeave;
  end;

  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    ...
  private
    FPieArray: TPieArray;
    FMA: Double;
  end;

...

implementation

{$R *.dfm}

procedure TPaintBoxEx.CMMouseEnter(var mMsg : TMessage);
begin
  if Assigned(FOnMouseEnter) then FOnMouseEnter(Self);
end;

procedure TPaintBoxEx.CMMouseLeave(var mMsg : TMessage);
begin
  if Assigned(FOnMouseLeave) then FOnMouseLeave(Self);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DoubleBuffered := true;

  SetLength(FPieArray, 4);
  ...

  (PaintBox1 as TPaintBoxEx).FOnMouseLeave := PaintBox1MouseLeave;

end;

procedure TForm1.PaintBox1MouseLeave(Sender: TObject);
begin
  FMA := -1;
end;

Bummi 11. Apr 2013 12:30

AW: MouseEnter/Leave bei Pie
 
Lass das EX weg, einfach

Delphi-Quellcode:
TPaintBox = class(TPaintBox)
...
end;

....
....

procedure TPaintBox.CMMouseEnter(var mMsg : TMessage);
.....
das EX würdest Du anhängen wenn Du eine abgeleitetes Komponente erstellen,registrieren und verwenden würdest.

Eine andere Möglichkeit wäre, keine Paintbox auf dem Form zu haben, eine FMyPaintBox:TPaintboxEX zu deklarieren und diese im OnCreate zu erzeugen.


BTW PaintBoxEx.FOnMouseLeave:= geht nicht, Du müsstest die Property verwenden PaintBoxEx.OnMouseLeave:=

Nic2012 11. Apr 2013 19:53

AW: MouseEnter/Leave bei Pie
 
Verstehe ich nicht, sorry. Wie kann ich Dein Beispiel so erweitern, das die vorhandene PaintBox1 um den Eventhandler "CMMouseLeave" erweitert wird ?

Wenn ich in meinem Beispiel das Ex weglasse bekomme ich "Typ TPaintBox" ist nicht vollständig definiert.

Bummi 11. Apr 2013 23:23

AW: MouseEnter/Leave bei Pie
 
Ich weiß nicht wo genau es hängt, vielleicht hilft hilft Dir diese Minibeispiel weiter

Delphi-Quellcode:
unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
 TPaintBox = class(ExtCtrls.TPaintBox)
  private
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    procedure CMMouseEnter (var mMsg : TMessage); message CM_MouseEnter;
    procedure CMMouseLeave (var mMsg : TMessage); message CM_MouseLeave;
  published
    property OnMouseEnter: TNotifyEvent READ FOnMouseEnter WRITE FOnMouseEnter;
    property OnMouseLeave: TNotifyEvent READ FOnMouseLeave WRITE FOnMouseLeave;
  end;

  TForm6 = class(TForm)
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    procedure MyMouseEnter(Sender: TObject);
    procedure MyMouseLeave(Sender: TObject);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

{ TPaintBox }

procedure TPaintBox.CMMouseEnter(var mMsg: TMessage);
begin
  inherited;
  if Assigned(OnMouseEnter) then OnMouseEnter(self);

end;

procedure TPaintBox.CMMouseLeave(var mMsg: TMessage);
begin
  if Assigned(OnMouseLeave) then OnMouseLeave(self);
end;

procedure TForm6.MyMouseEnter(Sender: TObject);
begin
   With TPaintbox(Sender) do
    begin
      Tag := clLime;
      Invalidate;
    end;
end;
procedure TForm6.MyMouseLeave(Sender: TObject);
begin
   With TPaintbox(Sender) do
    begin
      Tag := clRed;
      Invalidate;
    end;

end;

procedure TForm6.PaintBox1Paint(Sender: TObject);// ist auch Paintbox2 zugewiesen
begin
  With TPaintBox(Sender).Canvas do
    begin
      Brush.Color := TPaintBox(Sender).Tag;
      Fillrect(TPaintBox(Sender).ClientRect);
    end;
end;

procedure TForm6.FormCreate(Sender: TObject);
begin
 Paintbox1.OnMouseEnter := MyMouseEnter;
 Paintbox1.OnMouseLeave := MyMouseLeave;
 Paintbox2.OnMouseEnter := MyMouseEnter;
 Paintbox2.OnMouseLeave := MyMouseLeave;

end;

end.

Nic2012 15. Apr 2013 15:29

AW: MouseEnter/Leave bei Pie
 
Prima, Bummi hast mir sehr geholfen :)
Zitat:

"Typ TPaintBox" ist nicht vollständig definiert.
ExtCtrls vor PaintBox hat gefehlt und war die Ursache.
Nochmals besten Dank.

Bummi 15. Apr 2013 15:36

AW: MouseEnter/Leave bei Pie
 
:thumb:


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