PDA

Ver la Versión Completa : Existe algun componente "linea" y "vista miniatura"?


DSK25
07-06-2013, 17:33:49
Osea por componente "linea" me refiero a una linea que permita enlazar dos componentes, por ejemplo si tuviera dos panel quisiera que el componente "linea" los enlazara, si un panel se mueve la linea tambien para acomodarse a la nueva posicion del panel; tambien necesito un componente que permita tener una vista miniatura de otro componente, como por ejemplo ver en miniatura el contenido de un panel.

Existe alguno de estos componentes? Donde los puedo conseguir? Gracias :)

maeyanes
07-06-2013, 18:10:56
Hola...

Para el componente "linea" puedes probar con el TSplitter. Para la vista miniatura, ahí si no sabría decirte si existe algo...



Saludos...

DSK25
07-06-2013, 18:46:45
Hola...

Para el componente "linea" puedes probar con el TSplitter. Para la vista miniatura, ahí si no sabría decirte si existe algo...



Saludos...

Por componente linea me referia a algo así:

http://www.subeimagenes.com/img/asdf-658943.png

ecfisa
08-06-2013, 01:52:17
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. :rolleyes: :D

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 :

...
#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:

...
#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 :)

DSK25
08-06-2013, 17:15:00
Gracias ecfisa, todo ok :D

ecfisa
09-06-2013, 00:43:39
Hola DSK25.

Y ya que estamos, una idea para la miniatura.

Agregá un TPanel del tamaño que desees la miniatura, dentro de él pone un TImage y proba este código:

...

/* Ajustar propiedades de Panel2 y Image1 */
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Panel2->BevelInner = bsNone;
Panel2->BevelOuter = bsNone;
Panel2->Ctl3D = false;
Panel2->BorderStyle = bsSingle;
Image1->Align = alClient;
Image1->Stretch = true;
}

void WinCtrlToImage(TWinControl *aWinCtrl, TImage *aImg)
{
Graphics::TBitmap *bm = new Graphics::TBitmap;
HDC hDC;
__try {
bm->Width = aWinCtrl->Width;
bm->Height = aWinCtrl->Height;
hDC = GetWindowDC(aWinCtrl->Handle);
__try {
BitBlt(bm->Canvas->Handle, 0, 0, bm->Width,
bm->Height, hDC, 0, 0, SRCCOPY);
}
__finally {
ReleaseDC(aWinCtrl->Handle, hDC);
}
aImg->Picture->Bitmap->Canvas->Draw(0, 0, bm);
aImg->Picture->Bitmap->Assign(bm);
aImg->Stretch = true;
}
__finally {
delete bm;
}
}



Ejemplo de uso:

void __fastcall TForm1::btnToImgClick(TObject *Sender)
{
WinCtrlToImage(Panel1, Image1);
}


Ejemplo de salida:
http://imageshack.us/a/img19/8047/miniaturaq.jpg

Saludos. :)

DSK25
09-06-2013, 01:23:05
Excelente ecfisa, me funciono perfectamente, gracias :)