FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Componentes magnéticos.
Hola a tod@s:
He conseguido hacer dos componentes (de tipos diferentes) "magnetizados", de forma que cuando muevo (arrastrar y soltar) cualquiera de ellos en tiempo de diseño, se mueve su correspondiente compañero a la posición deseada. Para hacerlo he capturado el mensaje WM_MOVE. El problema está cuando selecciono los dos componentos y los muevo a la vez. Entonces se dispara dos veces el método de captura del mensaje WM_MOVE: cuando es movido por su compañero, y su propio evento WM_MOVE. Al llamarse dos veces el evento, el efecto de los cálculos hacen que los componentes se situen en un lugar diferentes a donde los solté. Sé que en el apartado de ejemplos había algo parecido realizado con Forms, aunque no sé si resuelve el problema de mover los dos a la vez. En cualquier caso, parece ser que ha cambiado el diseño de la web, y no lo consigo encontrar. ¿Alguien tiene esto resuelto? Recuerden que todo esto es en tiempo de diseño. Saludos y gracias. Última edición por Jose_Pérez fecha: 21-02-2008 a las 16:08:27. |
#2
|
||||
|
||||
Normalmente el componente magnético tiene una propiedad que indica el control al que se encuentra adherido, en uno de ellos podrías tener una variable "moving" a modo de bandera, para detener uno de los dos.
Quizás te interese más el mensaje wm_poschanging (dicho de memoria) Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#3
|
|||
|
|||
Gracias por tu respuesta Lepe. Cuando tenga tiempo lo probaré.
Un apunte de entrada: hay que tener en cuenta que TComonenteA mueve a TComponeteB y viceversa. |
#4
|
|||
|
|||
Hola de nuevo:
Después de darles muchas vueltas finalmente he conseguido resolver el problema. Voy a intentar explicar la solución lo mejor que pueda, porque la verdad es que hay que saber primero como se comporta el mensaje WM_MOVE para comprender la solución; finalmente he decidido capturar este mensaje y no WM_WINDOWPOSCHANGING propuesto por Lepe, ya que pensaba (sin haberlo probado a fondo) que a efectos prácticos era lo mismo uno que otro. El problema estaba en que cada componente (TComponenteA y TComponenteB) respondían a su correspondiente mensaje WM_MOVE sin tener en cuenta la respuesta del otro. De ese modo cuando, en tiempo de diseño, seleccionaba y arrastraba los dos componente a la vez se liaban los cálculos. Para comprobar el orden de llamada incluí varios ShowMessage en el código. Así pude comprobar, para mi sorpresa, que el modo en que se sucedían los mensajes WM_MOVE no era el que yo esperaba. Este es el orden (recuerden siempre que estamos hablando de tiempo de diseño y que estamos arrastrando los dos componentes a la vez): 1.- Se ejecuta la respuesta al mensaje WM_MOVE en TComponenteA. Aquí se modifican las propiedades Left y Top de TComponenteB. 2.- Primera sorpresa: se ejecuta dos veces la respuesta al mensaje WM_MOVE en TComponenteB: uno para Left (desplazamiento horizontal) y otro para Top (desplazamiento vertical). 3.- Segunda sorpresa: Se ejecuta una tercera respuesta al mensaje WM_MOVE en TComponenteB, que correspondería al momento en que se suelta el componente en el form. Para empeorar las cosas, en este momento el propio Delphi suma (o resta) las propiedades Top y Left del componente según el desplazamiento. Vamos, un lio. El principal problema era saber si el evento correspondía al punto 2 o al 3, sin necesidad de que los componentes se comunicaran a través de eventos o propiedades. Al final utilicé la función GetTickCount, del API, para medir el tiempo en milésimas de segundo entre una llamada y otra. ¡Ojo, hay que calcular un tiempo para Left y otro para Top, porque no siempre el desplazamiento es en diagonal! Tras hacer pruebas, vi que la diferencia de tiempo entre el punto 2 y 3 era 0. Y este es el resultado...
Última edición por Jose_Pérez fecha: 17-03-2008 a las 12:33:30. |
#5
|
||||
|
||||
Ahora que has explicado un poco más el tema, se vé las cosas de otra forma .
¿no puedes usar SetBounds en lugar de Left y Top? Ahí solo se produce el mensaje wm_windowposchanged:
la "Segunda sorpresa" puede ser por tener activada la opción "Align To Grid" en las opciones de Delphi. Lo que no queda claro, es el por qué no quieres tener enlazados ambos componentes con propiedades, es lo que se suele hacer como norma. Fíjate en el TDatasource que tiene una propiedad Dataset de forma pública: En tiempo de diseño, eliges en el inspector de objetos el control al que se desea adosar. Esto tiene varias ventajas: - Puedes acceder de un control a otro para modificar sus propiedades, sin tener que buscarlo (Findcomponent es un bucle que puede tener 60 o 100 iteraciones por los campos persistentes, paneles, etc). - Usando Notification puedes poner a nil esa propiedad cuando el usuario elimina el "componente B" de la ventana (en tiempo de diseño, claro) Esto ya es un poco más lioso, pero bueno. Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#6
|
|||
|
|||
Hola Lepe:
No he tenido tiempo de probar nada de lo que me dices, pero probablemente sea otra forma de hacerlo. Cita:
Por cierto, probando el componente he visto que en el evento Create hay que inicializar las variables FTickCountTop y FTickCountLeft a 0, de lo contrario, al crearse el componente toma los valores 0 para Top y Left en la respuesta al mensaje WM_MOVE.
Última edición por Jose_Pérez fecha: 05-03-2008 a las 15:14:56. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Componentes | Petolansa | Varios | 5 | 23-08-2007 17:34:22 |
Componentes MDO | Tauro78 | Firebird e Interbase | 1 | 21-01-2007 04:19:32 |
componentes xp | supermilloriver | OOP | 2 | 28-07-2005 17:50:52 |
Componentes USB | HARD-SOFT | Varios | 0 | 26-08-2004 13:00:05 |
Formulario magneticos | ElCherchu | Varios | 2 | 13-05-2003 16:14:45 |
|