今まではButtonとEditといった限られたコンポーネントを使ってプログラムを作ってきましたが、Delphiにはその他にも多数のコンポーネントが用意されています。それらの多くは、比較的簡単に使うことができます。ここでは、そうした「簡単に使え、かつ多用されるコンポーネント」の基本について説明をしましょう。今回は、ややこしそうな命令やソースコードは登場しませんから、肩の力を抜いていきましょう。
まずはボタン関係のものからです。今まで、ボタンといえば「プッシュボタン(マウスでクリックして何かを実行するボタン)」しか使ってきませんでしたが、その他にもWindowsではボタンを使います。その代表は「チェックボックス」と「ラジオボタン」でしょう。
チェックボタンは、マウスでクリックすることでチェックをON/OFFすることのできるボタンです。ラジオボタンは、いくつかある項目の中からクリックした1つだけを選ぶためのものです。どちらもWindowsの世界ではなじみのものですから説明しなくともわかりますね?
これらのボタン類は、コンポーネントパレットの「Standard」タブ内に「CheckBox」「RadioButton」という名前のコンポーネントとして用意されています。これらは、単に配置するだけで、自動的にクリックしてON/OFFしたり、複数のRadioButtonから1つ選んだりするようになります。ON/OFFや選択のための命令などは一切書く必要はありません。
ボタンのチェック状態は「Checked」というプロパティとして用意されています。これは真偽値になっていて、TrueにすればチェックがONに、FalseにすればOFFになります。また「クリックした時に何かの操作をしたい」という場合には、Buttonと同様にOnClickイベントを利用できます。
これらはとても簡単に使えるコンポーネントですが、実際に使ってみるとちょっと不満な点も見えてくるでしょう。特にラジオボタンについては「常に1グループしか作れない」という欠点があります。すなわち、RadioButtonをいくつ配置しても、それら全体で1つしか選択できないようになっているのです。複数の選択グループを作れないんですね。
もし、複数のグループを作りたいならば、「Standard」タブ内にある「GroupBox」というものを利用します。これは、「枠」となるコンポーネントで、これを作って、その中にRadioButtonを作ると、それらは他のものとは切り離された独立した1つのグループとして扱われます。つまり、GroupBoxを作れば、その数だけグループが作れるのですね。
ただし、この方式はやたらとコンポーネントの数も増えますし、あんまりスマートじゃありません。個人的には、ラジオボタンが必要な時には「RadioGroup」というコンポーネントをお勧めします。これも「Standard」タブに用意されているもので、GroupBoxとRadioButtonを1つにまとめたような機能のコンポーネントです。
これは、コンポーネントを作ると、まず枠だけのものが作成されます。「items」プロパティの「・・・」ボタンをクリックすると、表示する項目を入力するダイアログが現れるので、ここで各項目を改行して入力します。すると、設定した項目をラジオボタンとして内部に表示するのです。
現在選択されている項目は「ItemIndex」というプロパティで設定できます。これは選択されている項目の番号を示すもので、0から始まる整数で設定されます。初期状態では「-1」になっており、これでは何の項目も選択されていません。 これを変更すれば、項目を選択できます。例えば「0」にすると、一番最初の項目がONになるというわけです。もちろん、プログラム内で現在選択されている項目を知りたい時にも、このItemIndexの値を調べればわかります。
何かのON/OFFやラジオボタンなどは、数個の選択肢の中から1つを選ぶのに適したインターフェイスでした。が、項目の数が増えるとさすがにそうはいきません。もっと別のものを考える必要があるでしょう。
こうした場合に多用されるのは、「リスト」と「コンボボックス」でしょう。リストは、文字通りたくさんの項目がリスト表示されているもののことです。これらは「Standard」タブに「ListBox」「ComboBox」というコンポーネントとして用意されています。
上の図の内、左側がListBox、右側がComboBoxです。どちらも「たくさんの項目から1つを選ぶ」という点では似ていますが、違う点もあります。
まず、ListBoxでは複数の項目を選択することができます。またComboBoxでは、項目を選ぶほかに、直接テキストを入力させるようなことも可能です。このように微妙に性質が違いますから、必要に応じて「どちらを使ったほうが便利か」を考えて使い分けるのが良いでしょう。
これらの基本的な使い方は、RadioGroupと似ています。まず、「Items」プロパティで表示する項目を1つずつ改行して入力します。そして、プログラム内などで「現在選択されているのはどれか」を調べたい時には、コンポーネントの「ItemIndex」プロパティを調べます。
まぁ、これだけでも一応使えますが、 いくつか覚えておくと便利なものなどもありますから、それらも簡単に触れておきましょう。
・「ListBox」で、複数の項目を選択できるようにする
ListBoxで複数項目を選択可能にするためには「MultiSelect」というプロパティをTrueにします。これで複数の項目が選べるようになります。が、これをTrueにすると、ItemIndexで選択されている項目を調べることができなくなるので注意が必要です。
複数項目を選択可能にした場合、各項目の選択状態は「Selected」というプロパティで調べます。これは、配列の値になっていて、Selected[番号]という形で特定の項目の選択状態を調べるのです。例えば、ListBox1.Selected[0]がTrueならば、ListBoxの最初の項目は選択されている、ということになります。――これはちょっとわかりにくいので、簡単な例を上げておきましょう。
procedure TForm1.Button1Click(Sender: TObject); var num,i: Integer; begin num := ListBox1.Items.Count; for i := 0 to num - 1 do begin if ListBox1.Selected[i] then ShowMessage(IntToStr(i) + '番目は選択されている'); end; end;
こ れは、ListBox1の各項目の選択状態をチェックし、ONになっている項目を全てメッセージボックスで表示するプロシージャです。ボタンのOnClickなどに割り付けて実行してみて下さい。
ここでは、まず「num := ListBox1.Items.Count;」というものを使ってItemsの項目数を調べています。Itemsは、このようにCountプロパティで項目数がわかるのです。そして繰り返しの中で、「if ListBox1.Selected[i] then・・」というようにして、各項目の選択状態を調べ、TrueならばShowMessageしています。こんな具合に、繰り返しを使って順番にSelected[i]を調べていけば、全ての項目について選択の状態がわかりますね。
また、「○○番目の項目のテキスト」というのは、Items[番号]という形で得ることができます。これはListBoxに限らず、ComboBoxなどでも共通するものですので覚えておきましょう。
注意しておきたいのは、「itemsにしろSelectedにしろ、番号は0から始まる」ということです。ですから、総当たりをする場合には、繰り返し回数を0〜(項目数−1)にしておく必要があります。これを忘れると、配列の要素数を超えて配列を使おうとしてエラーを起こしますので注意して下さい。
・ComboBoxのStyleとOnChangeについて
ComboBoxは、デフォルトでは設定した項目がずらっと出てくるだけですが、この表示方式は変更できます。「Style」プロパティがそのためのプロパティで、以下のような値が用意されています。
csDropDown――テキストの直接入力とリスト表示の両方が可能
csDropDownList――リスト表示のみでテキストの直接入力は不可
csSimple――csDropDownと同様だがリストを常に表示
csOwnerDrawFixed――独自の方式で表示(わからないと使えない)
csOwnerDrawVariable――独自の方式で表示(これもわからないと使えない)
とりあえず、最後の2つはちょっとややこしいので忘れて下さい。このStyleを変更することで、テキストの入力を禁止したりできるわけですね。
もう1つComboBoxで知っておきたいのは「項目を変更した時のイベント」です。これは「OnChange」というもので、項目を選んだり、直接テキストを入力するなどした場合に発生します。――これも、簡単な例を上げておきましょう。
procedure TForm1.ComboBox1Change(Sender: TObject); var n: Integer; begin n := ComboBox1.ItemIndex; ShowMessage('選択したのは、' + ComboBox1.Items[n]); end;
これは、項目を選んだ時に、選択した項目を表示する例です。ここでは、まずItemIndexを使って選択された項目を調べ、それから「ComboBox1.Items[n];」という形で選択項目のテキストを取り出して表示しています。「○○」番目の項目のテキスト」というのは、このように「Items[番号]」として得ることができます。これはComboBoxに限らず、ListBoxや、更にはRadioGroupなどでも共通して使えるテクニックです。
この他に、数字を入力や表示するのに便利なコンポーネントというのもあります。それは、数量バー関係のものです。Delphiでは、「Standard」タブに「ScrollBar」、「Win32」タブに「TrackBar」「ProgressBar」というコンポーネントがそれぞれ用意されています。全て、おおまかな数量を示すためのものです。
上から「ScrollBar」「TrackBar」「ProgressBar」です。前者2つはユーザーがマウスで操作できますが、最後のProgressBarは表示だけで操作はできません。
これらはいずれも、スライダーや目盛りの表示位置で、一定範囲の中のいくつあたりが選択されているかを示すようになっています。これらのコンポーネントには最大値と最小値のプロパティがあり、その範囲内で現在の値を設定するようになっているのです。これらを使うには、まずこの3つのプロパティをよく覚えておく必要があります。
Min――最小値の値
Max――最大値の値。Minより小さくてはいけない
Position――現在選択されている値。Min〜Maxの間でないといけない
また、前者2つ(ScrollBar、TrackBar)には、ComboBoxと同様に「OnChange」イベントが用意されています。これにより、値が変更された時の処理を行なうことができます。現在の設定値はPositionでわかりますから、このOnChangeを利用したプロシージャでPositionの値を取り出し、処理すれば、「値を変更したときに何かの処理をする」といったことができるというわけです。
この他にもさまざまなプロパティは用意されていますが、それらはいろいろ値を変更してみれば働きはわかるでしょう。特にScrollBarは、バーや矢印をクリックした時の増減量や、バーの向き(縦横)などに関するプロパティなども用意されていますから、オブジェクトインスペクタで調べてみると良いでしょう。
こうした具体的に操作するコンポーネントの他に、「コンポーネントを整理したりまとめたりするためのコンポーネント」というものもあります。その代表的なものが「タブパネル」でしょう。
Delphiでは、「Win32」タブに「PageControl」というコンポーネントとして用意されています。実は、この他に「TabControl」という似たようなものもあるのですが、こちらはお勧めしません。というのも、ページの切り替え時の表示処理などが用意されておらず、非常に機能が低くて使いにくいからです。
PageControlは、「ページ」というものを使って各タブの表示をまとめて整理します。PageControlコンポーネントは、作成した初期状態では、ただの四角いパネルです。ここで、PageControlコンポーネントを右ボタンクリックしてポップアップメニューを呼び出し、「ページ新規作成」を選んでみましょう。コンポーネントに新たにページが作成され、「TabSheet1」というタブが表示されます。――同様にして、必要なだけページを作っていけば、それらがタブとして表示され、タブクリックで切り替わるようになるというわけです。
作成されたページは、「TabIndex」というプロパティで調べることができます。これも0から始まる番号で、現在表示されているページを示します。「1」とすれば、2番目のタブが選ばれた状態になるというわけです。もちろん、用意されているタブの数を超えて指定することはできません。
ページの切り替えは、フォームデザイナ上でも行なうことができます。ですから、デザイナでタブを切り替え、画各ページの中にコンポーネントなどを配置していけば、タブで表示の切り替わるインターフェイスが全くノンプログラミングで作れてしまうというわけです。
また、タブを切り替えた時には「OnChange」イベントが発生しますので、これを利用して、タブ変更時の処理などを行なうことができます。
・・・というわけで、GUIコンポーネントの中でも、もっとも多用されるものについて、ごく基本的な使い方だけをまとめてみました。これらのコンポーネントには、もちろん他にもたくさんのプロパティやイベントが用意されていますし、この他にも便利なコンポーネントはたくさんあります。が、以上説明した基本的なコンポーネントを実際に使ってみれば、それらを組み合わせただけでもけっこうちゃんとしたインターフェイスが作れることがわかると思います。
まず、これら基本中の基本となるコンポーネントを使えるようにしてから、少しずつ利用できるものの幅を広げていくのが良いでしょう。