DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

フォームのサイズを制限する

ここでは、フォームの大きさ(サイズ)を制限する方法について説明します。

なおフォームのサイズを変更できないようにする方法は「フォームのサイズを変更できないようにする」で、フォームを最大化、最小化できないようにする方法は「フォームを最大化、最小化できないようにする」で説明しています。

補足:フォームのサイズをMaxWindowTrackSize以上にする方法は、「フォームのサイズをMaxWindowTrackSize(デスクトップ)以上にする」に移動しました。

最小サイズと最大サイズを設定する

フォームの最小サイズを設定するには、MinimumSizeプロパティを使用します。これにより、ユーザーがウィンドウをあまりに小さくしてしまうことを防ぐことができます。

また、MaximumSizeプロパティにより、最大サイズを設定できます。フォームが最大化された時も、このサイズより大きくはなりません。

プログラムによってフォームのサイズを変更する場合も、これらのプロパティの制約を受けます。

MaximumSizeプロパティのサイズは、システムで決められた上限値を超えて指定することができません。キャプションとサイズ変更境界があるウィンドウの既定の最大サイズは、SystemInformation.MaxWindowTrackSizeプロパティで取得できます(デスクトップ全体のサイズとなります)。

なお最小サイズと最大サイズをWindowsで設定されているサイズに戻すには、Size.Empty(サイズの高さと幅を0)にします。

以下にフォーム(自分自身)の最小サイズと最大サイズを設定する例を示します。

VB.NET
コードを隠すコードを選択
'このフォームの最小サイズを幅200、高さ100にする
Me.MinimumSize = New Size(200, 100)
'このフォームの最大サイズを幅400、高さ200にする
Me.MaximumSize = New Size(400, 200)
C#
コードを隠すコードを選択
//このフォームの最小サイズを幅200、高さ100にする
this.MinimumSize = new Size(200, 100);
//このフォームの最大サイズを幅400、高さ200にする
this.MaximumSize = new Size(400, 200);
補足:MinimumSizeで指定したサイズが小さすぎる時は、これがフォームの最小サイズにならないかもしれません。詳しくは掲示板のログをご覧ください。
補足:.NET Framework 1.0では、MDIの子フォームサイズをMinimumSizeやMaximumSizeにより制限することができません。対処法はマイクロソフトのサポート技術情報にあります。

サイズ変更後に修正する方法

フォームのサイズが変更された直後に、フォームのサイズを修正するという方法も考えられます。フォームのサイズが変更されたことは、「フォームの位置や大きさが変更されたことを知る」で紹介しているように、SizeChangedイベント、またはResizeイベントで知ることができます。

以下の例では、SizeChangedイベントを使用して、フォームが指定されたサイズを超えた時、サイズが小さくするようにしています。また、フォームの状態が最大化、最小化された時は元に戻すようにしています。

VB.NET
コードを隠すコードを選択
'SizeChangedイベントハンドラ
Private Sub Form1_SizeChanged(sender As Object, e As EventArgs) _
    Handles MyBase.SizeChanged

    'フォームが最小化、最大化された時は、元の状態に戻す
    If Me.WindowState = FormWindowState.Minimized OrElse _
        Me.WindowState = FormWindowState.Maximized Then

        Me.WindowState = FormWindowState.Normal
    End If

    'フォームの幅が400より大きくならないようにする
    If 400 < Me.Width Then
        Me.Width = 400
    End If
    'フォームの高さが200より大きくならないようにする
    If 200 < Me.Height Then
        Me.Height = 200
    End If
End Sub
C#
コードを隠すコードを選択
//SizeChangedイベントハンドラ
private void Form1_SizeChanged(object sender, EventArgs e)
{
    //フォームが最小化、最大化された時は、元の状態に戻す
    if (this.WindowState == FormWindowState.Minimized ||
        this.WindowState == FormWindowState.Maximized)
    {
        this.WindowState = FormWindowState.Normal;
    }

    //フォームの幅が400より大きくならないようにする
    if (400 < this.Width)
    {
        this.Width = 400;
    }
    //フォームの高さが200より大きくならないようにする
    if (200 < this.Height)
    {
        this.Height = 200;
    }
}

WM_SIZINGメッセージを利用する方法

サイズ変更後に修正する方法は、サイズが変更された後でまたサイズを変更していますので、見た目はよくありません。この欠点は、WM_SIZINGメッセージを利用すれば、解消されます。

WM_SIZINGメッセージの使用例は「フォームが移動できる範囲を制限する」の「WM_MOVINGメッセージを使用する方法」でも紹介していますので、そちらも参考にしてください。

以下の例では、この方法を使って、フォームのサイズが大きくなりすぎないようにしています。このコードは、フォームクラス内に記述してください。なおこの方法は、プログラムによってフォームの大きさが変えられた場合には対応していません。

VB.NET
コードを隠すコードを選択
'Imports System.Runtime.InteropServices
'Imports System.Security.Permissions

<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
    Public Left As Integer
    Public Top As Integer
    Public Right As Integer
    Public Bottom As Integer
End Structure

<SecurityPermission(SecurityAction.Demand, _
    Flags:=SecurityPermissionFlag.UnmanagedCode)> _
Protected Overrides Sub WndProc(ByRef m As Message)
    Const WM_SIZING As Integer = &H214

    If m.Msg = WM_SIZING Then
        'フォームの範囲を取得
        Dim rect As RECT = _
            CType(System.Runtime.InteropServices.Marshal.PtrToStructure( _
                    m.LParam, GetType(RECT)), RECT)

        'フォームが大きすぎる時は、小さくする
        If 400 < rect.Right - rect.Left Then
            rect.Right = rect.Left + 400
        End If
        If 200 < rect.Bottom - rect.Top Then
            rect.Bottom = rect.Top + 200
        End If

        'フォームの範囲を設定
        System.Runtime.InteropServices.Marshal.StructureToPtr( _
            rect, m.LParam, True)
    End If

    MyBase.WndProc(m)
End Sub
C#
コードを隠すコードを選択
//using System.Runtime.InteropServices;
//using System.Security.Permissions;

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

[SecurityPermission(SecurityAction.Demand,
    Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
    const int WM_SIZING = 0x214;

    if (m.Msg == WM_SIZING)
    {
        //フォームの範囲を取得
        RECT rect = (RECT)
            System.Runtime.InteropServices.Marshal.PtrToStructure(
            m.LParam, typeof(RECT));

        //フォームが大きすぎる時は、小さくする
        if (400 < rect.Right - rect.Left)
        {
            rect.Right = rect.Left + 400;
        }
        if (200 < rect.Bottom - rect.Top)
        {
            rect.Bottom = rect.Top + 200;
        }

        //フォームの範囲を設定
        System.Runtime.InteropServices.Marshal.StructureToPtr(
            rect, m.LParam, true);
    }

    base.WndProc(ref m);
}
  • 履歴:
  • 2015/5/18 「フォームのサイズをMaxWindowTrackSize以上にする」の内容を別のページに移動。「サイズ変更後に修正する方法」、「WM_SIZINGメッセージを利用する方法」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。