Seth Grossman
Visual Studio Team
Microsoft Corporation
January 2002
日本語版最終更新日 2003 年 5 月 6 日
要約 : WindowsR のフォームとコントロールの形状をカスタマイズする作業は簡単です。フォームは、イメージ ファイルといくつかのプロパティ設定のみで標準以外の形状にカスタマイズできます。また、コントロールの形状のカスタマイズに必要なのは、数行のコードのみです。
目次
はじめに
手順
フォームの形状を変更する
コントロールの形状を変更する
その他の変更
まとめ
はじめに
以前のバージョンの MicrosoftR Visual BasicR では、四角形以外のフォームやコントロールを作成することは、API 呼び出しや非常に高度なプログラミングを必要とする、時間と手間のかかる作業でした。
今後は、このような作業は必要はありません。Windows フォームの最も気の利いた機能の 1 つに、フォームを四角形以外の形状に変更できるという点があります。この機能は、Microsoft Windows MediaR Player 7 で採用されていますが、この機能を見た開発者の多くは間違いなく、これを自分のアプリケーションに取り入れたいと思うでしょう。
また、いろいろな形のコントロールをフォームに描画することができます。四角形以外のフォームやコントロールを使用したアプリケーションは、標準のウィンドウやコントロールに慣れたユーザーの目を引く、ほかとは違った外観になります。
Windows フォームとコントロールは両方とも、自由な形状に描画することができます。この文書では、不規則な形状をしたフォームを作成して、このフォーム上に従来とは異なる形状のコントロールを作成する方法について説明します。
注 : このプロセスには、多くのグラフィック関連のプログラミングが関係します。この結果、コンピュータの動作は、装備されているメモリやグラフィック カードによって異なります。自由に描画されたフォームやコントロールを使用するアプリケーションは、ユーザーに配布する前に必ず各種のビデオ カードでテストし、十分なパフォーマンスが得られることを確認してください。
手順
ここでは、四角形以外のフォームを作成する手順について簡単に説明します。まず、ビットマップを作成します。完成したビットマップはフォームとなるため、フォーム上に配置するコントロールをすべて格納できる大きさにする必要があります。次に、いくつかのプロパティを設定して、このビットマップをフォームにします。
魅力的な形状のフォームの上部に従来の長方形のタイトル バーが表示されるのは不自然であるため、プロパティを設定してタイトル バーを削除します。しかし、タイトル バーを削除すると、フォームを移動したり閉じたりする機能など、タイトル バーに関連付けられているすべての機能が使用できなくなります。したがって、ユーザーがこれまでと同じ方法でフォームの操作を続けられるように、これらの機能を保持するためのコードを作成します。
Windows ベースのアプリケーションでフォームの形状をカスタマイズするには、以下の操作を行う必要があります。
- フォームの形状を設定するための .bmp ファイルを作成する。
- Windows アプリケーション プロジェクトを作成し、フォームの背景として .bmp を使用するようにプロパティを設定し、タイトル バーを削除する。
- タイトル バーの機能 (フォームを移動したり、閉じたりする機能など) を実行するためのコードを入力する。
フォームの形状を変更する
ここでは、標準以外の形状を持つフォームを作成する方法を、手順を追って説明します。
四角形以外の形状を持つビットマップを作成するには
Microsoft ペイントなど、ビットマップを描画するためのグラフィック プログラムを起動します。Microsoft ペイントを起動するには、[スタート] ボタンをクリックして [プログラム] をポイントし、[アクセサリ] の [ペイント] をクリックします。
Microsoft ペイントで、四角形以外の形状の図形を作成して 1 色で塗りつぶし、背景には別の色を使用して区別できるようにします。ここで描画する図形は最終的にはフォームになるため、必ず十分な大きさを設定します。
たとえば、次のようになります。
図 1
注 : 背景色は後で重要になるため、青などの覚えやすい色を選択します。
.bmp ファイルを保存します。
フォームの輪郭となるビットマップが作成できたら、プロジェクトを作成する準備は完了です。
プロジェクトを作成する
- Microsoft Visual StudioR .NET で Windows アプリケーション プロジェクトを作成します。詳細については、「Windows アプリケーション プロジェクトの作成」 を参照してください。
フォームの形状を確定するために背景を設定するには
Windows フォーム デザイナでフォームをクリックして、フォーカスを移動します。
プロパティ ウィンドウで次の操作を行います。
FormBorderStyle プロパティを None に設定する。
このプロパティにより、フォームからタイトル バーが削除されます。これで、フォームを閉じたり、画面上でフォームを移動したりする機能などの、タイトル バーの機能はすべて使えなくなります。ただし、この文書には、この問題を解決するためのコードが用意されています。
フォームの BackgroundImage プロパティを先ほど作成した .bmp に設定する。このファイルをプロジェクト システムに追加する必要はありません。この処理はファイルを背景イメージとして指定した時点で自動的に行われます。
このプロパティにより、ビットマップ イメージがフォームの背景になるように設定されます。このプロパティを、次に指定する TransparencyKey プロパティと共に使用することにより、フォームの形状が定義されます。
TransparencyKey プロパティを .bmp ファイルの背景色に設定する。上の例では、青に設定しています。
このプロパティで、透過色にするフォーム上の部分をアプリケーションに指定します。つまり、四角形から目的の形をしたフォームが "切り取られ" ます。
アプリケーションを保存し、F5 キーを押して実行します。
この Windows フォームを実行すると、先ほど作成したビットマップと同じような外観で表示されます。また、アプリケーションを移動したり閉じたりする際に使用するタイトル バーが表示されていないことに注意してください。Alt キーを押しながら F4 を押してアプリケーションを閉じ、開発を続けます。
FormBorderStyle を None に設定すると、タイトル バーの標準機能が使えなくなります。したがって、プロジェクトにカスタム コードを追加し、フォームを移動できるようにする必要があります。次の手順では、フォームを閉じるためのボタン コントロールを追加します。また、フォームを移動するためのコードの作成方法についても詳しく説明します。
フォームを移動するコードを作成するには
ツールボックスから、フォームにボタン コントロールをドラッグします。
プロパティ ウィンドウで、Text プロパティを "フォームを閉じる" に設定します。
このボタンをダブルクリックして、Click イベント ハンドラを追加します。
コード エディタが開きます。ボタンの Click イベント ハンドラの位置に挿入ポインタが表示されます。
ボタンがクリックされるとフォームを閉じるコードを次のように入力します。
' Visual Basic Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub
// C# private void button1_Click(object sender, System.EventArgs e) { this.Close(); }
- 次に、フォームをドラッグして移動するためのプロシージャを作成します。次のようなコードを入力し、Point オブジェクトを新しく作成します。このオブジェクトは、フォームの移動方法を計算する際に変数として機能します。
' Visual Basic Private mouse_offset As Point
// C# private Point mouse_offset;
フォームの MouseDown イベント用にイベント ハンドラを作成します。ここでは、ユーザーがフォームの任意の部分をクリックしてドラッグできるようにするためのコードを作成します。
Visual Basic を使用している場合は、コード エディタの最上部に表示される [クラス名] ボックスを使用してイベント ハンドラを作成し、[(Base Class Events)] を選択します。[メソッド名] ボックスで [MouseDown] を選択します。
C# を使用している場合は、ソリューション エクスプローラでフォームを右クリックして [ビュー デザイナ] をクリックし、イベント ハンドラを作成します。プロパティ ウィンドウで、最上部にある稲妻の形をした [イベント] ボタンをクリックします。Load イベントに移動し、右側のボックスに「Form1_Load」と入力します。[戻る] をクリックして、このイベントに対するイベント ハンドラを作成します。
次のようなコードを入力し、マウスの現在位置に基づいて
mouse_offset
変数に座標を割り当てます。' Visual Basic
Private Sub Form1_MouseDown(sender As Object, _ e As System.Windows.Forms.MouseEventArgs) _ Handles MyBase.MouseDown mouse_offset = New Point(- e.X, - e.Y) End Sub
// C# private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { mouse_offset = new Point(-e.X, -e.Y); }
フォームの MouseMove イベントに対するイベント ハンドラを作成します。
次のようなコードを入力します。マウスの左ボタンをクリックしてドラッグすると、フォームの Location プロパティが新しい位置に設定されます。
' Visual Basic
Private Sub Form1_MouseMove(sender As Object, _ e As System.Windows.Forms.MouseEventArgs) _ Handles MyBase.MouseMove If e.Button = MouseButtons.Left Then Dim mousePos As Point = Control.MousePosition mousePos.Offset(mouse_offset.X, mouse_offset.Y) Location = mousePos End If End Sub
// C# private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point mousePos = Control.MousePosition; mousePos.Offset(mouse_offset.X, mouse_offset.Y); Location = mousePos; } }
アプリケーションを保存し、F5 キーを押して実行します。このフォームの形状は、最初に描画した画像と同じように表示されます。
フォーム上の任意の場所をクリックしてドラッグし、移動することを確認します。[フォームを閉じる] ボタンをクリックし、フォームを閉じます。
ここまでは、フォームの形状の変更について説明しましたが、さらに、コントロールの形状も変更することができます。次に、自由な形状を持つコントロールを作成してみましょう。
コントロールの形状を変更する
このセクションでは、自由な形状を持つコントロールの作成方法について説明します。コントロールには TransparencyKey プロパティがないため、別の方法を使ってきれいな形に仕上げます。
前のセクションでは、イメージと、画面の透明な部分を使って、フォームの形状を "切り抜き" ましたが、自由な形状を持つコントロールは別の方法で描画します。自由な形状を持つコントロールを描画する場合、フォームに対してコントロールの描画方法を指示し、コントロールを描画する画面上の正確な座標位置と描画方法を指定します。このような作業に不安があっても心配する必要はありません。.NET Framework には、このようなカスタム描画を簡単に実行できるようにするクラスやメソッドが用意されています。
四角形以外のコントロール
コントロールが描画される画面上のエリアは、1 つの領域 (Region) と見なすことができます。.NET Framework のクラスは、コントロールに、そのコントロールの描画方法に関する指示を与えます。さまざま指示を指定することにより、思い通りにコントロールを描画できます。
指示には GraphicsPath クラスを利用します。このクラスは、図形の描画に使用できる連続した直線や曲線を表します。まず、GraphicsPath クラスのインスタンスを指定し、どのような図形を描画するかを指示します。次に、コントロールの Region プロパティを GraphicsPath クラスのインスタンスに設定します。この作業のみで、独特のインターフェイスを持つコントロールを作成することができます。
ここで、Windows フォーム コントロールの形状をカスタマイズするために必要な手順を復習してみましょう。
- GraphicsPath クラスのインスタンスを作成する。
- サイズや形などの GraphicsPath の詳細を指定し、希望する形状を持つコントロールを描画する。
- コントロールの Region プロパティを GraphicsPath クラスのインスタンスに設定する。
コントロールには、さまざまな形を設定することができます。このセクションでは、"ここをクリック" という形のボタンを作成する方法について説明します。
テキストの形をしたボタンを作成するには
ツールボックスから、フォームにボタン コントロールをドラッグします。
プロパティ ウィンドウで次の操作を行います。
- Name プロパティを CustomButton に設定する。
- CustomButton の
BackColor
プロパティをフォームの背景と比較してコントラストがはっきりする色に設定する。 - CustomButton の
Text
プロパティを空の文字列に設定する。
フォームを右クリックして [コードの表示] を選択します。
フォームの Load イベントに対するイベント ハンドラを作成します。
コード エディタの最上部にある [クラス名] ボックスで、[CustomButton] を選択します。[メソッド名] ボックスの [Paint] を選択します。
次のようなコードを入力し、GraphicsPath クラスのインスタンスを使用して、カスタマイズされた方法でボタンの面を描画します。
以下のコードでは MS UI Gothic フォントでテキスト文字列としてボタンが描画されます。さらに、このコードでは、文字列のサイズやスタイルなど、その他の属性も指定されています。次に、この文字列は、GraphicsPath クラスのインスタンスに追加されます。最後に、GraphicsPath はボタンの Region プロパティに設定されます。上で説明したとおり、領域 (Region) は、画面上に定義された描画エリアです。
' Visual Basic
Private Sub CustomButton_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles CustomButton.Paint
' GraphicsPath クラスの新規インスタンスをインスタンス化します。
Dim myGraphicsPath As New System.Drawing.Drawing2D.GraphicsPath()
' 文字列を指定します。この文字列がコントロールの形状となります。
Dim stringText As String = "ここをクリック"
' 上の文字列に使用するフォントを指定します。
Dim family As FontFamily = New FontFamily("MS UI Gothic")
' 上の文字列に使用するフォント スタイルを指定します。
Dim fontStyle As FontStyle = fontStyle.Bold
' 次に、文字列の高さを指定します。
' この整数値は正方形の一辺を表します。
' 指定した文字列はこの正方形の内部に描画されます。
' より大きな文字列を描画するには整数値を大きくし、
' 小さくするには整数値を小さくします。
Dim emSize As Integer = 35
' 次にテキストの開始位置を表します。この位置は
' フォームではなく、コントロールの端から計算されます。
Dim origin As PointF = New PointF(0, 0)
' StringFormat オブジェクトには行間や位置揃えなど
' テキストの書式設定の情報を指定します。
Dim format As StringFormat = StringFormat.GenericDefault
' AddString メソッドを使用して上で指定した詳細が設定された
' 文字列を作成します。
myGraphicsPath.AddString(stringText, family, fontStyle, emSize, origin, format)
' コントロールの Region プロパティを、上で作成した
' GraphicsPath クラスのインスタンスに設定します。
CustomButton
.Region = New Region(myGraphicsPath)
End Sub
// C#
private void CustomButton
_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
// GraphicsPath クラスの新規インスタンスをインスタンス化します。
System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new
System.Drawing.Drawing2D.GraphicsPath();
// 文字列を指定します。 この文字列がコントロールの形状となります。
string stringText = "ここをクリック";
// 上の文字列に使用するフォントを指定します。
FontFamily family = new FontFamily("MS UI Gothic");
// 上記の文字列に使用するフォント スタイルを指定します。
// FontStyle enum を int としてキャストし、目的のフォントを
// 作成するときに、AddString メソッドが複数の FontStyle
// メンバを受け取れるようにします。
int fontStyle = (int)FontStyle.Bold;
// 次に文字列の高さを指定します。
// この整数値は正方形の一辺を表します。
// 指定した文字列はこの正方形の内部に描画されます。
// より大きな文字列を描画するには整数値を大きくし、
// 小さくするには整数値を小さくします。
int emSize = 35;
// これはテキストの開始位置を表すポイントです。 この位置は
// フォームではなく、コントロールの端から計算されます。
PointF origin = new PointF(0, 0);
// StringFormat オブジェクトには行間や位置揃えなど
// テキストの書式設定の情報を指定します。
StringFormat format = new StringFormat(StringFormat.GenericDefault);
// AddString メソッドを使用して上で指定した詳細が設定された
// 文字列を作成します。
myGraphicsPath.AddString(stringText, family, fontStyle, emSize, origin, format);
// コントロールの Region プロパティを、上で作成した
// GraphicsPath クラスのインスタンスに設定します。
CustomButton
.Region = new Region(myGraphicsPath);
}
> **注 :** GraphicsPath クラスは、フォームではなく、コントロールに対して描画を行うことに注意してください。図形を (0,0) の位置に描画すると、この図形はコントロールの左上隅の位置に配置されます。
ボタンの Click イベントに対するイベント ハンドラを作成します。実行時に外観を変更しても、ボタンの持つ標準機能は変わらないことを確認するために、Click イベント ハンドラにボタンの背景色を変更するコードを作成します。
コード エディタの最上部にある [クラス名] ボックスで、[CustomButton] を選択します。[メソッド名] ボックスの [Click] を選択します。
次のようなコードを入力して、ボタンの BackColor プロパティを変更します。
' Visual Basic Private Sub
CustomButton
_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) HandlesCustomButton
.ClickCustomButton
.BackColor = Color.BlanchedAlmond End Sub
// C#
private void CustomButton
_Click(object sender, System.EventArgs e)
{
CustomButton
.BackColor = Color.BlanchedAlmond;
}
アプリケーションを保存し、実行します。
このアプリケーションを実行すると、長方形のボタンの代わりに、"ここをクリック" という形状のボタンが表示されることがわかります。ボタンが表示されない場合は、アプリケーションを閉じて、フォームのサイズを大きくしてください。さらに、このボタンをクリックすると色が変わりますが、このボタンの機能自体は変わりません。
その他の変更
GraphicsPath クラスのインスタンスを使用した上の例では、文字列を指定し、この文字列を使用してコントロールの基本的な形状を決定しました。しかし、テキストの形ではなく、三角形や円など幾何学的な形をしたコントロールが必要な場合もあります。.NET Framework には、このような作業を行うために必要な機能も用意されています。
文字列を指定してボタンの形としてレンダリングする代わりに、.NET Framework であらかじめ定義された図形を使うことができます。これらの図形を組み合わせて使用することにより、コントロールの外観を自由に制御することができます。
注 : GraphicsPath クラスには、曲線、円弧、扇形、矩形など、使用可能な図形を定義するメソッドがあります。以下のコード例では、楕円形が 4 つ定義されます。これらの楕円形をボタンなどのコントロールに適用すると、ちょうど人の目の形に見えます。GraphicsPath クラスに定義されているその他の図形と組み合わせて、いろいろな形状を試してみてください。
' Visual Basic Private Sub Button1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles Button1.Paint Dim myGraphicsPath As System.Drawing.Drawing2D.GraphicsPath = New _ System.Drawing.Drawing2D.GraphicsPath() myGraphicsPath.AddEllipse(New Rectangle(0, 0, 125, 125)) myGraphicsPath.AddEllipse(New Rectangle(75, 75, 20, 20)) myGraphicsPath.AddEllipse(New Rectangle(120, 0, 125, 125)) myGraphicsPath.AddEllipse(New Rectangle(145, 75, 20, 20)) ' ボタンを見やすくするために、背景色を変更します。 Button1.BackColor = Color.Chartreuse Button1.Size = New System.Drawing.Size(256, 256) Button1.Region = New Region(myGraphicsPath) End Sub // C# private void button1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new System.Drawing.Drawing2D.GraphicsPath(); myGraphicsPath.AddEllipse(new Rectangle(0, 0, 125, 125)); myGraphicsPath.AddEllipse(new Rectangle(75, 75, 20, 20)); myGraphicsPath.AddEllipse(new Rectangle(120, 0, 125, 125)); myGraphicsPath.AddEllipse(new Rectangle(145, 75, 20, 20)); // ボタンを見やすくするために、背景色を変更します。 button1.BackColor = Color.Chartreuse; button1.Size = new System.Drawing.Size(256, 256); button1.Region = new Region(myGraphicsPath); }
注 : このコードは、FillMode 列挙体の既定の設定値を利用しています。FillMode により、閉じた図形の内部の塗りつぶし方法とクリップ方法が決定されます。詳細については、「FillMode 列挙体」 を参照してください。
また、Form
クラスは System.Windows.Forms.Control
クラスから派生したものであるということに留意してください。つまり、Windows フォーム デザイナによって提供されるフォームのインスタンスは、結局はコントロールなのです。したがって、自由な形状のフォームの作成には、先ほど説明した "ビットマップ イメージ" を使用する方法と、GraphicsPath クラスのインスタンスを使用する方法があります。GraphicsPath クラスのインスタンスでいろいろ試し、楽しい形のフォームを作ってみてください。
まとめ
これまで説明したように、アプリケーション内でフォームやコントロールの外観をカスタマイズするのは非常に簡単です。フォームの場合は、希望するフォームの形状を含むイメージ ファイルがあれば、この作業を行うことができます。コントロールの場合は、コントロールの形状を定義する GraphicsPath を指定する必要があります。ここでは、カスタマイズされた形状のフォームとコントロールを作成する基本について順を追って学習しました。この知識を基にして、独自のユーザー インターフェイスを作成してみましょう。