フォームの移動・リサイズ完了を検出する - C#
フォームの移動やリサイズの完了を検出する方法を紹介します。
UI
下図のUIを準備します。
コード
下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FormMoveComplete
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void FormMain_ResizeEnd(object sender, EventArgs e)
{
textBox1.Text += "移動、リサイズが完了しました。\r\n";
}
}
}
解説
フォームのResizeEndイベントを実装します。フォームの移動やリサイズの完了時にResizeEndイベントが発生します。イベントが発生したらテキストボックスにメッセージを表示します。
実行結果
アプリケーションを実行します。下図のウィンドウが表示されます。
ウィンドウをリサイズします。リサイズ完了時にテキストボックスにメッセージが表示されます。
ウィンドウを移動します。ウィンドウの移動が完了するとテキストボックスにメッセージが表示されます。
Windowsメッセージから判定する方法
Windowsメッセージを判定する方法でもウィンドウの移動完了を検出できます。
コード
以下のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FormMoveComplete
{
public partial class FormMain : Form
{
private const int WM_EXITSIZEMOVE = 0x0232;
public FormMain()
{
InitializeComponent();
}
protected override void WndProc(ref Message msg)
{
if (msg.Msg == WM_EXITSIZEMOVE) {
textBox1.Text += "移動、リサイズが終了\r\n";
}
base.WndProc(ref msg);
}
}
}
解説
WndProcメソッドをオーバーライドし、Windowsメッセージを取得します。
if (msg.Msg == WM_EXITSIZEMOVE) {
textBox1.Text += "移動、リサイズが終了しました\r\n";
}
Windowsメッセージが"EM_EXITSIZEMOVE"であれば、ウィンドウの移動が終了したことを示すWindowメッセージであるため、ウィンドウの移動が終了した旨をテキストボックスに表示します。
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
ウィンドウをリサイズします。リサイズ完了時にテキストボックスにメッセージが表示されます。
タイトルバーをドラッグしてウィンドウを移動させます。ウィンドウの移動の完了時にテキストボックスにメッセージが表示されます。
移動、リサイズのみを検出する方法
上記の方法では移動とリサイズの両方でイベントが発生します。移動、リサイズのみを検出する方法を紹介します。
フォームのResizeEndイベントを用いる方法
コード
下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FormMoveResizeComplete
{
public partial class FormMain : Form
{
private const int WM_EXITSIZEMOVE = 0x0232;
private bool move_flag = false;
private bool resize_flag = false;
public FormMain()
{
InitializeComponent();
}
private void FormMain_ResizeEnd(object sender, EventArgs e)
{
if (move_flag ==true) {
textBox1.Text += "移動が完了しました。\r\n";
move_flag = false;
}
else if (resize_flag == true) {
textBox1.Text += "リサイズが完了しました。\r\n";
resize_flag = false;
}
}
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if (Visible == true) move_flag = true;
}
protected override void OnResize (EventArgs e)
{
base.OnResize(e);
if (Visible == true) resize_flag = true;
}
}
}
解説
OnMove時、OnResize時にそれぞれのフラグを立てることで、ResizeEndイベント発生時にリサイズか移動どちらの操作であったのかを判別します。
実行結果
プロジェクトを実行します。下図の画面が表示されます。
ウィンドウを移動します。移動が完了するとテキストボックスに移動が完了した旨のメッセージが表示されます。
ウィンドウをリサイズします。リサイズした場合は、移動時と異なるメッセージが表示されウィンドウの移動とリサイズを別々に検出できています。
WM_EXITSIZEMOVE ウィンドウメッセージを検出する方法
コード
下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FormMoveResizeComplete
{
public partial class FormMain : Form
{
private const int WM_EXITSIZEMOVE = 0x0232;
private bool move_flag = false;
private bool resize_flag = false;
public FormMain()
{
InitializeComponent();
}
protected override void WndProc(ref Message msg)
{
if (msg.Msg == WM_EXITSIZEMOVE && move_flag) {
textBox1.Text += "移動完了\r\n";
move_flag = false;
}
else if (msg.Msg == WM_EXITSIZEMOVE && resize_flag) {
textBox1.Text += "リサイズ完了\r\n";
resize_flag = false;
}
base.WndProc(ref msg);
}
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if (Visible == true) move_flag = true;
}
protected override void OnResize (EventArgs e)
{
base.OnResize(e);
if (Visible == true) resize_flag = true;
}
}
}
解説
ResizeEndイベントを用いる方法と同様に、OnMove,OnResizeメソッドをオーバーライドしそれぞれでフラグを立て、ウィンドウメッセージ検出時にフラグを判断してウィンドウの移動かリサイズかを判定します。
実行結果
プロジェクトを実行します。下図の画面が表示されます。
ウィンドウを移動します。移動が完了するとテキストボックスに移動が完了した旨のメッセージが表示されます。
ウィンドウをリサイズします。リサイズした場合は、移動時と異なるメッセージが表示されウィンドウの移動とリサイズを別々に検出できています。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用