 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Sab 27 Ago, 2005 10:42 pm Asunto: ALFREDO-CESAR. Arratrar TShape por un Formulario o TImage? |
|
|
Hago esto:
| Código: |
void __fastcall TfrmZonas::LMDShapeButton1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
TLMDShapeButton *Objeto = (TLMDShapeButton *)Sender;
ReleaseCapture();
SendMessage(Objeto->Handle),WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
|
y me dice esto:
[C++ Error] UnidadZonas.cpp(372): E2316 'Handle' is not a member of 'TLMDShapeButton'
Que estoy haciendo mal?...
Lo mismo me dice el compilador si utilizo un TShape normal.
Donde está la propiedad "Handle" de un componente TShape.
Y puestos a pedir.
¿Como hago para que el Objeto que estoy arrastrando se mueva con el cursor o se enganche al ratón mientras desplazo el Objeto?
Muchisimas GRACIAS. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Lun 29 Ago, 2005 5:08 pm Asunto: Urgente |
|
|
Por favor, necesito que alguien me ayude, es URGENTE. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
alfredo Master

Registrado: 13 Oct 2003Mensajes: 246Ubicación: Valencia Venezuela
|
Publicado: Lun 29 Ago, 2005 7:41 pm Asunto: |
|
|
Hola, bueno el problema es que este componente no tiene Handle asi que no puedes agarrarlo por ahi, pero hay otra forma no tan elegante y simple pero funciona, primero debes declarar las siguentes variables bajo private del header:
bool Arrastrando;
Int CentroH, CentroV;
y vamos a utilizar los tres eventos mouse, para fijar mover y soltar el shape | Código: |
void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TShape * oTmpShape = (TShape *)Sender;
CentroH = oTmpShape->Width / 2;
oTmpShape->Left = oTmpShape->Left+X-CentroH;
CentroV = oTmpShape->Height / 2;
oTmpShape->Top = oTmpShape->Top+Y-CentroV;
Arrastrando = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if (Arrastrando)
{
TShape * oTmpShape = (TShape *)Sender;
oTmpShape->Left = oTmpShape->Left+X-CentroH;
oTmpShape->Top = oTmpShape->Top+Y-CentroV;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
Arrastrando = False;
}
//---------------------------------------------------------------------------
| Espero que te sirva, se puede mejorar el codigo para que no salte al darle click fuera de su centro calculando las coordenadas absolutas respecto al form y aplicando las correcciones pertinentes |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mar 30 Ago, 2005 12:48 am Asunto: |
|
|
Gracias Alfredo, lo probaré _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Mie 31 Ago, 2005 5:39 am Asunto: |
|
|
Prueba asi, ya que TShape, no deciende de TWinControl, por lo tanto, no tiene la propiedad Handle, pero haciendo chapuza, trampa, etc etc,
prueba esta codigo..
| Código: | void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
// jalamos el control
TShape *pS = static_cast<TShape*>(Sender);
// guardamos el parent original
TWinControl *parentOriginal = pS->Parent;
// creamos un panel temporal
TPanel *pP = new TPanel(this);
pP->Parent = this;
// del tamaño del TShape
pP->SetBounds(pS->Left,pS->Top,pS->Width,pS->Height);
pP->Parent = pS->Parent;
pS->Parent = pP; // metemos el TShap en el panel
// lo movemos, y al final
ReleaseCapture();
SNDMSG(pP->Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
// restauramos el original.
pS->Parent = parentOriginal;
pS->Left = pP->Left;
pS->Top = pP->Top;
delete pP;
} |
_________________
 |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mie 31 Ago, 2005 5:59 pm Asunto: |
|
|
Gracias Cesar por contestar, pero la verdad es que lo que Alfredo me ha ofrecido era lo que realmente necesitaba. Con el codigo que tu me propones solo se vé el perimetro del TPanel, aparte de que el resultado no es Optimo. De la forma que Alfredo me ha propuesto el efecto visual es que arrastras realmente el TLMDShapeButton. Gracias a los dos. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mie 31 Ago, 2005 6:39 pm Asunto: PARA ALFREDO |
|
|
Alfredo, funciona perfectamente, a falta de el incomodo click que hace que se cambie de sitio. Como tu bien dices hay que calcular las coordenadas, en el momento que hago click, pero despues de intentarlo una y otra vez, he desesperado un poco , ya que no se en que evento tengo que hacerlo realmente y cuando le debo de dar las nuevas coordenadas al Objeto. Si no te supone mucho problema, podrias echarme otra vez una mano? GRACIAS. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
alfredo Master

Registrado: 13 Oct 2003Mensajes: 246Ubicación: Valencia Venezuela
|
Publicado: Mie 31 Ago, 2005 6:57 pm Asunto: |
|
|
Hola, Pues resulta que era mas sencillo de lo que parecia, ya me imaginaba yo convirtiendo coordenadas relativas a absolutas, pues no...
el evento que usamos es del shape y las posiciones X,Y son por tanto relativas a este, asi que solo modifica OnMouseDown como abajo: | Código: | void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TShape * oTmpShape = (TShape *)Sender;
CentroH = X;//Posicion X donde Hacemos Click sobre el Shape
oTmpShape->Left = oTmpShape->Left+X-CentroH;
CentroV = Y;//Posicion Y donde Hacemos Click sobre el Shape
oTmpShape->Top = oTmpShape->Top+Y-CentroV;
Arrastrando = true;
}
|
|
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mie 31 Ago, 2005 7:36 pm Asunto: |
|
|
Otra opción, en la que solo tendrás que usar el evento OnMouseMove.
- Pon el siguiente código en el OnMouseMove de cualquier control que necesites mover:
| Código: | TControl* control = static_cast<TControl*>(Sender);
static bool pulsado = false;
static TPoint posicion;
if (!pulsado && Shift.Contains(ssLeft))
posicion = Point(X, Y);
pulsado = Shift.Contains(ssLeft);
if (pulsado)
{
control->Left += X - posicion.x;
control->Top += Y - posicion.y;
} |
|
|
| Volver arriba |
|
 |
