WisdomSoft - for your serial experiences.

2.2 座標、サイズ、色

Windows フォームおよび GDI+ において、座標やサイズ、長方形領域、色などを設定するための基本的なデータ型を紹介します。

2.2.1 ピクセルと座標

フォームを表示させたり、図形を描画するには、画面上のどこに表示するのか、どのくらいの幅や高さを持つのかという情報を設定する必要があります。画面上の特定の位置は、特定の原点からどれだけの距離が離れているかを数値で表します。これを座標と呼び、通常は画面の左上隅を原点 0 と考え、水平に X 座標、垂直に Y 座標を持ちます。

原点である画面左上隅は、X 座標、Y 座標ともに 0 なので (0, 0) であると表現できます。X 座標の値が増えるほどより(画面向かって)右側に、Y 座標の値が増えるほどより下に向かいます。X 座標が負数になれば画面左隅よりもさらに左側に、Y 座標が負数になれば画面上隅よりさらに上を表しています。

図1 ピクセル座標系
図1 ピクセル座標系

ディスプレイのようなラスタデバイスはピクセルと呼ばれる小さな点の集合で表されています。1つの座標は1つのピクセルに対応しています。すなわち座標 (400, 300) とした場合は、デバイス左上隅から右に 400 ピクセル、下に 300 ピクセルの位置を表します。

図2 ピクセルと座標
図2 ピクセルと座標

上図は、矩形1マスが1ピクセルとして考えてピクセルと座標の関係を表しています。実際には、ディスプレイ上の 1 ピクセルはとても小さいため人間の目には小さな点にしか見えません。例えば、画面解像度が 1024 × 768 に設定されている場合は、横に 1024 ピクセル、縦に 768 ピクセルまで存在することになります。

2.2.2 スクリーン座標とクライアント座標

グラフィックスやコントロールの位置を指定する場合、スクリーン座標クライアント座標のどちらなのか注意する必要があります。スクリーン座標とはデバイス全体を対象にした絶対座標です。ディスプレイ左上隅を原点 (0, 0) と考えて座標を指定します。例えば、アプリケーションのメインウィンドウの座標を指定する場合はスクリーン座標となります。

これに対してクライアント座標は、親コントロールの左上隅を原点 (0, 0) とする相対座標です。何らかのコントロールの子コントロールの座標を指定する場合や、特定のコントロールに図形を描画する処理で指定する座標はクライアント座標となります。

図3 スクリーン座標とクライアント座標
図3 スクリーン座標とクライアント座標

2.2.3 フォームの初期座標

フォームを表示させるとき、最初にデスクトップ上のどこに表示させるかという問題があります。デフォルトでは、最初にフォームが表示されるときは Windows が既定の位置に自動的に設定します。これは、Form クラスの StartPosition プロパティで設定されています。Windows 既定の位置ではなく、自分でウィンドウの表示位置を指定したい場合は、まずこの StartPosition プロパティを変更する必要があります。

Form クラス StartPosition プロパティ
public FormStartPosition StartPosition { get; set; }

このプロパティの値は System.Windows.Forms.FormStartPosition 列挙体のいずれかのメンバでなければなりません。FormStartPosition 列挙体には以下のようなメンバが宣言されています。

System.Windows.Forms.FormStartPosition 列挙体のメンバ
メンバ名 説明
CenterParent 親フォームの境界内の中央に配置する。
CenterScreen 現在の表示の中央に配置する。
Manual Location プロパティで指定されている位置に配置する。
WindowsDefaultBounds Windows の既定位置と既定のサイズで配置する。
WindowsDefaultLocation Windows の既定位置、Size プロパティの大きさで配置する

デフォルトでは WindowsDefaultLocation メンバがフォームの開始位置として設定されています。例えば、これを CenterScreen メンバに変更することで、常に画面の中央にウィンドウを表示するように設定することができます。 

コード1
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.StartPosition = FormStartPosition.CenterScreen;
		Application.Run(form);
	}
}

コード1は、アプリケーションのメインウィンドウを常に画面中央に配置するプログラムです。この場合、座標を計算しなくても Form オブジェクトの StartPosition プロパティを設定するだけなので非常に簡単であることがわかります。

2.2.4 座標を指定する

Windows 既定の座標や画面中央などではなく、指定した特定の座標にフォームを表示させるには、フォームの Top プロパティ及び Left プロパティを設定します。Top プロパティは、クライアント座標でコントロールの上端の座標をピクセル単位で指定します。同様に left プロパティは、コントロール左端の座標を指定します。

Control クラス Top プロパティ
public int Top { get; }
Control クラス Left プロパティ
public int Left { get; }

これら Top 及び Left プロパティは System.Windows.Control クラスで定義されています。Form クラスを含めたすべての GUI コントロールは Control クラスを継承しているので、共通してこうした設定用プロパティを利用することができます。 

コード2
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.StartPosition = FormStartPosition.Manual;
		form.Left = 400;
		form.Top = 300;
		Application.Run(form);
	}
}

