unit uFormMagnet;
interface
uses
Classes, Forms, Messages, Windows;
type
TFormMagnet =
class(TComponent)
private
fPreviousLocation : TPoint;
fParentsOldWinProc : TWndMethod;
fParent : TCustomForm;
protected
procedure WindowProcHandler(
var message: TMessage);
virtual;
procedure OnMove(
var msg: TWMMove);
message WM_MOVE;
public
property Parent : TCustomForm
read fParent;
procedure AfterConstruction;
override;
procedure BeforeDestruction;
override;
end;
implementation
uses
Types;
{ TFormMagnet }
procedure TFormMagnet.AfterConstruction;
begin
inherited;
if Owner
is TCustomForm
then
begin
fParent := TCustomForm(Owner);
fParentsOldWinProc := Parent.WindowProc;
Parent.WindowProc := WindowProcHandler;
fPreviousLocation := Point(Parent.Left, Parent.Top);
end;
end;
procedure TFormMagnet.BeforeDestruction;
begin
inherited;
if Assigned(fParentsOldWinProc)
then
Parent.WindowProc := fParentsOldWinProc;
end;
procedure TFormMagnet.WindowProcHandler(
var message: TMessage);
begin
if message.Msg = WM_MOVE
then
OnMove(TWMMove(
message));
if Assigned(fParentsOldWinProc)
then
fParentsOldWinProc(TMessage(
message));
end;
procedure TFormMagnet.OnMove(
var msg: TWMMove);
var
i : Integer;
form : TCustomForm;
begin
for i := 0
to Screen.FormCount - 1
do
begin
form := Screen.Forms[i];
if form <> Parent
then
begin
// Differenz zwischen alter und neuer Position ebenfalls
// auf die anderen Fenster anwenden
form.Top := form.Top + (Parent.Top - fPreviousLocation.y);
form.Left := form.Left + (Parent.Left - fPreviousLocation.x);
end;
end;
fPreviousLocation := Point(Parent.Left, Parent.Top);
end;
end.