alfredo Master

Registrado: 13 Oct 2003Mensajes: 246Ubicación: Valencia Venezuela
|
Publicado: Mie 31 Ago, 2005 8:21 pm Asunto: |
|
|
Muy bueno!! este _Leo si sabe hacer Aikus con el codigo  |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Jue 01 Sep, 2005 12:16 am Asunto: MIL Gracias |
|
|
Soys unos genios del la programación, es lo único que se me ocurre.
Los dos formas que me proponeis funcionan perfectamente, aunque con la forma de _Leo se escribe menos codigo y no hace falta emplear variables globales a nivel de formulario.
Por otra parte el código de Alfredo también considero que es muy elegante, aunque existia código redundante:
| Código: |
void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TShape * oTmpShape = (TShape *)Sender;
CentroH = X;//Posicion X donde Hacemos Click sobre el Shape
oTmpShape->Left = oTmpShape->Left+X-CentroH;
CentroV = Y;//Posicion Y donde Hacemos Click sobre el Shape
oTmpShape->Top = oTmpShape->Top+Y-CentroV;
Arrastrando = true;
}
|
Este código era redundante:
oTmpShape->Left = oTmpShape->Left+X-CentroH;
oTmpShape->Top = oTmpShape->Top+Y-CentroV;
Quedando de esta forma:
| Código: |
void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TShape * oTmpShape = (TShape *)Sender;
CentroH = X;//Posicion X donde Hacemos Click sobre el Shape
CentroV = Y;//Posicion Y donde Hacemos Click sobre el Shape
Arrastrando = true;
}
|
Al final mi codigo ha quedado asi:
| Código: |
void __fastcall TfrmZonas::LMDShapeButton1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TLMDShapeButton * PLSB = (TLMDShapeButton *)Sender;// Puntero al Objeto TLMDShapeButton
Componente = PLSB->ComponentIndex; // Para saver el Numero de Componente que he pulsado
LeftAnt = PLSB->Left; // Para guardar su posicion Left anterior por si se rechazo el arrastre
TopAnt = PLSB->Top; // Para guardar su posicion Top anterior por si se rechazo el arrastre
}
//---------------------------------------------------------------------------
void __fastcall TfrmZonas::LMDShapeButton1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
// Codigo de _Leo
TControl* control = static_cast<TControl*>(Sender);
static bool pulsado = false;
static TPoint posicion;
if (!pulsado && Shift.Contains(ssLeft))
posicion = Point(X, Y);
pulsado = Shift.Contains(ssLeft);
if (pulsado)
{
control->Left += X - posicion.x;
control->Top += Y - posicion.y;
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmZonas::LMDShapeButton1MouseUp(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if(((TLMDShapeButton *)Sender)->Left > (741 - ((TLMDShapeButton *)Sender)->Width) || ((TLMDShapeButton *)Sender)->Top > (741 - ((TLMDShapeButton *)Sender)->Height))
{
ShowMessagePos("La nueva posición está fuera del Plano permitido.\n\n"
"Si quiere ver los límites del plano active la Rejilla de Orientación,\n"
"en la pantalla anterior.", frmVentas->Left + 350,frmVentas->Top + 300);
((TLMDShapeButton *)Sender)->Left = LeftAnt;
((TLMDShapeButton *)Sender)->Top = TopAnt;
}
if(((TLMDShapeButton *)Sender)->Left != LeftAnt || ((TLMDShapeButton *)Sender)->Top != TopAnt)
BtnGuardar->Enabled = true; // Si el arrastre a tenido exito
}
//---------------------------------------------------------------------------
|
Todo esto, porque es un mapa dibujado en un TImage y necesito saver si el usuario se sale de el, cuando arrastra los Objetos del Formulario.
Así que tengo que controlar que el arrastre se rechace en caso de que se salga.
En resumen que he solucionado el problema gracias a los dos.
Por cierto....
Esta linea ¿Es un puntero a el Objeto TLMDShapeButton?
TLMDShapeButton * PLSB = (TLMDShapeButton *)Sender;// Puntero al Objeto TLMDShapeButton
Perdonar mi ignorancia.
Pero si no es así. ¿Me podeis explicar que es?
No quiero parecer repetitivo,... pero Gracias otra vez. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
alfredo Master

Registrado: 13 Oct 2003Mensajes: 246Ubicación: Valencia Venezuela
|
Publicado: Jue 01 Sep, 2005 3:23 pm Asunto: |
|
|
Bueno gracias por lo de genio, pero en mi caso no debe aplicar ya que tu mejoraste mi codigo, yo me quedo con el de _Leo por que como tu dijiste tiene menos lineas, usa menos eventos y se ahorra unas variables.
Con respecto a tu pregunta aunque estoy algo flojo en teoria creo que
TLMDShapeButton * PLSB es un puntero al tipo de objeto y
= (TLMDShapeButton *)Sender es lo que hace que apunte al objeto en si.
Si me equivoco alguien me corregira espero. |
|
| Volver arriba |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Jue 01 Sep, 2005 3:50 pm Asunto: |
|
|
Gracias Alfredo por tu rapida respuesta, en cuanto al tema, por mi parte ya está todo resuelto. Gracias. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|