<チェックボックスとオプションボタンコントロール>

 今度はチェックボックスとオプションボタンを説明します。

 チェックボックスオプションボタンの違いを簡単に説明するとすれば、チェックボックスはON/OFF機能で、オプションボタンは、複数の選択肢の中から 1 つだけを選択するような場合に使用する機能だと考えればよいでしょう。

 たとえば、ゲームなどのアプリケーションを例にとれば、チェックボックスはゲーム音楽を鳴らすのか鳴らさないのかを区別するために使えばよいでしょう。
また、オプションコントロールは、画面サイズを選択(640 X 400, 800 X 600, フルスクリーン)するのに使えばよいでしょう。*1

*1

チェックボックスはON/OFF機能だと説明しましたが、オプションボタンを2つ用意してON/OFFを実現する方法も考えられます。このあたりは好みの問題もありますし、開発事情によって使い分ければよいでしょう。また、オプションボタンは、通常グループ化して使用します。

 さて、今回も簡単なサンプルを交えながらいつものように説明していきますが、今回はコントロール配列の説明とレジストリの操作も同時に説明します。

 最終的に図1のようなフォームを作成しますが、チェックボックスとオプションボタンはコントロール配列で貼り付けますので、チェックボックスは一つだけ'男'を貼り付けます。また、オプションボタンは'ドライブ'というオプションボタンだけ貼り付けます。

図1



図2

 図2のように貼り付けることができましたか?そういえば、貼り付ける前に一つ説明しておく必要がありました。それは、フレームコントロールとチェックボックス、またはオプションボタンの関係について説明しておかなければなりません。

 フレームコントロールピクチャーコントロールなどは、それ自身がコンテナの役割を果たします。つまり、フォームとコントロールの関係と同じにできるのです。この関係の場合、フォームがコンテナとなり、コマンドボタンなど、フォームに貼り付けたコントロールはフォームからはみ出して表示させることはできません。同じように、フレームコントロールもフレーム内にチェックボックスなどを貼り付けた場合、フレームからはみ出してチェックボックスを貼り付けることはできません。もちろん、この場合コントロールをはみ出して貼り付ける意味などどこにもありません。

 一方オプションボタンは、先ほど説明しましたが、通常はグループ化して使用します。グループ化というのは、貼り付ける対象のコンテナが異なっていれば、それは違うグループとして扱われます。つまり、オプションボタンをグループによって分類するには、コンテナをグループごとに分けて、必ずそのコンテナの上にボタンを配置しなければ正しい動作はしません。

 それでは、フレームコントロール上にコントロールをコントロール配列で貼り付ける方法を説明します。各コントロールの規定値のプロパティは次のように変更し、図2のようなフォームを作成されていることを前提に進めていきます。

コントロール名

規定値オブジェクト名

変更後オブジェクト名

プロパティ変更箇所

フレーム Frame1 fraCont1 Captionプロパティ

変更前:Frame1
変更後:性別

フレーム Frame2 fraCont2 Captionプロパティ

変更前:Frame2
変更後:趣味

オプションボタン Option1 optSex Captionプロパティ

変更前:Option1
変更後:男

チェックボックス Check1 chkHobby Captionプロパティ

変更前:Check1
変更後:ドライブ

コマンドボタン Command1 Command1 Captionプロパティ

変更前:Command1
変更後:OK

コマンドボタン Command2 Command2 Captionプロパティ

