Gracias por responder ricardo, suponia que ese era el efecto de inherited, pero confrmado queda claro.
Al final con el movimiento conjunto de ventanas el tema esta solucionado y un poco mas afinado
en este video se ve una muestra del efecto con topes incluidos
http://www.youtube.com/watch?v=yHiEy...ature=youtu.be
Hago un resumen de lo necesario, o lo que es lo mismo, la receta para cocinarlo
Formulario Padre o principal:
1 manejador de mensaje del movimiento de la pantalla principal
Código Delphi
[-]
private
procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
3 variables publicas
Código Delphi
[-]
public
PxArriba: word;
PxAbajo: word;
PxDcha: word;
En el OnCreate (por ejemplo) calcular los margenes
en mi caso tengo abajo una TStatusBar
Código Delphi
[-]
PxArriba := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYFRAME) - 1;
PxAbajo := StatusBar.Height + GetSystemMetrics(SM_CYFRAME);
PxDcha := GetSystemMetrics(SM_CXFRAME);
Al crear las ventanas hijas darle informacion sobre los limites para que no se pasen
Código Delphi
[-]
DCx[i].PxArriba := FormRemoto.PxArriba;
DCx[i].PxAbajo := FormRemoto.PxAbajo;
DCx[i].PxDcha := FormRemoto.PxDcha;
DCx[i].Left := StrToIntDef(SGmaquinas.Cells[4, i + 1], 1);
DCx[i].Top := StrToIntDef(SGmaquinas.Cells[5, i + 1], 1);
El manejador que mueve las ventanas hijas cuando se mueve el padre
Código Delphi
[-]
procedure TFormRemoto.WMWindowPosChanging(var Message: TWMWindowPosChanging);
var
i, t: integer;
begin
t := Length(DCx);
if t = 0 then
Exit;
for i := 0 to t - 1 do
begin
if DCx[i] = nil then
Continue;
DCx[i].Forma.Top := Self.Top + PxArriba + DCx[i].Top;
DCx[i].Forma.Left := Self.Left + PxDcha + DCx[i].Left;
end;
inherited;
end;
Formulario hijo (semitrasparente con alphablendvalue)
unas variables publicas y los procedimientos de movimiento de raton
al final he deshechado los mensaje windows porque sale un movimiento "mas fino" de esta forma
Código Delphi
[-]
public Forma: TForm; FormularioPadre: TWinControl; PxArriba: word; PxAbajo: word; PxDcha: word; Left, Top: word; procedure LedOnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); procedure LedOnMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer); procedure LedOnMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Crear los formularios hijos en tiempo de ejecucion
Código Delphi
[-]
Forma := TForm.CreateNew(FormularioPadre, 0); Forma.Position := poDesigned;
Forma.BorderStyle := bsNone;
Forma.Left := FormularioPadre.Left + PxDcha + Left; Forma.Top := FormularioPadre.Top + PxArriba + Top;
if Icono = False then
begin
Forma.Width := 206;
Forma.Height := 256;
end
else
begin
Forma.Width := 26;
Forma.Height := 26;
end;
Forma.Color := clHotLight;
Forma.Visible := Visible;
Forma.AlphaBlend := True;
Forma.AlphaBlendValue := 210;
Forma.ShowHint := True;
Forma.Hint := 'Left-Click y arrastre para mover';
Forma.OnMouseDown := LedOnMouseDown;
Forma.OnMouseMove := LedOnMouseMove;
Forma.OnMouseUp := LedOnMouseUp;
...
crear los componentes vcl y asigarno a la forma y los evento si es necesario
Lnumero := TLabel.Create(Forma);
Lnumero.Parent := Forma;
Lnumero.Top := LedOn.Top + 5;
Lnumero.Left := LedOn.Left + 6;
Lnumero.Height := 13;
Lnumero.Width := 12;
Lnumero.Transparent := True;
Lnumero.Caption := IntToStr(Numero);
Lnumero.ShowHint := True;
Lnumero.Hint := LedOn.Hint;
Lnumero.Visible := Icono;
Lnumero.OnMouseDown := LedOnMouseDown;
Lnumero.OnMouseMove := LedOnMouseMove;
Lnumero.OnMouseUp := LedOnMouseUp;
...
y los manejadores de eventos
Código Delphi
[-]
procedure TcapturadorDCx.LedOnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
oldLeft := X;
oldTop := Y;
if Sender is TForm then
Exit;
if Button = mbRight then
begin
if Icono = True then
SetIcono(False)
else
SetIcono(True);
Exit;
end;
if ssDouble in Shift = False then
Exit;
if DCx = nil then
ActivaDCx else
if DCx.abierto = True then
DesactivaDCx
else
if (DCx.conectando = False) and (Conectando = False) then
ActivaDCx; end;
procedure TcapturadorDCx.LedOnMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
var
nX, nY: integer;
begin
if ssLeft in Shift = False then
Exit;
if Forma.Left < (FormularioPadre.Left + PxDcha) then
begin
Forma.Left := FormularioPadre.Left + PxDcha;
SetCursorPos(Forma.Left + X, Forma.Top + Y);
end;
if (Forma.Left + Forma.Width) > (FormularioPadre.Left + FormularioPadre.Width - PxDcha) then
begin
Forma.Left := (FormularioPadre.Left + FormularioPadre.Width) - Forma.Width - PxDcha;
SetCursorPos(Forma.Left + X, Forma.Top + Y);
end;
if Forma.Top < (FormularioPadre.Top + PxArriba) then
begin
Forma.Top := FormularioPadre.Top + PxArriba;
SetCursorPos(Forma.Left + X, Forma.Top + Y);
end;
if (Forma.Top + Forma.Height) > (FormularioPadre.Top + FormularioPadre.Height - PxAbajo) then
begin
Forma.Top := (FormularioPadre.Top + FormularioPadre.Height) - Forma.Height - PxAbajo;
SetCursorPos(Forma.Left + X, Forma.Top + Y);
end;
if X < oldLeft then
begin
nX := oldLeft - X;
Forma.Left := Forma.Left - nX;
end
else
begin
nX := X - oldLeft;
Forma.Left := Forma.Left + nX;
end;
if Y < oldTop then
begin
nY := oldTop - Y;
Forma.Top := Forma.Top - nY;
end
else
begin
nY := Y - oldTop;
Forma.Top := Forma.Top + nY;
end;
end;
procedure TcapturadorDCx.LedOnMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Left := Forma.Left - (FormularioPadre.Left + PxDcha);
Top := Forma.Top - (FormularioPadre.Top + PxArriba);
Movido(Sender);
end;
procedure TcapturadorDCx.Movido(Sender: TObject);
begin
if Assigned(FOnMovido) then
FOnMovido(Self);
end;
Ala, un pasito mas, gracias a todos.
