.NET TIPS

ウィンドウ(フォーム)の形を変えるには?

デジタルアドバンテージ
2004/09/10

 Windowsアプリケーションのウィンドウの形といえば通常は四角形であるが、Windowsフォーム(System.Windows.Forms名前空間のFormクラス)では、その形を簡単に変えることができる。次の画面は、ウィンドウの形をポケット型(だ円の下半分の形)に変えたものだ。本稿では、このような四角形ではないウィンドウを表示するための方法について示す。

変形させたフォームの例

Regionプロパティの設定によるフォームの変形

 フォームの形を変えるには、FormクラスのRegionプロパティに領域を表すRegionクラス(System.Drawing名前空間)のオブジェクトを設定すればよい。ここでいう領域とは、一連の直線や曲線で囲まれた図形の内部部分のことである。

 「一連の直線や曲線で囲まれた図形」というのは、GraphicsPathクラス(System.Drawing.Drawing2D名前空間)を用いて作成することができる。ここでは詳細は述べないが、このクラスではAddLineやAddCurveといったメソッドにより、1つの図形を作り上げていくことができる。上記画面のような「だ円の下半分」の図形は、AddArcメソッドを使って次のように作成できる。

GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, 400, 600, 0, 180);

 AddArcメソッドの詳細については、リファレンス・マニュアルを参照していただきたい。この例では400×600ピクセルの四角形に外接する、だ円の下半分だけの図形を作成しているので、実際の図形の高さは300ピクセルとなる点に注意してほしい。

 このようにして作成した図形を基にRegionオブジェクトを作成するには、作成したGraphicsPathオブジェクトをRegionクラスのコンストラクタで指定すればよい。

Region pocketRegion = new Region(path);

 後は、このRegionオブジェクトをフォームのRegionプロパティにセットすれば、フォームの形を変えることができる。

 次のサンプル・コード*は、上記の処理をフォームのLoadイベント・ハンドラで実装したものだ。

* このサンプル・コードを試すには、まずVisual Studio .NETで新しいプロジェクトとして「Windows アプリケーション」を選択しプロジェクトを作成する。そしてフォームをダブルクリックしてコードを開き、自動作成されているForm1_Loadメソッドを削除してから、このサンプル・コードをコピー&ペーストすればよい。
 
private void Form1_Load(object sender, System.EventArgs e)
{
  System.Drawing.Drawing2D.GraphicsPath path
    = new System.Drawing.Drawing2D.GraphicsPath();
  path.AddArc(0, -this.Height, this.Width, this.Height * 2, 0, 180);
  this.Region = new Region(path);
}
ポケット型のフォームを表示するC#のサンプル・コード
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim path As System.Drawing.Drawing2D.GraphicsPath _
    = New System.Drawing.Drawing2D.GraphicsPath
  path.AddArc(0, -Me.Height, Me.Width, Me.Height * 2, 0, 180)
  Me.Region = New Region(path)
End Sub
ポケット型のフォームを表示するVB.NETのサンプル・コード

リサイズにも対応したフォームの変形

 リサイズを禁止しているようなウィンドウでは上記のコードで十分だが、リサイズ可能なウィンドウ(デフォルトではWindowsフォームはリサイズ可能)の場合には、ウィンドウがリサイズされるたびに、リサイズ後のウィンドウのサイズに基づいた領域をRegionプロパティに再設定する必要がある。

 これを行うには、フォームのリサイズ時に呼び出されるOnResizeメソッドをオーバーライドし(あるいはResizeイベントのイベント・ハンドラを作成してもよい)、先ほどForm1_Loadメソッドで記述した内容をそっくりそのまま移動させればよい。次のサンプル・コードは上記のコードをそのようにして書き換えたものだ。

private void Form1_Load(object sender, System.EventArgs e)
{
  OnResize(null);
}

protected override void OnResize(EventArgs e)
{
  base.OnResize(e);

  System.Drawing.Drawing2D.GraphicsPath path
    = new System.Drawing.Drawing2D.GraphicsPath();
  path.AddArc(0, -this.Height, this.Width, this.Height * 2, 0, 180);
  this.Region = new Region(path);
}
リサイズ時にもフォームの形を変えるC#のサンプル・コード
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  OnResize(Nothing)
End Sub

Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
  MyBase.OnResize(e)

  Dim path As System.Drawing.Drawing2D.GraphicsPath _
    = New System.Drawing.Drawing2D.GraphicsPath
  path.AddArc(0, -Me.Height, Me.Width, Me.Height * 2, 0, 180)
  Me.Region = New Region(path)
End Sub
リサイズ時にもフォームの形を変えるVB.NETのサンプル・コード

 なお、プログラムの起動時にはOnResizeメソッドは呼び出されないため、実際にはフォームが初めて表示されるときにもRegionプロパティの設定が必要となる。そのため、このサンプル・コードではForm1_Loadメソッドから直接OnResizeメソッドを呼び出して実行している。End of Article

カテゴリ:Windowsフォーム 処理対象:ウィンドウ
使用ライブラリ:Formクラス(System.Windows.Forms名前空間)
使用ライブラリ:Regionクラス(System.Drawing名前空間)
使用ライブラリ:GraphicsPathクラス(System.Drawing.Drawing2D名前空間)
 
この記事と関連性の高い別の.NET TIPS
ウィンドウのリサイズ時に再描画を行うには?
Windowsフォームで簡単に画像を表示するには?
ある座標や領域がコントロールの領域内に含まれているかを確認するには?
クライアント領域やウィンドウ領域の座標を取得するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間