Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Mover dos formularios al mismo tiempo (https://www.clubdelphi.com/foros/showthread.php?t=58805)

santus 01-08-2008 16:07:28

Mover dos formularios al mismo tiempo
 
Hola amigos. Tengo que hacer una aplicacion simple. El tema complejo es que tengo que lograr mover dos formularios al mismo tiempo en tiempo de ejecución.

Los formularios son sismples. Nomas tienen unas cosillas que mostrar pero nada mas. Tengo un formulario principal, y tengo otro formulario al lado, que se abre para mostrar información al hacer click en un botón. Este se muestra al lado del principal.

Ya logré mover el fomulario desde cada de las ventanas. Arrastrando el mouse sobre cada una, me las mueve en forma independiente. Para ello usé esta funcion:

Código Delphi [-]

procedure TfMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    ReleaseCapture;    
    Perform(WM_SYSCOMMAND, SC_DRAGMOVE, Integer(PointToSmallPoint(Point(X,Y))));
end;

Hasta aquí todo bien. Cada una de las ventanas se mueve en forma independiente. Ahora bien. Estoy intentantando que se muevan los dos al mismo tiempo. Osea, cuando arrastro el mouse sobre uno, se mueva tambien el otro.

Se me ocurrió sin muchos resultados, enviar un mensaje personalizado a cada formulario para que se muevan todos juntos. Algo asi como:

Código Delphi [-]
CONST
  WM_MOVERFORM = WM_USER + 0;
  SC_DRAGMOVE = $F012;

procedure TfMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 SendMessage(Handle,WM_MOVERFORM,SC_DRAGMOVE,Integer(PointToSmallPoint(Point(X,Y))));
end;

procedure OnMoverVentana(var Msg: TMessage); message WM_MOVERFORM;

procedure TfMain.OnMoverVentana(var Msg: TMessage);
begin
    ReleaseCapture;
    Perform(WM_SYSCOMMAND, Msg.WParam,Msg.LParam);
end;

Para el segundo formulario hago lo mismo. Le envio el handle del otro fomulario así:

Código Delphi [-]
procedure TfMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    SendMessage(Handle,WM_MOVERFORM,SC_DRAGMOVE,   Integer(PointToSmallPoint(Point(X,Y))));
    SendMessage(form2.handle,WM_MOVERFORM,SC_DRAGMOVE,   Integer(PointToSmallPoint(Point(X,Y))));

end;

Y así. El problema que luego de enviar el primer mensaje la aplicación no envia el próximo mensaje hasta que no termino de soltar el mouse, osea que se mueve sólo el que primero recibe el mensaje.

Estoy perdido. Buscando aqui y en internet no encotré ni siquiera una idea de como seguir. Si alguien tiene alguna idea, siempre va a ser bienvenida porque a esta altura, ya ni se si esta implementación es correcta.

Bien, gracias a todo, y espero no haberlos aburrido con este laaarrggooo post. Gracias.

coso 01-08-2008 16:47:32

Hola, creo que deberias seguir enviando el mensaje mediante onmousemove. no he revisado tu codigo, pero la idea seria seguir actualizando la posicion de la form destino mientras el mouse esta pulsado

Neftali [Germán.Estévez] 01-08-2008 17:20:52

En la sección de ejemplos de mi página, hay uno tiitulado "Simular barras flotantes en torno al formulario" y creo que es más o menos lo que necesitas. Al mover un formulario arrastra otro "pegado" a él.
Se utiliza el mensaje WM_WINDOWPOSCHANGING.

Está con el código fuente, así que puedes descargarlo y echarle un vistazo.

santus 01-08-2008 19:38:29

excelente!!!
 
Gracias Neftali.
Me funcionó de diez el ejemplo de tu página.

Lo unico que hice fue agregarle el mensaje al formulario principal, y que se acomoden las posiciones del segundo. Por si a alguien le interesa, quedaría algo asi:

Código Delphi [-]
unit uMain;
...
private
   procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
...
implementation

...
// evento OnMouseDown del formulario.
// esto sirve para mover el formulario de tipo BorderStyle = bsNone.
procedure TfMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const
  SC_DRAGMOVE = $F012;
begin
  ReleaseCapture;
  Perform(WM_SYSCOMMAND, SC_DRAGMOVE, Integer(PointToSmallPoint(Point(X,Y))));
end;


// actualiza la posición del segundo form cuando lo movemos.
procedure TfMain.WMWindowPosChanging(var Message: TWMWindowPosChanging);
begin
  inherited;
  if (Assigned(form2)) and (form2.Visible) then
    form2.acomodarVentana;
end;
...

Y en el segundo formulario:

Código Delphi [-]
unit unit2;
...
public
    procedure acomodarVentana;
...
implementation
...

// elegimos a donde va el form. En mi caso, que lo muestre a la izq.
procedure TForm2.acomodarVentana;
begin
  Self.Top := fMain.Top;
  Self.Left := fMain.Left - Self.Width;
end;
...

Si al moverlo se ve el efecto del parpadeo en el formulario, simplemente agregar al evento OnCreate del form2:

Código Delphi [-]
   Self.DoubleBuffered := true;

En fin. Gracias Neftali por tu ayuda. Me ha venido muy bien, ya que no sabía como seguir. Hasta llegue a pensar que simplemente no se podia hacer esto:eek::eek::eek::eek:. Y gracias tambien a todos los que se tomaron el trabajo de intentar entenderme!!:)

Saludos.


La franja horaria es GMT +2. Ahora son las 01:36:12.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi