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:
Código Delphi
[-]
procedure TControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
if CheckNewSize(AWidth, AHeight) and
((ALeft <> FLeft) or (ATop <> FTop) or
(AWidth <> FWidth) or (AHeight <> FHeight)) then
begin
InvalidateControl(Visible, False);
FLeft := ALeft;
FTop := ATop;
FWidth := AWidth;
FHeight := AHeight;
UpdateAnchorRules;
UpdateExplicitBounds;
Invalidate;
Perform(WM_WINDOWPOSCHANGED, 0, 0);
RequestAlign;
if not (csLoading in ComponentState) then Resize;
end;
end;
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:
Código Delphi
[-]
published
property AdosadoA :TControl read Fcontrol write FControl;
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)
Código Delphi
[-]
procedure TComponentA.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = ComponentB) and
(Operation = opRemove) then
begin
ComponentB := nil ; end;
end;
Esto ya es un poco más lioso, pero bueno.
Saludos