GUIアプリの作り方

ホームC#入門講座第4章:簡易暗号化アルゴリズム > GUIアプリの作り方

GUIアプリの作り方

CUIとGUI

いわゆるアプリケーションには様々な種類があります。これはプログラミング全般を学ぶ上でも重要ですから、少し解説します。

CUIとは「キャラクタユーザーインターフェイス」の略です。文字による操作を前提としたアプリケーションであり、これまでのプログラムはすべてCUIです。CUIでは「入力デバイス」はキーボードで、「出力デバイス」はコンソールという黒い画面でした。昔ながらのコンピュータのイメージとはこんな感じだと思います。

GUIとは「グラフィカルユーザーインターフェイス」の略です。マウスによる操作を前提としており、ウィンドウやボタン、アイコンなどが装備されています。Appleが最初だと思われていますが、昔から「X WIndow System」というUNIXのウィンドウシステムがあり、Appleはこれを発展させたものです。WindowsはAppleからヒントを得て、現在のように世界中のパソコンを支配するようになりました。なお、AppleはBSDというUNIX系OSで、OS自体もUNIXの血を引いています。

Webアプリケーションとは、サーバーで動作するプログラムです。掲示板やアクセスカウンター、ブログやWiki、mixiなどはすべてWebアプリケーションです。多くはデータベースと密接に連携し、ブラウザだけでアクセスができます。

組込みプログラムとは主に家電向けのプログラムです。ほぼすべての家電にはプログラムが組み込まれていますが、それらはOSの上で動作するのではありません。アプリケーションはOS上で動作するプログラムを指しますので、組込みはアプリケーションではありません。ただし、プレイステーションなどはLinuxをOSとしており、特殊な例であるといえます。

LinuxやBSDなどのUnix系OSではCUIアプリケーションが多く用いられております。慣れてしまえばコンソール画面はとても使い易いのですが、Windowsユーザーにとっては抵抗が大きいでしょう。ですから、現在ではほとんどのWindowsアプリケーションはGUIをサポートしています。

なお、余談ですがBSDというのはLinuxとは別系統のUnix系OSで、Linuxのお兄さんにあたります。YahooのサーバはFreeBSDというOSで作られており、AppleもBSDがベースになっています。Googleや多くのベンチャー企業のサーバはLinuxを用いています。両者の違いはライセンスなどによるものが大きく、実際は多くのソフトウェアが両方で動作します。

System.Windows.Forms名前空間

GUIにおいては「ウィンドウ」と「コントロール」の関係を意識しなくてはなりません。つまり、「ボタン」や「テキストボックス」、「ラジオボタン」などの「コントロール」は「ウィンドウ」の中に配置されており、上下関係がはっきりしています。

「ウィンドウ」にはコントロールを格納する配列によく似た「コレクション」という機能が実装されています。コントロールはそこに入れて初めてウィンドウの支配下に入り、使用可能になります。

なお、「ウィンドウ」はフォームと呼ばれます。フォームとコントロールはすべて System.Windows.Forms 名前空間で実装されており、例えばフォームならFormクラス、ボタンならButtonクラスというようにクラスで定義されています。

メソッド・プロパティ・イベント

フォームもコントロールもいずれもクラスですから、メソッドやプロパティといったメンバが実装されています。例えばButtonの背景色は「BackColorプロパティ」で指定できますし、逆に背景色を既定値に戻したければ「ResetBackColor()メソッド」を呼び出せば実現できます。

そして、GUIアプリにおいて重要なメンバが「イベント」です。イベントは高度なトピックであり、ここでは詳しく説明できません。イベントとは「ある重要なことが起きたときに、そのことを他のオブジェクトに通知する」ものだと考えてください。

イベントによって伝えられたら、それに応じて処理をすることができます。その処理はイベントメソッドに記述しており、イベントメソッドはイベントを管理する場所へ格納されています。イベントが発生すると格納されたイベントメソッドを次々に呼び出します。

ソースコード

using System;
using System.Drawing;
using System.Windows.Forms;
 
public class HelloWorld : Form
{
	static public void Main ()
	{
		Application.Run (new HelloWorld ());
	}
 
	public HelloWorld ()
	{
		Button b = new Button ();
		b.Text = "Click Me!";
		b.Click += new EventHandler (Button_Click);
		Controls.Add (b);
	}
 
	private void Button_Click (object sender, EventArgs e)
	{
		MessageBox.Show ("Button Clicked!");
	}
}

これはLinux上で動作する.NET環境の「Mono」の英語サイトにあったサンプルをそのまま引用したものです。WindowsアプリケーションはCUIより複雑ですので、いくつかの項目に分けて整理します。

名前空間

一番上の using と書かれたところには、System.Windows.Forms名前空間だけでなく、System.Drawing名前空間も列挙します。

継承

フォームは「System.Windows.Forms.Formクラス」に記述されています。私たちがそのFormクラスを元に独自のフォームを作る場合、そのフォームを継承します。

public class HelloWorld : Form

継承する場合は、クラス名の後に「:」コロンを書き、さらに継承元となるクラス名を記述します。

継承によってFormクラスの内容がそのままHelloWorldクラスにコピーされます。また、privateやpublicとは別のprotectedというアクセス修飾子で保護されたメンバも、継承の場合は使用することができるようになります。

Application.Run()メソッド

イベントを利用するWindowsアプリケーションでは、メッセージループという機能を開始させる必要があります。イメージとしてはサーバやデーモンに似ています。マウスやキーボードの動きを監視するデーモンを立ち上げ、そのデーモンがイベントをキャッチしてプログラムに伝えるイメージです。

