第14章 フラットでポイントするとカーソルが変わるボタン


何とも長い表題です。



まずは、今回作るプログラムの実行結果を見てみましょう。

ボタンの外観がフラットになりました。そして、カラフルです。

ボタンに表示されているテキストも大きめですね。かつ色が白い。

また、マウスをのせると、カーソルが指型になります。



ボタンを押すと、どのボタンを押したのか、メッセージボックスで表示します。

同時に、クライアント領域にも表示されます。



さらに、フォームのサイズが縮小されて全部が表示されなくなったら、スクロールバーが出てきます。



まずは、ボタンをフラットにする方法ですが、これはButtonクラスのFlatStyleをFlatSytle.Flatに設定するだけです。FlatSytleプロパティはButtonBaseクラスからの軽症です。

public FlatStyle FlatStyle { get; set; }
戻り値のFlatStyleは、FlatStyle列挙体でメンバは次の通りです。

メンバ意味
Flatコントロールがフラットに表示される
Popupマウスでポイントされると立体的に表示される
Standard立体表示
System外観はOSにより決定される

次に、ボタンに自分で描画するには、ButtonクラスのOnPaintメソッドをオーバーライドします。Buttonクラスから継承したクラスを作らなかった場合はPaintイベントと自作ハンドラを関連づける必要があります。

protected override void OnPaint(PaintEventArgs pevent)
{
    base.OnPaint(pevent);

    string title = "ボタン";
    Graphics g = pevent.Graphics;
    Brush br;
        
    switch (no)
    {
        case 0:
            br = Brushes.Red;
            title += "1";
            break;
        case 1:
            br = Brushes.Blue;
            title += "2";
            break;
        case 2:
            br = Brushes.Brown;
            title += "3";
            break;
        case 3:
            br = Brushes.Gold;
            title += "4";
            break;
        default:
            br = Brushes.Black;
            break;
    }
        
    g.FillRectangle(br, 
        new Rectangle(5, 5, this.Width - 10, this.Height - 10));
    Font font = new Font("MS ゴシック", 14);
    SizeF sz = g.MeasureString(title, font);
    Single x = (this.Width - sz.Width) / 2.0F;
    Single y = (this.Height - sz.Height) / 2.0F;
    g.DrawString(title, font, Brushes.White, x, y);
}
背景をいろいろな色で塗るならBackColorプロパティを設定すればいいんじゃないか、と思われる方もいると思いますが、そうすると外観が図で示したようにはなりません。(ボタンの周りもその色になる、ボタン境界の内側も塗りつぶされるなど)

そこで、自力でFillRectangleメソッドで矩形に塗りつぶしています。Graphics.FillRectangleメソッドには、4つのオーバーロードバージョンがあります。

public void FillRectangle (
	Brush brush,
	Rectangle rect
)
public void FillRectangle (
	Brush brush,
	RectangleF rect
)
public void FillRectangle (
	Brush brush,
	int x,
	int y,
	int width,
	int height
)
public void FillRectangle (
	Brush brush,
	float x,
	float y,
	float width,
	float height
)
最初の引数は、塗りつぶすブラシを指定します。後の引数は矩形を左上隅の座標で示して、幅・高さを指定するか、Rectangleまたは、RectangleF構造体で指定します。

RectangleF構造体は第6章ですでに解説しています。Rectangle構造体は、これのint版です。

Rectangle構造体のコンストラクタはオーバーロードされていて、次のようなものがあります。

public Rectangle (
	Point location,
	Size size
)
public Rectangle (
	int x,
	int y,
	int width,
	int height
)
Rectangle構造体の、主なプロパティにはX,Y(左上隅のx,y座標)、Size(この四角形のサイズ)、 Width(幅)、Height(高さ)などがあります。

Point構造体は、第3章ですでに出てきました。

さて、四角形を描画したらその上からDrawStringメソッドでテキストを描画します。

MeasureStringメソッドで、表示するテキストの計測を行います。描画開始の左上隅の座標は

Single x = (this.Width - sz.Width) / 2.0F;
Single y = (this.Height - sz.Height) / 2.0F;
で求まります。szは文字列の計測結果を持っているSizeF構造です。