変更前:Command2
変更後:キャンセル

 まずは、フレームコントロール上にオプションボタンを貼り付ける方法を説明しなければなりませんね。難しく考えることはありません。単に対象となるフレームコントロール上へコントロールを貼り付ければよいだけです。サンプルでは、性別のフレームコントロール上に'男'というオプションボタンを貼り付ければよいだけです。同様に、趣味のフレームコントロール上に'ドライブ'というチェックボックスを貼り付けます。

 それでは、性別に使用しているオプションボタンからコントロール配列にしてみましょう。

  1. フォーム上の'男'というオプションボタンを選択します。
  2. 次に編集メニューから「コピー」を選択します。
  3. 次に、'性別'というフレームコントロールを選択し、もう一度編集メニューから、今度は「貼り付け」を選択します。貼り付ける前に、性別の対象となるフレームコントロールをアクティブに選択していることが重要です。
  4. すると「既に同じ名前のコントロール'optSex'があります。コントロール配列にしますか?」というメッセージが表示されますので、「はい」で答えます。
  5. 画面上の性別のフレームコントロール上にコピーが作成されたと思います。
  6. このコピーされたコントロールのプロパティを変更します。Captionプロパィ'の男'を'女'に変更し、最後にコントロールの位置を男の下へ整列するように移動します。

 今度は、趣味用のチェックボックスも同様にコントロール配列にします。

  1. フォーム上の'ドライブ'というチェックボックスを選択します。
  2. 次に編集メニューから「コピー」を選択します。
  3. 次に、'趣味'というフレームコントロールを選択し、もう一度編集メニューから今度は「貼り付け」を選択します。貼り付ける前に、趣味の対象となるフレームコントロールをアクティブに選択していることが重要です。
  4. すると「既に同じ名前のコントロール'chkHobby'があります。コントロール配列にしますか?」というメッセージが表示されますので、「はい」で答えます。ただし、趣味は全部で4つ用意してあるので、貼り付け操作はあと2回おこなう必要があります。※一度コントロール配列にしたコントロールを貼り付ける場合は、上記の確認メッセージは表示されません。
  5. 最後にそれぞれのCaptionプロパティを'音楽鑑賞'、'映画鑑賞'、'盆栽'と修正します。

 さて、図1のようにうまく作成することができましたか?さて、うまく配置できたが確認してみましょう。図3のように、うまく配置できている場合は、フレームコントロールからコントロールをはみ出して移動することはできません。フレームコントロールからフォームにはみ出して移動できる場合は、性別のフレームコントロール上に正しく貼り付けられていないことになります。

図3

 頭のよいあなたは、今回なぜコントロール配列にしたのか疑問に思ったに違いありません。コントロール配列の利点は、リソースの消費を抑える効果もありますが、なんといっても各イベントを一括管理できるところにあります。コントロール配列にしたイベントソースには、引数としてIndexという名前の変数が自動で生成されます。きっと、なぜコントロール配列にしたのか、後ほどの説明で納得していただけるでしょう。


 さてさて、今回のサンプルは、簡単な個人情報を入力するサンプルなのですから、入力したデータをどこかに保存しておかなければ再利用できません。今回はVBが用意しているレジストリへ保存してみることにします。

<レジストリを扱う関数>

 レジストリを扱う関数は[SaveSetting][GetSetting][DeleteSetting][GetAllSettings]というステートメント、または関数があります。スペルからだいたい想像できると思いますが、[GetSetting]関数は、レジストリからデータを読み込む関数で、[SaveSetting]ステートメントは、レジストリにデータを保存するものです。[DeleteSetting]ステートメントは、レジストリの内容を削除するステートメントです。[GetAllSettings]はここでは使用しませんが、レジストリの項目内のすべてのキーを列挙する関数です。

 それでは、サンプルを見ながら簡単に説明します。

 まずは、Form_Loadイベントから見ていきましょう。

Private Sub Form_Load()

    Dim intIndex As Integer ' コントロール配列のインデックス番号

    '
    ' レジストリに保存された内容を読み込む
    '

    ' 以前選択された「性別」を読み込む
    mintOptionIndex = GetSetting("hidesamp", "optcheck", "sex", 0)
    optSex(mintOptionIndex).Value = True


    ' 以前選択された「趣味」を読み込む
    For intIndex = 0 To 3
        ' 各項目のチェックボックスの選択状態をレジストリへ保存する
        chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby" & Trim(Str(intIndex)), 0)
    Next intIndex