ApplicationクラスのRun()メソッドは、このデーモンにあたるメッセージループを開始します。また、引数にFormクラスのオブジェクトを渡してフォームを表示させる役割も果たします。

ここでは「new HelloWorld()」として、自分自身のオブジェクトを渡しています。こうすることでFormクラスを継承したHelloWorldクラスが実体化され、フォームとして表示されます。

コンストラクタの役割

クラスと同じ名前をもつメソッドをコンストラクタといい、クラスがオブジェクト化されるときに自動的に呼び出されることはすでに習いました。GUIアプリケーションではこのコンストラクタの特徴をいかし、フォームを「初期化」します。

ここではフォームに追加するボタンを実体化し、フォームのControlsコレクションに追加格納しています。フォームにあらかじめ表示させておきたいことはここですべて初期化します。それ以外の動作はイベントメソッドで記述します。

イベントハンドラー

イベントは上で少し話しましたが、実際の使い方は上のプログラムに表れています。

b.Click += new EventHandler (Button_Click);

bはボタンのオブジェクトです。そのClickイベントにイベントメソッドを追加しています。イベントメソッドはイベントハンドラーというオブジェクトで包み、そのイベントハンドラーをイベントに追加します。

ここで使用している演算子「+=」は以前にも使いましたが、このようにイベントハンドラーを追加するように拡張された形式で使うのは初めてです。

イベントメソッド

private void Button_Click (object sender, EventArgs e)
{
	MessageBox.Show ("Button Clicked!");
}

イベントメソッドは決まりきった引数をとりますので、覚えていても損はありません。まず、第1引数の「sender」はイベントを送信したコントロールを格納しています。次に、第2引数の「e」はイベントが発生した際の様々な状況を格納しています。例えば、エラーの際はeをうまく使うことでエラーメッセージを表示することができたりします。イベントメソッドはこの2つの引数を定義するのが普通です。

なお、object型というのはすべてのベースになる型です。object型であればFormオブジェクトもButtonオブジェクトもTextBoxオブジェクトも格納できます。

またMessageBoxクラスはメッセージボックスに関するクラスです。Show()メソッドを使えば、メッセージボックスを使って文字列を表示できます。いくつかのオーバーロードがあり、アイコンなども指定できます。

これでGUIアプリケーションの基本を一通り学びました。次回は最終回です。XOR演算を用いた簡易暗号化ソフトをGUIで実装します。

コラム:Gtk#の場合

System.Windows.Forms名前空間に定義されたコントロールは、Monoプロジェクトの努力によってLinuxでも動作するようになりました。Linux既存のウィンドウシステムと連携して、Windowsプログラムを実行することが可能になるのです。

MonoプロジェクトはLinuxで動作することを目的としており、Linuxはサーバ用途で使われることが大半です。ですから、MonoプロジェクトではSystem.Windows.Forms名前空間よりもSystem.Web名前空間の実装を急ぎ、WebアプリケーションではApacheとの連携やXSPという独自の簡易サーバを生みだし、.NETよりも一歩進んでいます。

Webアプリケーションにはおくれたものの、Forms名前空間も実装が完了し、現在ではほぼ動作させることが可能となっています。Monoの開発当初は、Windowsに固有のGUIコントロールを「System」名前空間に配置していることから、「Micorosoftは本気でマルチプラットフォームを実現する気ではないのではないか?」といわれ、批判が集中していた、などということもありました。Microsoftは「Microsoft名前空間」を別に用意し、DirectXなどはそこに配置しています。

LinuxにはWindowsとは別のウィンドウ管理技術が発達しています。それは「GIMP」という画像処理ソフトを作るために開発されたX Window System用のツールキット「GTK」です。Linux上のアプリケーションの多くはGTKを用いています。

GTKをC#から使えるようにしたのが「Gtk#」です。これは.NET Frameworkにあわせて「Gtk#2.0」まで開発が進んでおり、Linuxではすでに複数の有力ソフトがこのGtk#を使って作られています。Monoのコンパイラは.NETのコンパイラよりも簡潔なバイトコードを生成すると言われており、オープンソースの努力が現実的に実ってきました。

 using System;
 using Gtk;
 
 public class GtkHelloWorld {
  
   public static void Main() {
     Application.Init();
 
     Window myWin = new Window("My first GTK# Application! ");
     myWin.Resize(200,200);
     
     Label myLabel = new Label();
     myLabel.Text = "Hello World!!!!";
          
     myWin.Add(myLabel);
     
     myWin.ShowAll();
     
     Application.Run();   
   }
 }

これがGtk#を用いたGTKアプリケーションです(同じくMonoから引用)。継承を用いていないのが大きな特徴ですが、.NETのSystem.Windows.Forms名前空間に極めて近い形で実装できることが分かります。

.NETはもともとマルチプラットフォームな環境として開発されたため、Microsoftも比較的Monoに協力的でした。また、ノベルというMicrosoftのライバル企業がSUSELinuxを買収し、Monoプロジェクトの後見人を買ってでたため、Microsoftがオープンソース陣営に近づくきっかけになりました。ノベルはGoogleのSEOエリック・シュミット氏がSEOを勤めていた会社でもあり、Monoを通じてIT企業の様々な様相を探ることができます。

もはや誰でも知っているWikipediaの検索技術はMonoを用いて実装されています。C#というマルチプラットフォームな言語を学んできたみなさんは、ぜひLinuxやApple、BSDなど様々なOSに興味を持ち、知的好奇心を満たしていただけたらなぁ、と思います。