ここに出てくるイベント |
- Enter/フォーカス取得時
- Exit/フォーカス喪失時
- GotFocus/フォーカス取得後
- LostFocus/フォーカス喪失後
|
ラベルコントロールや使用可能プロパティが"いいえ"に設定されているコントロールなどを除いて、すべてのコントロール、フォーム、あるいはレポートのプレビューウィンドウなどは「フォーカス」を持つことができます。1つ1つのオブジェクトの集合体として構成されるWindowsシステムの画面では、この「フォーカス」は非常に重要な要素の1つでもあります。例えば、テキストボックスコントロールでは、次のようなフォーカス関連のイベントを持っています。
- フォーカス取得時
- フォーカス喪失時
- フォーカス取得後
- フォーカス喪失後
フォームの場合には、"フォーカス取得後"イベントと"フォーカス喪失後"しかありませんので、テキストボックスでもこの2つだけで事足りそうなのですが、「取得時」・「喪失時」というイベントも追加されているということを考えると、何らかの理由あるいは使い勝手の違いがあるはずです。そこでここでは、このテキストボックスの4つのイベントに焦点を当てて、フォーカス関連のイベントの動きをチェックしてみたいと思います。
 |
TABキーやEnterキーによるフォーカス移動では? |
次のサンプルフォームでは、すべてのテキストボックスについて、同様にして、イベントトレース用のプロシージャ呼び出しが設定してあります。

このフォームを使って、「顧客ID」→「氏名」→「シメイ」という順番で、TABキーによってフォーカスを移動させてみます。フォームを開くところからイベントのトレースを開始し、「シメイ」にフォーカスが移ったところでそのままフォームを閉じるまでの過程をトレースするものとします。なお、テキストボックス「顧客ID」は、タブ移動順が先頭になっています。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
顧客ID |
フォーカス取得時 |
2 |
顧客ID |
フォーカス取得後 |
3 |
顧客ID |
フォーカス喪失時 |
4 |
顧客ID |
フォーカス喪失後 |
5 |
氏名 |
フォーカス取得時 |
6 |
氏名 |
フォーカス取得後 |
7 |
氏名 |
フォーカス喪失時 |
8 |
氏名 |
フォーカス喪失後 |
9 |
シメイ |
フォーカス取得時 |
10 |
シメイ |
フォーカス取得後 |
11 |
シメイ |
フォーカス喪失時 |
12 |
シメイ |
フォーカス喪失後 |
結果は上表のようになりました。「顧客ID」→「氏名」→「シメイ」という順番でフォーカス移動を行っていますので、オブジェクト名もそのような順番になっていることが確認できるでしょう。また、それぞれのオブジェクトを見ても、今回取り扱っている4つのイベントがセットとなって、同じ順番で発生していることも分かります。さらに、実際の操作では、"フォーカス取得時"と"フォーカス取得後"、および"フォーカス喪失時"と"フォーカス喪失後"のそれぞれ2つのイベントがセットとなって、同時に発生することが分かりました。
実際のキーボード操作と合わせてみますと、まずフォームを開くと同時に、「顧客ID」の"フォーカス取得時"イベントと"フォーカス取得後"イベントが発生します。これは、このテキストボックスのタブ移動順が先頭になっているためです。その場合には特に操作することなく、これらのイベントが発生します。続いて、TABキーを押すと、フォーカスが「顧客ID」から「氏名」に移動します。これに伴い、「顧客ID」の"フォーカス喪失時"と"フォーカス喪失後"と、「氏名」の"フォーカス取得時"イベントと"フォーカス取得後"イベントが連続して発生します。「氏名」から「シメイ」へのフォーカス移動でも同じです。最後の11と12のイベントはフォームを閉じる際に発生したものです。おそらくこの時点でフォームのウィンドウ自体もフォーカスを失っているはずですので、それに伴って、アクティブなコントロールもフォーカスを同時に失い、そのイベントが発生するということが分かります。
これだけの操作だけでは、「取得時」と「取得後」などのようにイベントが分かれている理由やメリットは特に見当たりません。
 |
マウスによるコントロール移動では? |
先ほどの操作では、TABキーによって、タブ移動順に沿ってフォーカスを移動させましたが、今後はマウスを使って、離れたコントロールへのフォーカス移動を行ってみます。
まずフォームを開いて、「顧客ID」にフォーカスがある状態にします。ここからイベントのトレースを開始します。「顧客ID」にフォーカスがある状態から、「氏名」、「シメイ」という順番でそれぞれのテキストボックスをクリックしていきます。
その結果は次のようになりました。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
顧客ID |
フォーカス喪失時 |
2 |
顧客ID |
フォーカス喪失後 |
3 |
氏名 |
フォーカス取得時 |
4 |
氏名 |
フォーカス取得後 |
5 |
氏名 |
フォーカス喪失時 |
6 |
氏名 |
フォーカス喪失後 |
7 |
シメイ |
フォーカス取得時 |
8 |
シメイ |
フォーカス取得後 |
すでにフォームが開いている状態からトレースしたことと、最後にフォームを閉じていない点を除けば、TABキーによる操作とまったく同じ結果となっています。この時点でもまだ、「取得時」と「取得後」などの、イベントが分かれている理由やメリットは見当たりません。
 |
