ここでは、フォームが最大化、あるいは最小化状態の時、実際にフォームを通常状態に戻すことをせずに、通常状態時の位置と大きさ(サイズ)を取得する方法を紹介します。アプリケーション終了時にフォームの位置と大きさを保存しておきたい時に役に立ちます。
なおフォームの位置と大きさを取得する方法は「フォームの位置と大きさを取得、変更する」で、フォームの状態を調べる方法は「フォームの現在の状態(最大化、最小化)を調べる」で説明しています。
.NET Framework 2.0以降では、RestoreBoundsプロパティが使えます。
このプロパティは、現在のフォームの状態が最大化、あるいは最小化の時のみ有効です。通常状態の時は、無意味な値になります。
以下の例では、自分自身のフォームが現在通常状態の時はBoundsプロパティの値を表示し、それ以外(最大化、最小化状態)の時はRestoreBoundsプロパティの値を表示しています。
If Me.WindowState = FormWindowState.Normal Then 'フォームが通常状態の時は、現在の位置と大きさを表示 Console.WriteLine(Me.Bounds) Else 'フォームが最大化か最小化状態の時は、 ' 通常状態に戻った時の位置と大きさを表示 Console.WriteLine(Me.RestoreBounds) End If
if (this.WindowState == FormWindowState.Normal) { //フォームが通常状態の時は、現在の位置と大きさを表示 Console.WriteLine(this.Bounds); } else { //フォームが最大化か最小化状態の時は、 // 通常状態に戻った時の位置と大きさを表示 Console.WriteLine(this.RestoreBounds); }
.NET Framework 1.1以前でRestoreBoundsプロパティを使用できない場合は、通常状態のフォームの位置とサイズを覚えておくという方法があります。フォームの位置が変更されるとLocationChangedイベントとMoveイベントが、サイズが変更されるとSizeChangedイベントとResizeイベントが発生しますので(詳しくは、「フォームの位置や大きさが変更されたことを知る」)、その時フォームが通常状態だったら、位置とサイズを覚えておくようにします。
'フォームが通常状態の時の位置とサイズ Private normalLocation As Point Private normalSize As Size 'フォームのLoadイベントハンドラ Private Sub Form1_Load(sender As Object, e As EventArgs) _ Handles MyBase.Load 'はじめのフォームの位置とサイズを覚えておく '(この時フォームは通常状態である必要がある) Me.normalLocation = Me.Location Me.normalSize = Me.Size End Sub 'フォームのLocationChangedイベントハンドラ Private Sub Form1_LocationChanged(sender As Object, e As EventArgs) _ Handles MyBase.LocationChanged 'フォームが通常状態だったら、位置を覚えておく If Me.WindowState = FormWindowState.Normal Then Me.normalLocation = Me.Location End If End Sub 'フォームのSizeChangedイベントハンドラ Private Sub Form1_SizeChanged(sender As Object, e As EventArgs) _ Handles MyBase.SizeChanged 'フォームが通常状態だったら、サイズを覚えておく If Me.WindowState = FormWindowState.Normal Then Me.normalSize = Me.Size End If End Sub
//フォームが通常状態の時の位置とサイズ private Point normalLocation; private Size normalSize; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //はじめのフォームの位置とサイズを覚えておく //(この時フォームは通常状態である必要がある) this.normalLocation = this.Location; this.normalSize = this.Size; } //フォームのLocationChangedイベントハンドラ private void Form1_LocationChanged(object sender, EventArgs e) { //フォームが通常状態だったら、位置を覚えておく if (this.WindowState == FormWindowState.Normal) { this.normalLocation = this.Location; } } //フォームのSizeChangedイベントハンドラ private void Form1_SizeChanged(object sender, EventArgs e) { //フォームが通常状態だったら、サイズを覚えておく if (this.WindowState == FormWindowState.Normal) { this.normalSize = this.Size; } }
また、GetWindowPlacement functionを使用するという方法もあります。ただしこの関数はデスクトップ座標で位置を返すようで、タスクバーが画面の左や上にある場合は、フォームのLeftやTopプロパティとは違った値になってしまいます。なおフォームの位置をデスクトップ座標で設定する方法は、「フォームの位置と大きさを取得、変更する」で説明しています。
この方法で、通常状態のフォームの位置とサイズを返すメソッドの例を以下に示します。
'Imports System.Runtime.InteropServices <DllImport("user32.dll")> _ Private Shared Function GetWindowPlacement( _ hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As _ <MarshalAs(UnmanagedType.Bool)> Boolean End Function Private Structure WINDOWPLACEMENT Public length As Integer Public flags As Integer Public showCmd As Integer Public ptMinPosition As Point Public ptMaxPosition As Point Public rcNormalPosition As Rectangle End Structure 'このメソッドがあるフォームの通常状態時の位置とサイズを返す Public Function GetNormalBounds() As Rectangle Dim wp As New WINDOWPLACEMENT() wp.length = Marshal.SizeOf(wp) GetWindowPlacement(Me.Handle, wp) 'rcNormalPositionのWidthがRight、HeightがBottomとなっているので、修正 Return New Rectangle( _ wp.rcNormalPosition.X, _ wp.rcNormalPosition.Y, _ wp.rcNormalPosition.Width - wp.rcNormalPosition.X, _ wp.rcNormalPosition.Height - wp.rcNormalPosition.Y) 'または、以下のようにしても同じ 'Return Rectangle.FromLTRB( _ ' wp.rcNormalPosition.X, _ ' wp.rcNormalPosition.Y, _ ' wp.rcNormalPosition.Width, _ ' wp.rcNormalPosition.Height) End Function
//using System.Runtime.InteropServices; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowPlacement( IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); private struct WINDOWPLACEMENT { public int length; public int flags; public int showCmd; public Point ptMinPosition; public Point ptMaxPosition; public Rectangle rcNormalPosition; } //このメソッドがあるフォームの通常状態時の位置とサイズを返す public Rectangle GetNormalBounds() { WINDOWPLACEMENT wp = new WINDOWPLACEMENT(); wp.length = Marshal.SizeOf(wp); GetWindowPlacement(this.Handle, ref wp); //rcNormalPositionのWidthがRight、HeightがBottomとなっているので、修正 return new Rectangle( wp.rcNormalPosition.X, wp.rcNormalPosition.Y, wp.rcNormalPosition.Width - wp.rcNormalPosition.X, wp.rcNormalPosition.Height - wp.rcNormalPosition.Y); //または、以下のようにしても同じ //return Rectangle.FromLTRB( // wp.rcNormalPosition.X, // wp.rcNormalPosition.Y, // wp.rcNormalPosition.Width, // wp.rcNormalPosition.Height); }