End Sub



 いきなりレジストリからデータを取得する[GetSetting]関数を使っています。はじめてこのサンプルを起動した場合、当然レジストリには何のデータも登録されていませんから、データを読み込んでも意味がないように思いがちです。しかし、このイベントはプログラムが起動するたび(実際はフォームがロードされるたび)に実行されるので、保存されたデータを読み込むプログラムは書いておく必要があります。

 では、初めて起動されたかどうかはどう判断すればよいでしょうか?答えは簡単です。[GetSetting]関数には、デフォルト値を設定するパラメータが用意されています。つまり、データが保存されていない場合に返す値を指定できるのです。

 それでは、1行目から説明します。

mintOptionIndex = GetSetting("hidesamp", "optcheck", "sex", 0)

 まず、この行はレジストリに保存されている性別を取得するために使用しています。この関数の第1パラメータで指定している"hidesamp"、および第2パラメータで指定している"optcheck"、そして第3パラメータの"sex"は、レジストリに保存したときの名前と同じ値にセットする必要があります。最後に、第4パラメータで指定する内容が、先ほど説明したデフォルト値となります。
※これらのパラメータの詳細はヘルプの[GetSetting]や[SaveSetting]などのステートメントを参照しましょう。

 つまり、このステートメントを日本語読みすれば、

レジストリに登録されている"hidesamp"というアプリケーションの"optcheck"セクションの"sex"というキーに値がセットされていれば、その値を[mintOptionIndex]変数に代入しなさい。セットされていなければ[mintOptionIndex]変数には0を代入しなさい。

という意味になります。

 では次の optSex(mintOptionIndex).Value = True 行は何をしているのでしょう?先ほど性別をあらわすオプションボタンをコントロール配列にしました。そうなんです。コントロール配列を利用した場合、オブジェクト名がすべて'optSex'という名前になってしまい、そのオブジェクトを判別するには[Index]プロパティを参照する必要があるのです。男、および女のオプションボタンのプロパティを見てください。[Index]プロパティがそれぞれ0、そして1というユニークな値になっています。図4

図4

 

 オプションボタンの[Value]プロパティはをTrueに設定すれば選択状態になります。つまり、オプションボタンのへそに黒丸が付きます。この時点ですでに黒丸が付いていたものは自動的に解除されます。もちろん、対象となるのはグループ化されたオプションボタンのみです。

 これらを踏まえて日本語読みすれば、

sexというキーのレジストリに登録された内容のIndex番号のオプションボタンを選択状態、つまりへそに黒丸を入れなさいというステートメントになります。

 上記を理解できれば次のステートメントもなんとなく見えてくるはずです。その前にFor〜NextとTrim関数が新しく出てきましたね。説明しておきましょう。

<For〜Nextステートメント>

 フロー制御系のステートメントで、指定した回数分処理を繰り返すステートメントです。

<Trim関数>

 単に、指定した文字列の前後のスペースを取り除く関数です。この関数は結構使いますので覚えておきましょう。※LTrim関数でも同じ結果を得ることができます。

<Str関数>

 数値を文字列に変換する関数です。この関数で重要なのは、正の値の数値を文字列に変換した場合、先頭の文字列が必ず半角スペースになります。これには理由があります。数値の先頭には符合のエリアがあり、通常プラスの場合はその"+"は省略されています。つまり、次のように実験すれば一目瞭然です。

Dim a As Integer
a = 100
Text1.Text = "b" & Str(a)

結果は'b 100'

Dim a As Integer
a = -100
Text1.Text =  "b" & Str(a)

結果は'b-100'

となり、aが正の値の場合に限り、省略されたプラス記号がスペースに変換されたのです。

 さて、新しく出てきた関数の説明も終わったことですし、早速次のステートメントを日本語読みしてみましょう。

For intIndex = 0 To 3
    ' 各項目のチェックボックスの選択状態をレジストリへ保存する
    chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby" & Trim(Str(intIndex)), 0)
