フォームが移動したことを知る方法は「フォームの位置や大きさが変更されたことを知る」で説明していますが、ここではユーザーがフォームを移動し終えたことを知る方法について説明します。
「フォームのリサイズが終了するまでコントロールの大きさを変えない」ではユーザーがフォームのサイズを変更し終えたことをどうやって知るかについて説明しましたが、ここで紹介した方法が今回のケースでもほぼそのまま使えます。Application.Idleイベントを使った方法も使えますが、ここではそれ以外の方法について説明します。
.NET Framework 2.0からは、Form.ResizeEndイベントが追加されました。このイベントはフォームのサイズをユーザーが変更した時だけでなく、フォームを移動させた時にも発生します。よってこのイベントが発生した時、それがサイズの変更ではなく、移動の終了であることを確認しなければなりません。その方法としては、フォームのMoveイベントハンドラでフラッグを立てる方法や、ResizeBeginイベントが発生した時のフォームの位置を覚えておき、ResizeEndイベントが発生した時の位置と異なるか調べる方法などがあります。ここでは、Moveイベントを使った方法を紹介します。
Private moving As Boolean = False Protected Overrides Sub OnMove(ByVal e As EventArgs) MyBase.OnMove(e) 'フォームが表示されている時のみ有効とする If Me.Visible Then Me.moving = True End If End Sub 'フォームのResizeEndイベントハンドラ Private Sub Form1_ResizeEnd(ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.ResizeEnd If Me.moving Then Console.WriteLine("移動が終了しました") Me.moving = False End If End Sub
private bool moving = false; protected override void OnMove(EventArgs e) { base.OnMove(e); //フォームが表示されている時のみ有効とする if (this.Visible) this.moving = true; } //フォームのResizeEndイベントハンドラ private void Form1_ResizeEnd(object sender, EventArgs e) { if (this.moving) { Console.WriteLine("移動が終了しました"); this.moving = false; } }
.NET Framework 1.1以前の場合は、WM_EXITSIZEMOVEメッセージを使用する方法があります。ResizeEndイベントと同じで、これだけではフォームがリサイズされたのか移動させられたのかが分かりませんので、上記と同じ方法で判断する必要があります。なおフォームのリサイズ、移動の開始は、WM_ENTERSIZEMOVEメッセージで知ることができます。
'Imports System.Security.Permissions Private moving As Boolean = False Protected Overrides Sub OnMove(ByVal e As EventArgs) MyBase.OnMove(e) 'フォームが表示されている時のみ有効とする If Me.Visible Then Me.moving = True End If End Sub Private Const WM_EXITSIZEMOVE As Integer = &H232 <SecurityPermission(SecurityAction.Demand, _ Flags:=SecurityPermissionFlag.UnmanagedCode)> _ Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = WM_EXITSIZEMOVE AndAlso Me.moving Then Console.WriteLine("移動が終了しました") Me.moving = False End If MyBase.WndProc(m) End Sub
//using System.Security.Permissions; private bool moving = false; protected override void OnMove(EventArgs e) { base.OnMove(e); //フォームが表示されている時のみ有効とする if (this.Visible) this.moving = true; } private const int WM_EXITSIZEMOVE = 0x0232; [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref Message m) { if (m.Msg == WM_EXITSIZEMOVE && this.moving) { Console.WriteLine("移動が終了しました"); this.moving = false; } base.WndProc(ref m); }