Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2008年01月13日] [更新 2012年01月19日] Delphi サンプルプログラム集
125_2 つのフォームを同時に移動
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
Windows 7 U64(SP1) + Delphi XE2 Pro VCL-32, VCL-64
125_CloseForms.zip [539 KB] 2012年01月19日版 (EXE 同梱)



  • 2012年01月19日
  • コード整備と動作確認環境変更




2 つのフォームを同時に移動


メインフォームである Form1 を移動すると,子フォームである Form2 もお互いの位置関係を保って移動するサンプルです.ただそれだけです.
ある掲示板で質問のあった回答として作成したものです.

以下のコードはシンプルですが,同時に移動するだけでなく,子フォームに対して操作が必要な場合は,メッセージによる処理やサブクラス化の方法も考える必要があるかも知れません.



図1
実行画面
  • メインフォーム (Form1) のボタンクリック
  • 子フォーム (Form2) が表示される
    Form2 はキャプションバーなし
  • Form1 を移動すると Form2 も移動
  • Form2 は単独で移動可能

リスト1
メインフォームのユニットのコード
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private 宣言 }
    procedure WWMove(var Msg: TWMMove); message WM_MOVE;
  public
    { Public 宣言 }
     DistanceX : Integer;
     DistanceY : Integer;
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

//=============================================================================
//  ボタンをクリックしたらサブフォームを表示
//  サブフォームのPositonプロパティはpoDesigned
//
//  [注意]
//  プロジェクトソースの
//    Application.MainFormOnTaskbar := False;
//  としておくこと
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;
  Form2.Left := Self.Left - 50;
  Form2.Top  := Self.Top  - 50;
end;

//=============================================================================
//  このFormが移動したらForm2も移動する
//=============================================================================
procedure TForm1.WWMove(var Msg: TWMMove);
begin
  if (Form2 <> nil) and (Form2.Visible) then begin
    MoveWindow(Form2.Handle,
               Self.Left - DistanceX,
               Self.Top  - DistanceY,
               Form2.Width,
               Form2.Height,
               True);
  end;
end;

//=============================================================================
//  このFormがActiveになったらForm2との位置の差を計算
//  この差を保つ様にForm2も移動する
//=============================================================================
procedure TForm1.FormActivate(Sender: TObject);
begin
  if (Form2 <> nil) and (Form2.Visible) then begin
    DistanceX := Self.Left- Form2.Left;
    DistanceY := Self.Top - Form2.Top;
  end;
end;

end.


リスト2
子フォームのユニットのコード
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm2 = class(TForm)
  private
    { Private 宣言 }
  protected
    procedure CreateParams(var Params : TCreateParams); override;
    procedure WMLBUTTONDOWN(var message: TWMLBUTTONDOWN);message WM_LBUTTONDOWN;
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

{ TSubForm }

//=============================================================================
//  サブフォームとしてのこのフォームはキャプションバーなしとする
//=============================================================================
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  //この値を変えればウィンドウのスタイルが変わる
  Params.Style := WS_POPUP or WS_BORDER;
end;

//=============================================================================
//  フォームの任意の位置でフォームの移動を可能に
//=============================================================================
procedure TForm2.WMLBUTTONDOWN(var message: TWMLBUTTONDOWN);
begin
  SendMessage(Handle, WM_SYSCOMMAND, SC_MOVE or 2, 0);
end;

end.