クライアント領域の、任意の場所でマウスを左クリックします。
そして、ボタンを押したままマウスをドラッグします。
すると、最初にクリックした点を始点として、マウス位置を終点とする直線が、刻々と描かれます。ボタンを放すと、直線の描画が完了します。これを、繰り返して絵を描きます。
失敗しても、やり直しはできません。描画する直線の数には限りがあります。ファイルに保存することはできません。
ともかく、非常に原始的なお絵かきソフトです。
では、プログラムを見てみましょう。
// 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までを青色の直線で描画します。
では、実行結果を見てみましょう。
マウスをドラッグ中は、始点とマウス位置までの直線が青色で表示されます。
マウスボタンを放すと、直線が赤色で確定します。
簡単な絵を描画することができます。
Update 04/Jan/2007 By Y.Kumei