第50章 マウスで絵を描く


今回は、直線のみを使って絵を描くプログラムを作ってみます。



クライアント領域の、任意の場所でマウスを左クリックします。

そして、ボタンを押したままマウスをドラッグします。

すると、最初にクリックした点を始点として、マウス位置を終点とする直線が、刻々と描かれます。ボタンを放すと、直線の描画が完了します。これを、繰り返して絵を描きます。

失敗しても、やり直しはできません。描画する直線の数には限りがあります。ファイルに保存することはできません。

ともかく、非常に原始的なお絵かきソフトです。

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

// mouse03.cs

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

class mouse03 : Form
{
    Point[] pt;
    int no;
    Point prevpt1, prevpt2;
    const int nMaxNo = 100;

    public static void Main()
    {
        Application.Run(new mouse03());
    }

    public mouse03()
    {
        Text = "猫でもわかるC#プログラミング";
        BackColor = SystemColors.Window;
        
        pt = new Point[nMaxNo];
        no = 0;
        
        MainMenu mm = new MainMenu();
        Menu = mm;

        MenuItem miFile = new MenuItem("ファイル(&F)");
        mm.MenuItems.Add(miFile);

        MenuItem miExit = new MenuItem("終了(&X)");
        miFile.MenuItems.Add(miExit);
        miExit.Click += new EventHandler(miExit_Click);
    }

    void miExit_Click(object sender, EventArgs e)
    {
        Close();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);

        if (no >= nMaxNo)
        {
            MessageBox.Show("設定数を超えました",
                "限界", MessageBoxButtons.OK,
                MessageBoxIcon.Stop);
            return;
        }

        pt[no] = e.Location;
        prevpt1 = e.Location;
        no++;
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        
        pt[no] = e.Location;
        no++;
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        Graphics g = e.Graphics;

        for (int i = 0; i < no / 2; i++)
        {
            g.DrawLine(new Pen(new SolidBrush(Color.Red)),
                pt[i * 2], pt[i * 2 + 1]);
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (e.Button == MouseButtons.None)
            return;

        Graphics g = CreateGraphics();
        g.DrawLine(new Pen(new SolidBrush(Color.White)), prevpt1, prevpt2);
        g.DrawLine(new Pen(new SolidBrush(Color.Blue)), e.Location, prevpt1);
        prevpt2 = e.Location;
        g.Dispose();
    }
}
このプログラムは、mouse03クラスしかありません。

mouse03クラスのフィールドに、Point構造体の配列ptを用意しました。 直線の始点の座標をpt[0]とすると、終点の座標をpt[1],次の直線はpt[2],pt[3]という具合に、描画した線分の座標を記録していきます。(もちろん、後の章で書きますが、もっと良い方法があります。)

prevpt1, prevpt2には、直前に描画した直線の始点、終点を保存しておきます。

配列ptの要素数はnMaxNoとします。

Mainメソッドは、いつも通りです。

コンストラクタでは、配列を確保したり、メニューを作ったりしています。

miExit_Clickメソッドは、メニューから「終了」が選択されると呼び出されます。 単に、メインフォームを閉じてプログラムを終了します。

次は、このプログラムではかなり重要な、マウスボタンが押されたときの処理です。 ここでは、OnMouseDownメソッドをオーバーライドしています。

noがnMaxNo以上であった場合、配列に書き込めないのでその旨メッセージボックスを出してすぐに制御を返します。

pt[no]に、ボタンが押されたところの座標を記録します。そしてprevpt1にも、その座標を記憶させます。noを一つ進めます。

ボタンが離されたときの処理は、OnMouseUpメンバをオーバーライドして行っています。

ここでは、ボタンが離されたときの座標をpt[no]に蓄え、noを進めます。そして、Painイベントを発生させ、クライアント領域の再描画を行わせます。

マウスボタンが押されたところを始点、離されたところを終点としてpt[no]に記憶しておくことになります。

さて、Paintイベントの処理では、pt[i*2]からpt[i*2+1]の直線を描画します。 iは、0からno/2-1まで変化させればよいですね。

次は、マウスが移動中の時の処理です。

ボタンが押されていないときは、何もせずに戻ります。

最初にprevpt1から、prevpt2まで白で直線を描画し、以前の直線を消します。

そして、現在のマウス位置からprevpt1までを青色の直線で描画します。

では、実行結果を見てみましょう。

マウスをドラッグ中は、始点とマウス位置までの直線が青色で表示されます。



マウスボタンを放すと、直線が赤色で確定します。



簡単な絵を描画することができます。




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

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