Johan
Johan

Reputation: 47

Delphi 7 - 2nd form can follow the position of the mainform

How can I make a second form can follow the position of the main form wherever the main form shifted. for example, can be seen in this GIF image:

Screen capture video of moving one form and a second following its movements

I tried using this delphiDabbler tip, which is to stop a form moving, but did not manage to get something that worked.

Upvotes: 0

Views: 1618

Answers (2)

smooty86
smooty86

Reputation: 1112

Handle WM_WINDOWPOSCHANGING to move your other form(s) at the same time.

  ...

   public
     OldTop, OldLeft: Integer;
     procedure WindowPosChanging(var Msg: TWMWindowPosChanging);
       message WM_WINDOWPOSCHANGING;
   end;

   ...

 implementation

   ...

 procedure TForm1.WindowPosChanging(var Msg: TWMWindowPosChanging);
 var
     DTop, DLeft: Integer;
 begin      
   // well and here inside of you put the relationship of like you 
   // want him to move.   

   // an example of this moving them in the same sense can be...

   if (Form2 = nil) or (not Form2.Visible) then Exit;

   // this line is to avoid the error of calling them when the forms 
   // are creating or when they are not visible...

   DTop := Top - OldTop;
   DLeft := Left - OldLeft;

   Form2.Top := Form2.Top + DTop;
   Form2.Left := Form2.Left + DLeft;

   OldTop := Top;
   OldLeft := Left;

   inherited;
 end;

Source: http://delphi.cjcsoft.net/viewthread.php?tid=43047
(original code updated according to suggestions in comments)

Or something like this Two forms to snap each other

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 613013

In the main form you need this:

type
  TMainForm = class(TForm)
  protected
    procedure WMWindowPosChanged(var Msg: TWMWindowPosChanged); 
      message WM_WINDOWPOSCHANGED;
  end;

....

procedure TMainForm.WMWindowPosChanged(var Msg: TWMWindowPosChanged);
begin
  inherited;
  if Assigned(OtherForm) and not Application.Terminated then
  begin
    OtherForm.Left := Left + Width;
    OtherForm.Top := Top;
  end;
end;

This ensures that whenever the main form's position changes, the other form clamps to it. Note that this message can be sent before the other form is created, and after it is no longer valid. Hence the if statement.

And on the other form do this:

type
  TOtherForm = class(TForm)
  protected
    procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging); 
      message WM_WINDOWPOSCHANGING;
  end;

....

procedure TOtherForm.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
  inherited;
  if not Application.Terminated then
  begin
    Msg.WindowPos.x := MainForm.Left + MainForm.Width;
    Msg.WindowPos.y := MainForm.Top;
  end;
end;

This ensures that any attempts to move the other form are rejected.

Upvotes: 5

Related Questions