取得時/取得後、喪失時/喪失後の違い |
上記の2つの操作によるフォーカス関連イベントの発生順は、おそらく、イメージ通りの順番ではないでしょうか?。しかし、これでは「取得時/取得後」あるいは「喪失時/喪失後」というように、似た名前のイベントが別のものとして存在している理由が見つかりません。そこでいくつかの操作ケースを通して、その違いを見つけてみたいと思います。
■フォーム間でのフォーカス移動
先ほど使ったサンプルフォームとまったく同じフォームを作って、2つを並べて表示します。ただし、コピーしたフォームにはイベントトレース用のプロシージャ呼び出しは付けず、一方のフォーム(下図の左側のフォーム)のフォーカス関連イベントだけをチェックするようにします。

今、フォーカスは左側のフォームのテキストボックス「顧客ID」にあります。ここで、右側のフォームの「顧客ID」をクリックすることによって、左側のフォームからフォーカスを喪失させます。さらに続いて、左側のフォームをクリックしてフォーカスを戻します。ここではあくまでも「顧客ID」のテキストボックスをクリックするのではなく、フォームの余白部分やタイトルバーの部分をクリックすることによって左側のフォームを選択するようにします。
その結果は次の通りです。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
顧客ID |
フォーカス喪失後 |
2 |
顧客ID |
フォーカス取得後 |
ご覧のように、これまでとは違った結果が出ています。今後は"フォーカス喪失時"および"フォーカス取得時"イベントが発生していません。このことから、
- "フォーカス取得時"イベントは同一のフォーム内で、別のコントロールからフォーカスが移ってきたときだけ発生する
- "フォーカス喪失時"イベントは同一のフォーム内で、別のコントロールにフォーカスが移動したときだけ発生する
- "フォーカス取得後"イベントおよび"フォーカス喪失後"イベントは、フォーム内・フォーム外に関わらず、それぞれ、フォーカスを取得したとき・喪失したときに発生する
ということが分かります。つまり、フォーカスの移動に伴って何らかの処理をイベントプロシージャを使って行いたい場合、別のフォーム間とのフォーカス移動を考慮に入れるかどうかでその使用方法が違ってくることになります。もし、別のフォームからフォーカスが移ってきたときにも何らかの処理を行いたい場合、"Enter/フォーカス取得時"イベントプロシージャを使ってしまうと、処理されないことになってしまいますので、この点、イベントの使い方として注意が必要となります。逆に、"GotFocus/フォーカス取得後"イベントプロシージャに記述したコードは、まったく関係のないフォームからフォーカスが移ってきたときにも処理が実行されてしまいますので、処理内容をよく見極めてからこのイベントを使った方がよいでしょう。
■メイン/サブフォーム間でのフォーカス移動
今度は、「メインフォーム上のテキストボックス→サブフォーム上のテキストボックス」というフォーカス移動、および逆のケースについて調べてみます。さらに、サブフォームはメインフォームにとって1つのコントロールですので、タブ移動順に従って、メインフォーム上のテキストボックスからTABキーを押していくことによって、サブフォーム上の先頭のコントロールへとフォーカスが移動していきます(逆のケースはVBAなどで細工しないとできません)。この操作についても調べてみることにします。
ここでは、右図のようなフォームを使ってテストを行ってみます。
【メイン→サブへマウスのクリックでフォーカス移動】
メインフォームのテキストボックス「区分」にフォーカスがある状態で、サブフォーム上の「顧客ID」をクリックします。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
区分 |
フォーカス喪失時 |
2 |
区分 |
フォーカス喪失後 |
【サブ→メインへマウスのクリックでフォーカス移動】
サブフォームのテキストボックス「顧客ID」にフォーカスがある状態で、メインフォーム上の「区分」をクリックします。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
区分 |
フォーカス取得時 |
2 |
区分 |
フォーカス取得後 |
【メイン→サブへTABキーでフォーカス移動】
メインフォームのテキストボックス「区分」にフォーカスがある状態で、TABキーを押します。
発生順序 |
オブジェクト名 |
イベント名 |
1 |
区分 |
フォーカス喪失時 |
2 |
区分 |
フォーカス喪失後 |
ご覧のように、メインフォーム上のコントロール「区分」については、通常のイベントが発生していることが分かります。ところが、サブフォーム上のコントロールにフォーカスが移動したとき、あるいはフォーカスが喪失したときには何もイベントが発生していないのです。今回の操作はフォームを開いた直後に行いましたので、サブフォームでは「顧客ID」にすでにフォーカスがあります(上表では省略していますのが、そのときに"フォーカス取得時"イベントが発生しています。)。サブフォーム上で「顧客ID」がフォーカスを得ている状態で、メインフォームからサブフォーム上の「顧客ID」にフォーカスが移動しても何も起こらないのです。
このことから、もしサブフォーム「顧客ID」に何らかのフォーカス関連のイベントプロシージャを記述したとしても、メインフォームからフォーカスが移ってきたときには実行されない、ということをよく覚えておいた方がよいでしょう。
|