переместить TRectangle с помощью мыши (FMX, Win32) - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть форма FMX с привязкой TLayout к клиенту.На TLayout у меня есть TRectangle.Я могу легко переместить TRectangle с помощью следующего кода в событии нажатия кнопки:

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

Есть ли для меня чистый способ сделать это (переместить прямоугольник) с помощью мыши?Как нажать на прямоугольник и переместить его в новое место?Я просто пытаюсь создать небольшую программу для рисования, чтобы научиться ....

Использование C ++ Builder 10.2 версии 25.0.29899.2631 и сборка в Win32.

ОБНОВЛЕНИЕ: Я взялГанс подходит и в итоге заставляет его работать хорошо.Я добавил полный код в качестве ответа ниже.Ура!

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Вот полный код, необходимый для щелчка левой кнопкой мыши и перемещения прямоугольника TRECT на форме FMX в Win32 (еще не пробовал его на мобильном устройстве).Просто создайте новое приложение для нескольких устройств FireMonkey и поместите в него TRectangle и TButton.

Код для добавления к объявлению класса форм (в файле .h чуть ниже class TForm1 : public TForm {):

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.

Код для добавления к событию 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» в ложь, чтобы они игнорировали это.Добавьте поля TEdit, если вы хотите видеть все координаты TPointF при перемещении мыши и прямоугольника - это помогает при попытке выяснить координаты.

0 голосов
/ 20 декабря 2018

Способ перетаскивания компонентов заключается в сохранении смещения между положением мыши и положением элемента управления при нажатии мыши, а затем с помощью этого смещения вычисляется положение элемента управления в событии перемещения мыши.

В полу-pseudo код это будет выглядеть так:

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;
...