次に、マウスでポイントされたときの挙動はButtonクラスのOnMouseHoverメソッドをバーライドして記述します。このメソッドはControlクラスからの継承です。

protected override void OnMouseHover(EventArgs e)
{
    base.OnMouseHover(e);
    this.Cursor = Cursors.Hand;
}
ButtonクラスのCursorプロパティを指型のカーソルに設定します。
public virtual Cursor Cursor { get; set; }
Cursorを設定するには、Cursorオブジェクトのコレクションを提供するCursorsクラスを利用すると便利です。Cursorsクラスのstaticなプロパティでよく使われると思われるものには、次のようなものがあります。

プロパティ意味
Arrow矢印カーソル
Cross十字カーソル
Default規定のカーソル(通常矢印)
Hand指型のカーソル
Help矢印と疑問符のカーソル
WaitCursor待機カーソル

これらは、全部読み取り専用です。他にも多数定義されています。

では、プログラムを見てみましょう。

// button04

using System;
using System.Drawing;
using System.Windows.Forms;

class button04
{
    public static string str;

    public static void Main()
    {
        Size sz = new Size(120, 50);
        MyForm mf = new MyForm(sz);
        MyButton mybtn1 = new MyButton(mf, 
            new Point(10, 10), sz, 0);
        MyButton mybtn2 = new MyButton(mf,
            new Point(20 + mybtn1.Width, 10), sz, 1);
        MyButton mybtn3 = new MyButton(mf,
            new Point(10, 20 + mybtn1.Height), sz, 2);
        MyButton mybtn4 = new MyButton(mf,
            new Point(20 + mybtn1.Width, 20 + mybtn1.Height), 
            sz, 3);
        Application.Run(mf);
    }
}

class MyForm : Form
{
    Size bSize;

    public MyForm(Size sz)
    {
        Text = "猫でもわかるプログラミング";
        BackColor = SystemColors.Window;
        bSize = sz;

        AutoScroll = true;
        AutoScrollMinSize = new Size(sz.Width * 2 + 20, sz.Height * 2 + 60);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        Graphics g = e.Graphics;
        int x = 10;
        int y = bSize.Height * 2 + 30;
        Font font = new Font("MS ゴシック", 14);
        g.DrawString(button04.str, font, Brushes.Black, 
            x + AutoScrollPosition.X,
            y + AutoScrollPosition.Y);
    }
}

class MyButton : Button
{
    int no;
    
    public MyButton(Form parent, Point pt, Size sz, int n)
    {
        no = n;
        Parent = parent;
        Location = pt;
        Size = sz;
        BackColor = SystemColors.Control;
        FlatStyle = FlatStyle.Flat;
    }

    protected override void OnClick(EventArgs e)
    {
        base.OnClick(e);
        string str = "ボタン" + (no + 1) + "を押したね";

        button04.str = str;
        Parent.Invalidate();

        MessageBox.Show(str, "猫でもわかるプログラミング",
            MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
    }

    protected override void OnMouseHover(EventArgs e)
    {
        base.OnMouseHover(e);
        this.Cursor = Cursors.Hand;
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        base.OnPaint(pevent);

        string title = "ボタン";
        Graphics g = pevent.Graphics;
        Brush br;
        
        switch (no)
        {
            case 0:
                br = Brushes.Red;
                title += "1";
                break;
            case 1:
                br = Brushes.Blue;
                title += "2";
                break;
            case 2:
                br = Brushes.Brown;
                title += "3";
                break;
            case 3:
                br = Brushes.Gold;
                title += "4";
                break;
            default:
                br = Brushes.Black;
                break;
        }

        
        g.FillRectangle(br, 
            new Rectangle(5, 5, this.Width - 10, this.Height - 10));
        Font font = new Font("MS ゴシック", 14);
        SizeF sz = g.MeasureString(title, font);
        Single x = (this.Width - sz.Width) / 2.0F;
        Single y = (this.Height - sz.Height) / 2.0F;
        g.DrawString(title, font, Brushes.White, x, y);
    }
}
ちょっと長いですが、順番に見ていくとわかると思います。(特に、クラス間の連絡に注意して読んでみてください。)


[C# フォーム Index] [C# コンソール Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 29/Oct/2006 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。