Я пытаюсь расширить код этого от использования одного TRectangle до использования нескольких прямоугольников, которые можно добавить во время выполнения.В этом примере код для щелчка и перетаскивания применяется только к этому одному TRectangle Rectangle1
.Мне нужно сделать его более общим, чтобы оно работало с любым прямоугольником, который я добавляю в форму (прямоугольники не появятся во время разработки).Я нашел этот код для создания пользовательского класса , и он отлично работает для создания новых прямоугольников.Я могу назначить методы, которые запускаются, когда на них нажимают, но я думаю, что это неправильный путь, чтобы идти вниз из-за того, что это отдельный класс от TForm1
... и многие из точек данных, которые мне нужны для работы моего кода, взяты изTForm1
(положения и т.
Не знаю, с чего начать ... но сначала я думаю, что мне нужно знать, как создать массив элементов управления, к которым можно получить доступ, примерно так:
rectangles[i]->Position->X = ...
И затем иметь событиятот огонь, когда щелкают прямоугольники, который может воздействовать на этот i-й прямоугольник:
void __fastcall TForm1::rectsMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, float X, float Y){
rectangles[i]->Position->X = ....
rectangles[i]->Position->Y = .....
}
ОБНОВЛЕНИЕ 1 : я могу создать вектор TRectangles и манипулировать им черезвектор.Теперь, как я могу получить доступ к их событиям для запуска кода (например, OnClick)?Вот что у меня есть:
#include <vector> // in my cpp file
std::vector<TRectangle*> myRects; // in my cpp file outside of any function so it is global
void __fastcall TForm1::Button3Click(TObject *Sender)
{
TRectangle *R = new TRectangle(this);
R->Parent = this;
R->Position->X = 20 + 5*myRects.size(); // slightly offset them in space
R->Position->Y = 20;
R->Tag = myRects.size()+1; // i think this is how i will tell them apart
myRects.push_back(R);
}
Я могу переместить прямоугольник так:
void __fastcall TForm1::Button4Click(TObject *Sender)
{
myRects[1]->Position->X = 50; // this moves rectangle number 2.
myRects[1]->Position->Y = 50;
}
ОБНОВЛЕНИЕ 2 : С направлением Реми у меня все работаетсейчас!Я добавил R->OnClick = &myRectOnClick;
к своему Button3Click
методу прямо над push_back
.Затем я добавил следующий метод к моей TForm1.
void __fastcall TForm1::myRectOnClick(TObject *Sender)
{
if (TRectangle *Re = dynamic_cast<TRectangle *>(Sender)) { // make sure result of cast is not null
ShowMessage("Rectangle " + IntToStr(Re->Tag)); // Tag is how i know which rectangle i'm dealing with
}
}
ОБНОВЛЕНИЕ 3 : Не уверен, что это должен быть новый вопрос ... но я добавил PopupMenu1
, который я хочувызвать правой кнопкой мыши по прямоугольникам.Я включил его с R->PopupMenu = PopupMenu1
в коде Button3Click
.Событие MenueItem1Click
просто делает ShowMessage
отображением номера прямоугольников (currentR
).Ну, глобальный int currentR
для прямоугольника не устанавливается, когда я просто щелкаю правой кнопкой мыши на прямоугольнике.Я должен сначала щелкнуть левой кнопкой мыши, а затем щелкнуть правой кнопкой мыши по currentR
, чтобы установить этот тег прямоугольников.Ниже приведен мой код для события нажатия мыши на прямоугольнике - кажется, он должен всегда устанавливать currentR
для текущего прямоугольника независимо от щелчка левой или правой кнопкой мыши.
void __fastcall TForm1::myRectOnMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, float X, float Y)
{
if (TRectangle *Re = dynamic_cast<TRectangle *>(Sender)) { // make sure result of cast is not null
currentR = Re->Tag; // which rectangle
if (Button == 0) { // left mb
fMouseIsDown = true;
fMouseInRectAtClick.X = X;
fMouseInRectAtClick.Y = Y;
}
}
}
Для ясности вот моя последняя версияButton3Click
код, который помещает новый прямоугольник в форму:
void __fastcall TForm1::Button3Click(TObject *Sender)
{
TRectangle *R = new TRectangle(this);
R->Parent = this;
R->Position->X = 20 + 5*myRects.size();
R->Position->Y = 20;
R->Tag = myRects.size()+1;
R->OnMouseDown = &myRectOnMouseDown;
R->OnMouseUp = &myRectOnMouseUp;
R->OnMouseMove = &myRectOnMouseMove;
R->PopupMenu = PopupMenu1; // to get a popup menu
myRects.push_back(R);
}