我正在尝试将the code from this从使用一个TRectangle扩展为使用可以在运行时添加的多个矩形。在该示例中,要单击并拖动的代码仅适用于那个TRectangle Rectangle1
。我需要使其更通用,以便它可应用于我添加到表单中的任何矩形(在设计时矩形将不存在)。我发现this code to create a custom class,可以很好地创建新的矩形。我可以分配在单击它们时运行的方法,但由于与TForm1
是一个单独的类,因此我认为这是错误的选择...而且我需要许多数据点才能使代码正常工作来自TForm1
(位置等)。
简而言之,我希望能够在运行时添加TRectangles并针对该特定矩形在正常事件(单击矩形,单击鼠标时等)上运行代码。
不确定从哪里开始...但是首先,我想我需要知道如何制作一系列可以通过以下方式访问的控件:
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
)。好吧,当我右键单击矩形时,矩形的全局整数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);
}