用鼠标(FMX,Win32)移动TRectangle

时间:2018-12-20 05:06:39

标签: firemonkey c++builder

我有一个FMX表单,上面有一个与客户端对齐的TLayout。在TLayout上,我有一个TRectangle。我可以在按钮单击事件中使用以下代码轻松移动TRectangle:

 Rectangle1->Position->X = Rectangle1->Position->X + 10;

有没有一种干净的方法可以用鼠标执行此操作(移动矩形)?就像单击“矩形”并将其移动到新位置一样?我只是在玩游戏,试图制作一些绘图程序来学习。...

使用C ++ Builder 10.2 25.0.29899.2631版并在Win32中构建。

更新:我采用了Hans的方法,并最终使其很好地工作。我在下面添加了完整的代码作为答案。是的!

2 个答案:

答案 0 :(得分:1)

拖动组件的一种方法是在鼠标向下移动时存储鼠标位置和控件位置之间的偏移量,然后使用该偏移量来计算鼠标移动事件中控件的位置。

在半伪代码中,它看起来像这样:

Add the following to your TForm class:

fMouseIsDown: boolean;
fMouseDownOffset: TPointF;

procedure OnRectangleMouseDown(X,Y)
begin
  fMouseIsDown := true;
  fMouseDownOffset := PointF(Rectangle.Position.X-X, Rectangle.Position.Y-Y)
end;

procedure OnRectangleMouseMove(X,Y)
begin
  if fMouseIsDown then
  begin
    Rectangle.Position.X := X+fMouseDownOffset.X;
    Rectangle.Position.Y := Y+fMouseDownOffset.Y;
  end;
end;

procedure OnRectangleMouseUp(X,Y);
begin
  fMouseIsDown := false;
end;

答案 1 :(得分:0)

这是在Win32中左键单击并在FMX表单上移动TRectangle所需的完整代码(尚未在移动设备上尝试过)。只需创建一个新的FireMonkey多设备应用程序,然后在其上放置一个TRectangle和一个TButton。

要添加到表单的类声明中的代码(在class TForm1 : public TForm {下的.h文件中):

bool fMouseIsDown; // gets set to TRUE when left mouse click on the rectangle
TPointF fMousePosGlobal; // this is the mouses position relative to the screen
TPointF fMousePosForm; // this is the mouse pos relative to the form
TPointF captionOffset; // this is a small offset necessary since the form's TOP and LEFT are outside of form's client area due to caption bar and left edge of form
TPointF fMouseInRectAtClick; // this is the mouse pos relative to the rectangle (top left of rectangle is 0,0)

要添加到矩形的Rectangle1MouseDown事件中的代码:

if (Button == 0) {  // 0 for left mb, 1 for right mb
fMouseIsDown = true;  
fMouseInRectAtClick.X = X;  //mouse pos with respect to rectangle at time of click
fMouseInRectAtClick.Y = Y;
}

要添加到矩形的Rectangle1MouseMove事件中的代码(也添加到表单的FormMouseMove中,或者有时您在快速拖动时丢失了矩形):

fMousePosGlobal = Screen->MousePos(); //mouse global pos
fMousePosForm.X = fMousePosGlobal.X - Form1->Left;  // mouse pos relative to the form
fMousePosForm.Y = fMousePosGlobal.Y - Form1->Top;
if (fMouseIsDown) {
Form1->Rectangle1->Position->X =  fMousePosForm.X - captionOffset.X - fMouseInRectAtClick.X;
Form1->Rectangle1->Position->Y = fMousePosForm.Y - captionOffset.Y - fMouseInRectAtClick.Y;
}

要添加到Rectangle1MouseUp事件中的代码:

fMouseIsDown = false;  // add this to the form's MouseUp too in case you "lose" the rectangle on a drag.  That only happened when i forget to set the offsets.

要添加到Button的Button1Click事件中的代码:

captionOffset.X = 8.0; // this accounts for the width of the form left edge
captionOffset.Y = 30.0; // this accounts for the height of the form caption
// if you don't add this your "drag point" on the rectangle will jump as soon as you start the drag.

感谢汉斯的出发方向!

此外,我注意到在其他控件之间移动时拖动并不顺畅。如果这困扰您,则需要将其他控件设置为“ HitTest”,使它们忽略它。如果要在移动鼠标和矩形时查看所有TPointF坐标,请添加TEdit框-在尝试找出坐标时会很有帮助。