J'ai besoin de la forme de triangle propre, j'ai hérité mon formulaire de classe triangle TShape et remplacer la méthode de peinture. Tout fonctionne bien, mais j'ai besoin de déplacer ces formes avec la souris. J'ai défini la méthode pour chaque événement de gestion de forme onMouseDown. Déménagement travail aussi bien. Mais si deux formes se chevauchent (les formes sont en fait des rectangles avec des zones transparentes), que la surface transparente de la forme du dessus est sur une autre forme, alors la forme supérieure se déplace au lieu de la forme ci-dessous. C'est correct, c'est comme ça que Delphi fonctionne. Mais ce n'est pas intuitif pour l'utilisateur. Comment puis-je y parvenir? Est-il possible de ne pas supprimer l'événement de la file d'attente des événements et l'envoyer aux formes sous-jacentes, si oui, ce serait simple?Delphi - se déplaçant chevauchant TShapes
Répondre
Vérifiez si le clic de la souris est dans la zone du triangle avant de commencer à déplacer la forme. Cela nécessite un peu de maths, mais vous pouvez aussi abuser de la fonction WinAPI PtInRegion en créant une région temporaire, comme suit:
function PtInPolygon(const Pt: TPoint; const Points: array of TPoint): Boolean;
var
Region: HRGN;
begin
Region := CreatePolygonRgn(Points[0], Length(Points), WINDING);
try
Result := PtInRegion(Region, Pt.X, Pt.Y);
finally
DeleteObject(Region);
end;
end;
procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
StartMove: Boolean;
begin
StartMove := PtInPolygon(Point(X, Y), [Point(100, 0), Point(200, 200),
Point(0, 200)]);
...
A « refonte simple échantillon » par mon commentaire suit.
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
const
NUM_TRIANGLES = 10;
COLORS: array[0..12] of integer = (clRed, clGreen, clBlue, clYellow, clFuchsia,
clLime, clGray, clSilver, clBlack, clMaroon, clNavy, clSkyBlue, clMoneyGreen);
type
TTriangle = record
X, Y: integer; // bottom-left corner
Base, Height: integer;
Color: TColor;
end;
TTriangles = array[0..NUM_TRIANGLES - 1] of TTriangle;
TForm4 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
FTriangles: TTriangles;
FDragOffset: TPoint;
FTriangleActive: boolean;
function GetTriangleAt(AX, AY: Integer): Integer;
function IsMouseDown: boolean;
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
uses Math;
{$R *.dfm}
procedure TForm4.FormCreate(Sender: TObject);
var
i: Integer;
begin
FTriangleActive := false;
Randomize;
for i := 0 to NUM_TRIANGLES - 1 do
with FTriangles[i] do
begin
base := 40 + Random(80);
height := 40 + Random(40);
X := Random(ClientWidth - base);
Y := height + Random(ClientHeight - height);
Color := RandomFrom(COLORS);
end;
end;
procedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
TriangleIndex: integer;
TempTriangle: TTriangle;
i: Integer;
begin
TriangleIndex := GetTriangleAt(X, Y);
if TriangleIndex <> -1 then
begin
FDragOffset.X := X - FTriangles[TriangleIndex].X;
FDragOffset.Y := Y - FTriangles[TriangleIndex].Y;
TempTriangle := FTriangles[TriangleIndex];
for i := TriangleIndex to NUM_TRIANGLES - 2 do
FTriangles[i] := FTriangles[i + 1];
FTriangles[NUM_TRIANGLES - 1] := TempTriangle;
Invalidate;
end;
FTriangleActive := TriangleIndex <> -1;
end;
function TForm4.IsMouseDown: boolean;
begin
result := GetKeyState(VK_LBUTTON) and $8000 <> 0;
end;
procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if IsMouseDown and FTriangleActive then
begin
FTriangles[high(FTriangles)].X := X - FDragOffset.X;
FTriangles[high(FTriangles)].Y := Y - FDragOffset.Y;
Invalidate;
end;
end;
procedure TForm4.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FTriangleActive := false;
end;
procedure TForm4.FormPaint(Sender: TObject);
var
i: Integer;
Vertices: array of TPoint;
begin
SetLength(Vertices, 3);
for i := 0 to NUM_TRIANGLES - 1 do
with FTriangles[i] do
begin
Canvas.Brush.Color := Color;
Vertices[0] := Point(X, Y);
Vertices[1] := Point(X + Base, Y);
Vertices[2] := Point(X + Base div 2, Y - Height);
Canvas.Polygon(Vertices);
end;
end;
function TForm4.GetTriangleAt(AX, AY: Integer): Integer;
var
i: Integer;
begin
result := -1;
for i := NUM_TRIANGLES - 1 downto 0 do
with FTriangles[i] do
if InRange(AY, Y - Height, Y) and
InRange(AX, round(X + (Base/2) * (Y - AY)/Height),
round(X + Base - (Base/2) * (Y - AY)/Height)) then
Exit(i);
end;
end.
Ne pas oublier de mettre DoubleBuffered
à true
de la forme.
échantillon Compilé demo: http://privat.rejbrand.se/MovingTriangles.exe
Je sais que cela fait longtemps que vous n'avez pas posté cette réponse, mais peut-être pourriez-vous expliquer votre 'InRange' pour le calcul min/max de' AX'? ce genre de souffle dans mon esprit, je n'ai pas fait de maths ou de géométrie depuis longtemps. Après avoir regardé plus, je pense que j'ai commencé à comprendre. Vous réduisez la moitié du plus petit triangle potentiel 'Base' avec' AY' donné en divisant 'Y-AY' (petit triangle) par' Height'? Mais comment savez-vous que couper cela de deux côtés signifie que «X» est dans cette gamme? J'ai fait du dessin et c'est vrai et maintenant je le vois, mais ce n'est pas aussi clair quand on le fait par programmation – Raith
- 1. Cacao se déplaçant chevauchant NSViews
- 2. liens se chevauchant
- 3. Durées d'appel se chevauchant
- 4. UICollectionViewCellules se chevauchant
- 5. images positionnées absolues se déplaçant
- 6. GridSplitter se déplaçant très lentement
- 7. Inno Setup PageDescriptionLabel se chevauchant
- 8. Les requêtes MySQL se chevauchant
- 9. Colonnes se chevauchant avec IE7
- 10. Divs ronds se chevauchant parfaitement
- 11. L'image-objet Cocos2d scintille en se déplaçant
- 12. Plusieurs GLSurfaceView se déplaçant en même temps
- 13. Bouton se déplaçant hors de vue - android
- 14. Apache se déplaçant vers des hôtes virtuels
- 15. Image se déplaçant vers le haut
- 16. Pacman Ghost se déplaçant en android
- 17. QGraphicsItem se déplaçant le long du chemin
- 18. Swing indéterminé JProgressBar se déplaçant trop vite
- 19. div frontière se chevauchant bouton, comment l'inverser?
- 20. HTML index z se chevauchant maintenant
- 21. Sélection des plages horaires se chevauchant
- 22. Java: Comment voir l'icône se chevauchant
- 23. Expressions régulières se chevauchant partie II
- 24. GCCalendar chevauchant
- 25. Delphi "se souvient" de l'ancienne dépendance DCU
- 26. SFML Sprite se déplaçant violemment au 2ème tick
- 27. TemplateSyntaxError tout en se déplaçant de django 1.1 à 1.2.1
- 28. Silverlight spécifique Image se déplaçant vers la droite
- 29. Animer une ligne se déplaçant sur une toile
- 30. problème tout en se déplaçant AVD à un autre endroit
animations Dessin par le déplacement des contrôles sur un formulaire (même les contrôles graphiques) est mauvaise. Si j'étais vous, je stockerais la scène dans une structure de données personnalisée, puis dessinerais le formulaire complètement manuellement. Ensuite, aucune restriction ne vous retient - vous pouvez implémenter n'importe quelle interface de souris. –