コード2では、Form オブジェクトを表示させる前に、StartPosition を Manual に設定した後、Left と Top プロパティをそれぞれ設定しています。このプログラムを実行すると、表示されるウィンドウの初期座標が必ずスクリーン座標 (400, 300) であることが確認できます。

2.2.5 座標オブジェクト

コード2では、フォームの座標をそれぞれ X 座標 を Left プロパティで、Y 座標 を Top プロパティで個別に設定しました。この場合は直接数値型で座標を設定しますが、2次元座標とは X 座標と Y 座標を組み合わせてひとつのものだと考えられるため、2次元平面上の点を表す X 及び Y 値はペアで扱うべきでしょう。

.NET では、描画に関連するクラスや構造体を System.Drawing 名前空間に配置しています。2次元座標を表すには System.Drawing.Point 構造体を利用します。この構造体は X 座標と Y 座標を表す整数をペアで管理します。

System.Drawing.Point 構造体
System.Object
  System.ValueType
    System.Drawing.Point
[Serializable]
[ComVisible(true)]
public struct Point

Point 構造体は、コンストラクタで X 座標と Y 座標を整数で受け取ります。

Point 構造体のコンストラクタ
public Point(int x, int y);

コンストラクタで指定した x 及び y 値は、Point オブジェクトの X プロパティY プロパティから設定または取得することができます。Point 構造体は、コントロールの座標の設定以外でも、図形を描画するときの処理で図の開始座標などを指定するオブジェクトとして利用されるので、グラフィカル処理における基本的な情報提供オブジェクトのひとつです。

Point 構造体 X プロパティ
public int X { get; set; }
Point 構造体 Y プロパティ
public int Y { get; set; }

Control オブジェクトの座標を設定するには Left や Top プロパティを個別に設定する以外に Location プロパティで設定する方法があります。Location プロパティは Point オブジェクトでコントロールの現在の座標を設定または取得することができます。

Control クラス Location プロパティ
public Point Location { get; set; }

個別に座標を設定したり、個別に座標を取得するよりも、座標オブジェクトを用いて設定または取得した方が多くのケースではスマートなコードになるでしょう。 

コード3
using System.Drawing;
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.StartPosition = FormStartPosition.Manual;
		form.Location = new Point(400, 300);
		Application.Run(form);
	}
}

今後、様々な場面で Point オブジェクトを利用することになります。

2.2.6 幅と高さ

コントロールの幅や高さも、座標と同様にピクセル単位の数値で設定することができます。幅や高さは座標ではなく、コントロールの左上隅から数えたピクセル数となります。幅の場合はコントロールの左端からのピクセル数、高さの場合はコントロールの上隅からのピクセル数となります。

幅を設定するには Control クラスの Width プロパティ、高さを設定するには Height プロパティを利用します。

Control クラス Width プロパティ
public int Width { get; set; }
Control クラス Height プロパティ
public int Height { get; set; }

それぞれ、現在のコントロールの幅や高さを設定または取得します。フォームに対して設定すれば、表示されるウィンドウの幅と高さを変更できます。

コード4
using System.Drawing;
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.Width = 600;
		form.Height = 100;
		Application.Run(form);
	}
}
実行結果
コード4 実行結果

コード4では、幅 600 ピクセル、高さ 100 ピクセルのウィンドウを生成しています。デフォルトに比べて、横に長いウィンドウが表示されることがわかります。

2.2.7 サイズオブジェクト

サイズもまた、座標と同じように幅と高さで一組となる情報なのでひとつのオブジェクトとして表現するべきです。座標を Point 構造体で表すことができたように、幅と高さは System.Drawing.Size 構造体で表すことができます。

System.Drawing.Size 構造体
System.Object
  System.ValueType
    System.Drawing.Size
[Serializable]
[ComVisible(true)]
public struct Size

Size 構造体は、コンストラクタで幅 width と高さ height を受け取ります。それぞれ、整数によるピクセル値を指定します。

Size 構造体のコンストラクタ
public Size(int width, int height)

コンストラクタで設定した幅は Width プロパティ、高さは Hieght プロパティから取得することができます。

Size 構造体 Width プロパティ
public int Width { get; set; }
Size 構造体 Height プロパティ
public int Height { get; set; }

Size 構造体を使うことで、幅と高さをひとつのオブジェクトとして扱うことができるようになります。Control クラスでは、コントロールのサイズを Size オブジェクトを使って設定または取得することができる Size プロパティを用意しています。 

Control クラス Size プロパティ
public new Size Size { get; set; }

Size プロパティに Size オブジェクトを設定することで、ウィンドウの幅を変更することができます。 

コード5
using System.Drawing;
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.Size = new Size(600, 100);
		Application.Run(form);
	}
}

コード5は、コード4と同じ結果になるプログラムですが、フォームの幅と高さを Size プロパティから設定しています。Size オブジェクトは幅 600 ピクセル、高さ 100 ピクセルを指定しています。

2.2.8 矩形オブジェクト