Next intIndex

 まずは、4回処理が繰り返されることを理解し、hobby0〜3キーのレジストリに登録された内容のIndex番号のチェックボックスが設定されることを理解しましょう。Trim関数とStr関数の結果を省略すれば

ntIndex = 0 の1回目

chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby0", 0)

ntIndex = 1 の2回目

chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby1", 0)

ntIndex = 2 の3回目

chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby2", 0)

ntIndex = 3 の4回目

chkHobby(intIndex).Value = GetSetting("hidesamp", "optcheck", "hobby3", 0)

というループになります。補足しておけば、チェックボックスの[Value]プロパティは、0 が未チェック1がチェック、そして2が無効となっているので、レジストリの登録されている値によってチェックボックスの状態が変化します。

 さて、理解できたでしょうか。では、選択された性別、そして趣味をレジストリ保存する処理を説明することにします。

Private Sub cmdOK_Click()

    Dim intIndex As Integer ' コントロール配列のインデックス番号
    '
    ' 選択されたオプションボタン、およびチェックボックスをレジストリに保存する
    '

    ' オプションボタンの選択状態をレジストリへ保存する
    SaveSetting "hidesamp", "optcheck", "sex", mintOptionIndex

    For intIndex = 0 To 3
        ' 各項目のチェックボックスの選択状態をレジストリへ保存する
        SaveSetting "hidesamp", "optcheck", "hobby" & Trim(Str(intIndex)), chkHobby(intIndex).Value
    Next intIndex

    ' フォームを閉じる
    Unload Me

End Sub

 このイベントは、OKボタンがクリックされたときのイベントです。ここで重要なのは、レジストリに保存する時の名前をどのように名前で保存したかが重要です。あとで読み込むときにその名前で読み込む必要があるからです。また保存する値は、性別のオプションボタン、および趣味のチェックボックスの[Value]プロパティの値をそれぞれのキーに保存していることに注目してください。

 今回は、このイベントの日本語の説明はやめ、あなたの課題とします。恐らくForm_Loadイベントが理解できていれば、その逆になるということなのでさほど難しくないと思います。ただし、2点だけ説明しておかなければなりません。1点は

SaveSetting "hidesamp", "optcheck", "sex", mintOptionIndex

で使用されている[mintOptionIndex]変数です。これはフォームレベルの変数で宣言する必要があります。このイベント内で変数宣言されていないのは、このフォームのすべてのイベントプロシージャーで利用できるように下記の場所で宣言しているためです。初めてのプログラミングの項目の図3で説明しているように、フォームのOption Explicitのすぐ下の行に次の宣言します。

Option Explicit
Private mintOptionIndex As Integer ' オプションボタンの状態を保存する

 また、この変数は次のイベント内で設定しています。性別のオプションボタンのClickイベントに次のようなプログラムを書きます。

Private Sub optSex_Click(Index As Integer)
    ' 選択されたインデックス番号を記憶
    mintOptionIndex = Index
End Sub

 このイベントは、性別の'男'、または'女'のオプションボタンがクリックされたときに発生するイベントです。Indexというパラメータが付いていることに注目してください。これはコントロール配列でチラッと説明しましたが、この1つのイベントで性別グループのすべての処理を一括処理できることを意味します。
 具体的に説明するとすれば、'男'がクリックされたとき、この[Index]プロパティには自動的に0が代入されており、'女'がクリックされたときは自動的に1が代入されているので、その区別を[Index]プロパティで制御できます。つまり、このイベントで記述したステートメントは、mintOptionIndexという変数に、クリックされたとき(へその黒丸が入ったとき)のIndex番号を代入しているのです。要するに、現在選択されているのは男か女かを判別するために使用しているのです。

ずいぶん長いくだくだしい説明で解かりにくかったかもしれません。アプリケーションを作成するにあたり、このサンプルで示したそれぞれの機能は非常によく使用されます。複雑に考えないで一連のパターンなんだと思って覚えてください。


では、次のステップへ進むことにします。  next.gif (2455 バイト)   back.gif (2463 バイト)