コンソール・アプリケーションでもイベントを処理することはできます。コンソール編第47章でもイベントを取り扱っています。しかし、コンソール・アプリケーションはイベント処理が必須のものではありません。
フォーム・アプリケーションではユーザーからの入力手段が複数あります。キーボード、マウスのクリック、ボタンの押下などなど・・・。ユーザーがこれらの入力手段を用いて入力したかどうかを常に監視する必要があります。一つ一つ調べて行くのは効率がよくありません。
次に、フォーム・アプリケーションでは自分以外のアプリケーションの動作についても気を配る必要があります。
また、自分以外のアプリケーションがどのような動作を行うかは全く予測不能です。
自分のアプリケーションで、フォームにグラフィックスを描画したとします。ユーザーの気まぐれで、自分のフォームが他のアプリケーションのウィンドウで覆い隠されたとします。この時点で、画面は他のアプリケーションのウィンドウで描き変えられています。そして、そのウィンドウが立ち去ったらどうでしょうか。せっかく描画したグラフィックスが消されてしまいますね。
主に、これらの2つの理由からGUIのプログラミングでは、イベント処理を行います。
イベントとは、何か事が起きたら(マウスがクリックされた、キーボードのキーが押された、覆っていたウィンドウが立ち去ったなどなど・・)、ウィンドウ(フォーム)にやって来て、アプリケーションに、こういう事が起きたぞ!と教えてくれる仕組なのです。
結局、いろいろなものを見張っているのではなく、何か事が起きたら(イベントが起きたら)どうするかをプログラムするのです。
こういったプログラム方式を「イベントドリブン型」プログラムといいます。
あれこれ、考えるより実例を見た方が早いでしょう。
Formクラスには、フォームに描画が必要になったときに送られるPaintイベントをメンバに持っています。
これを処理する場合、PaintEventHandlerというデリゲートをPaintイベントに関連づける必要があります。PaintEventHandlerは、System.Windows.Forms名前空間で定義されています。
public delegate void PaintEventHandler ( Object sender, PaintEventArgs e )このデリゲートをイベントに関連づけるには、
Paint += new PaintEventHandler(メソッド名);とします。(コンソール編第47章)
そして、ここで指定したメソッドの引数はデリゲートのそれと同じにする必要がありました。
このメソッドが、イベントが起きたときに実際に処理をすます。このメソッドをイベントハンドラといいます。(デリゲートをイベントハンドラと説明している本もあります。デリゲートも、このメソッドを指しているので同じ事ですが・・・)
具体的に、どうするかを示します。
Form f = new Form(); f.Paint += new PaintEventHandler(OnMyHandler); ...として、イベントにデリゲートを関連づけます。自作イベントハンドラは
static void OnMyHandler(object sender, PaintEventArgs e) { ....//実際の処理 }となります。
senderは、イベントの発生源を表します。
PaintEventArgsクラスには、ClipRectangleとGraphicsという2つのパブリックプロパティを有しています。
前者は、描画先四角形を取得し、後者は描画用グラフィックスを取得します。
主に使うのは後者でしょう。
Graphics g = e.Graphics;として、gを用いて描写を行います。(もちろん、引数をそのまま使ってe.Graphics.ナンタラとしてもよいのですが・・・)
では、具体的にプログラムを作ってみましょう。
// paintargs01.cs using System; using System.Drawing; using System.Windows.Forms; class paintargs01 { public static void Main() { Form f = new Form(); f.Text = "猫でもわかるプログラミング"; f.BackColor = Color.White; f.Paint += new PaintEventHandler(MyHandler); Application.Run(f); } static void MyHandler(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.DrawLine(new Pen(Color.Red), 10, 50, 280, 50); } }Formクラスのオブジェクトを生成後、TextとBackColorを設定しています。
次に
f.Paint += new PaintEventHandler(MyHandler);でイベントに、デリゲートを関連づけています。
自作イベントハンドラMyHandlerでは、PaintEventArgs型引数を利用して、グラフィックスを取得し、DrawLineメソッドで直線を描画しています。
Graphicsクラスには、多数の描画用メソッドを持っています。DrawLineメソッドは4つのオーバーロードバージョンがあります。
public void DrawLine ( Pen pen, Point pt1, Point pt2 ) public void DrawLine ( Pen pen, PointF pt1, PointF pt2 ) public void DrawLine ( Pen pen, int x1, int y1, int x2, int y2 ) public void DrawLine ( Pen pen, float x1, float y1, float x2, float y2 )pt1とpt2、もしくは(x1, y1)と(x2, y2)を結ぶ直線を描画します。
Penクラスは、直線や曲線の描画に使用するペンを定義します。4つのオーバーロードコンストラクタがありますが、もっとも単純なものは
public Pen ( Color color )でしょう。
Point構造体の主なパブリックプロパティはXとYです。
public int X { get; set; } public int Y { get; set; }さて、
g.DrawLine(new Pen(Color.Red), 10, 50, 280, 50);では、(10, 50)と(280, 50)を結ぶ直線を描画します。ペンは単純な赤色のペンです。
では、実行結果を見てみましょう。
Update 18/Oct/2006 By Y.Kumei