座標とサイズを組み合わせることで、ひとつの矩形を表現することができます。フォームもひとつの矩形なので、ウィンドウの座標とサイズを一組にした情報があれば一度にウィンドウの座標とサイズ(すなわちウィンドウの矩形)を設定したり、取得することができます。

Control クラスは Location や Size プロパティから位置とサイズを設定することができましたが、これを同士に設定したり取得する Bounds プロパティが存在します。

Control クラス Bounds プロパティ
public Rectangle Bounds { get; set; }

Bounds プロパティから矩形を表すオブジェクトを設定したり取得することができます。矩形は System.Drawing.Rectangle 構造体で表現することができます。このクラスは、単純に座標とサイズをパックしたクラスです。

System.Drawing.Rectangle 構造体
System.Object
    System.ValueType
        System.Drawing.Rectangle
[Serializable]
[ComVisible(true)]
public struct Rectangle

このクラスのコンストラクタは、Point と Size オブジェクトを受けてこれらを組み合わせて矩形を定義する方法と、単純に X 座標、Y 座標、幅、高さをそれぞれ個別に int 型で受ける方法があります。

Rectangle クラスのコンストラクタ
public Rectangle(Point location, Size size)
public Rectangle( int x, int y, int width, int height )

location パラメータには左上隅を表す座標を、size パラメータにはサイズを指定します。

x パラメータと y パラメータには左上隅を表す X 座標と Y 座標を、width パラメータに幅、height パラメータに高さを指定します。Point クラスと Size クラスを理解していれば説明は不要でしょう。

また、Rectangle クラスは Point クラスと Size クラスのように、X、Y、Width、Height プロパティを保有しています。Rectangle オブジェクトから座標やサイズを取得したり変更したい場合はこれらのプロパティを利用してください。 

コード6
using System.Drawing;
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.StartPosition = FormStartPosition.Manual;
		form.Bounds = new Rectangle(300, 10, 400, 100);
		Application.Run(form);
	}
}

コード6は、表示するフォームの位置とサイズを Bounds プロパティから設定しています。位置とサイズを両方とも変更する場合は、個別に設定するよりも Bounds プロパティから一度に変更してしまった方が便利です。

2.2.9 背景色を指定する

Form オブジェクトのデフォルトの背景色はシステムに設定されているコントロールの色ですが、これを任意の色に変更することで、フォームのクライアント領域の色を指定することができます。コントロールの背景色は Control クラスの BackColor プロパティで設定・取得することができます。

Control クラス BackColor プロパティ
public virtual Color BackColor { get; set; }

このプロパティが要求する型は Color 構造体型のオブジェクトです。System.Drawing や System.Windows.Forms 名前空間で色を指定するときは、この System.Drawing.Color 構造体を使います。

System.Drawing.Color 構造体
System.Object
    System.ValueType
        System.Drawing.Color
[Serializable]
[ComVisible(true)]
public struct Color

Color 構造体は、色をアルファ、赤、緑、青の 4 つの要素に分割して管理しています。それぞれの値は 0 ~ 255 間での範囲で 0 がまったく色の無い状態を表し、255 が最も明るい状態を表します。アルファは、色の不透明度を表すもので 0 が完全な透明を、255 が不透明を表します。

Color オブジェクト生成するには、コンストラクタではなく Color 構造体の静的な FromArgb() メソッドを使います。

Color 構造体 FromArgb() メソッド
public static Color FromArgb(int red, int green, int blue)
public static Color FromArgb(int alpha,int red,int green,int blue)

alpha パラメータにはアルファ値を、red パラメータには赤要素、green パラメータには緑要素、blue パラメータには青要素の値を、それぞれ指定します。この組み合わせによって様々な色を表現することができます。例えば黄色を表すオブジェクトを作るには Color.FromArgb(0xFF, 0xFF, 0) というように、赤要素と緑要素を組み合わせます。

Color オブジェクトの色は、アルファを A プロパティ、赤要素を R プロパティ、緑要素を G プロパティ、青要素を B プロパティから取得できます。

Color 構造体 A プロパティ
public byte A { get; }
Color 構造体 R プロパティ
public byte R { get; }
Color 構造体 G プロパティ
public byte G { get; }
Color 構造体 B プロパティ
public byte B { get; }

これらのプロパティは読み取り専用です。

コード7
using System.Drawing;
using System.Windows.Forms;

public class Test
{
	static void Main() 
	{
		Form form = new Form();
		form.BackColor = Color.FromArgb(0x80, 0x80, 0xFF);
		Application.Run(form);
	}
}
実行結果
コード7 実行結果

コード7は、表示するフォームの BackColor プロパティに薄いブルーを表す Color オブジェクトを設定しています。デフォルトの色とは異なる背景色が設定されていることがわかります。

Color 構造体は、FromArgb() メソッド以外に一般的な色を静的な読み取り専用プロパティとして提供しています。黒ならば Color.Black、赤ならば Color.Red と指定することができます。このほかにも多くの固定色を読み取り専用プロパティで提供しているので必要なときはドキュメントを参照してください。