Hola DSK25.
No conozco ningun componente "linea", pero se me ocurrió un código que podes mejorar y tal vez, quíen te dice, hasta usar.
El ejemplo usa dos
TPanel, pero del mismo modo podrían ser un
TEdit y un
TCheckBox, un
TLabel y un
TComboBox, etc. Asigna en ambos controles los métodos ControlMouseDown, ControlMouseMove y ControlMouseUp a los eventos correspondientes.
No realiza los quiebres de línea entre los paneles como en tu imágen, pero que los une... los une.
Unit1.h :
Código:
...
#define WM_AFTER_CREATE WM_USER + 300
class TForm1 : public TForm
{
...
private:
void __fastcall WMAfterCreate(TMessage &Msg);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_AFTER_CREATE, TMessage, WMAfterCreate);
END_MESSAGE_MAP(TForm);
void __fastcall GetLineEnds(TControl *C1, TControl *C2);
void __fastcall DrawLine(TControl *C1, TControl *C2,const TColor aColor);
public:
__fastcall TForm1(TComponent* Owner);
};
};
Unit1.cpp:
Código:
...
#define LINECOLOR clBlue
TPoint pVec[1], pIni;
bool Moving = false;
TControl *Ctrl1, *Ctrl2;
/* PRIVATE */
void __fastcall TForm1::WMAfterCreate(TMessage &Msg)
{
DrawLine(Ctrl1, Ctrl2, LINECOLOR);
}
void __fastcall TForm1::GetLineEnds(TControl *C1, TControl *C2)
{
if (C1->Left + C1->Width < C2->Left) {
pVec[0].x = C1->Left + C1->Width ;
pVec[0].y = C1->Top + C1->Height / 2;
pVec[1].x = C2->Left;
pVec[1].y = C2->Top + C2->Height / 2;
} else if (C2->Left + C2->Width < C1->Left){
pVec[0].x = C2->Left + C2->Width;
pVec[0].y = C2->Top + C2->Height / 2;
pVec[1].x = C1->Left;
pVec[1].y = C1->Top + C1->Height / 2;
} else if (C1->Top + C1->Height > C2->Top + C2->Height) {
pVec[0].x = C1->Left + C1->Width / 2;
pVec[0].y = C1->Top;
pVec[1].x = C2->Left + C2->Width / 2;
pVec[1].y = C2->Top + C2->Height;
} else {
pVec[0].x = C1->Left + C1->Width / 2;
pVec[0].y = C1->Top + C1->Height;
pVec[1].x = C2->Left + C2->Width / 2;
pVec[1].y = C2->Top;
}
}
void __fastcall TForm1::DrawLine(TControl *C1, TControl *C2,const TColor aColor)
{
if(C1->Left > C2->Left+C2->Width || C1->Left+C1->Width < C2->Left
|| C1->Top > C2->Top+C2->Height ||C1->Top+C1->Height < C2->Top) {
Canvas->Pen->Color = aColor;
Canvas->Pen->Width = 2;
Canvas->MoveTo(pVec[0].x, pVec[0].y);
Canvas->LineTo(pVec[1].x, pVec[1].y);
}
}
/* PUBLIC */
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Ctrl1 = Panel1; // Edit, Label, etc
Ctrl2 = Panel2; // Idem
Ctrl1->Hint = " Ctrl+Mouse click para arrastrar ";
Ctrl1->ShowHint = true;
Ctrl2->Hint = Panel1->Hint;
Ctrl2->ShowHint = true;
GetLineEnds(Ctrl1, Ctrl2);
PostMessage(Handle, WM_AFTER_CREATE, 0, 0);
}
void __fastcall TForm1::ControlMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (Shift.Contains(ssCtrl)) {
Moving = true;
DrawLine(Ctrl1, Ctrl2, Color);
}
pIni.x = X;
pIni.y = Y;
}
void __fastcall TForm1::ControlMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
TControl *Ctrl = static_cast<TControl*>(Sender);
if (Moving) {
Ctrl->Left += X - pIni.x;
Ctrl->Top += Y - pIni.y;
}
}
void __fastcall TForm1::ControlMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
GetLineEnds(Ctrl1,Ctrl2);
DrawLine(Ctrl1, Ctrl2, LINECOLOR);
Moving = false;
}
Saludos