バージョン 6.3.3
 —  プログラミングガイド  —

タブコントロールの操作

このドキュメントでは、次のトピックについて説明します。


タブコントロールの作成

タブコントロールは、他の標準コントロール(リストボックスやプッシュボタンなど)と同じようにダイアログエディタで作成します。 つまり、ダイアログエディタ[挿入]メニューを使用して、あるいは[挿入]ツールバーからのドラッグ & ドロップによってスタティックに作成するか、または TYPE 属性を TABCTRL に設定した PROCESS GUI ACTION ADD ステートメントを使用してランタイム時にダイナミックに作成します。

また、ダイアログウィザードを使用して、タブコントロールを持つダイアログを生成できます。 この場合、このセクションで説明する多くの手法がウィザードによって自動的に適用されます。明示的な実装は不要で、展開したり "入力" したりするだけで、生成された構造が保持されます。 これにより、プログラミングにかかる労力を大幅に減少できます。

タブコントロールには、関連付けられたタブを含めることもまったく含めないこともできます。 タブは、ダイアログエディタでタブコントロールの属性ウィンドウから定義するか、またはランタイム時に TYPE 属性を TABCTRLTAB に設定した PROCESS GUI ACTION ADD ステートメントを実行することによって定義できます。

Top of page

コントロールのタブへの割り当て

タブコントロールはコンテナです。 ただし、このコントロールの Natural の実装では、個別のタブはコンテナではありません。 ダイアログエディタでタブコントロール内にコントロールを作成すると、そのコントロールの PARENT 属性には、現在アクティブなタブ(存在する場合)のハンドルではなく、タブコントロールのハンドルが自動的に設定されます。 子コントロールを特定のタブに関連付けるには、関連付けるタブのハンドルを子コントロールの OWNER 属性に設定します。 設定後は、タブが非アクティブになるとコントロールが自動的に非表示になり、タブが再度アクティブになると再び表示されます。

ただし、ダイアログエディタでは、タブコントロールの[UI アクティブ(U)]STYLE フラグが設定されている場合にのみ(デフォルトでは設定されています)、子コントロールの OWNER 属性が自動的に設定されることに注意してください。 この STYLE フラグが設定されていない場合、子コントロールの OWNER 属性は設定されません(つまり、NULL-HANDLE)。 後者の場合、タブを切り替えても、子コントロールの表示/非表示の切り替えは自動的には行われません。 [UI アクティブ(U)]STYLE は、ランタイム時には効力がないことに注意してください。

Top of page

タブコントロールページとしてのコントロールボックスの使用

前述のとおり、タブコントロール内の子コントロールはすべて、属しているタブに関係なくタブコントロールを親として持ちます。 これでも十分ですが、個別のサブ階層に各タブのコントロールを分けることをお勧めします。

これを実現する最も便利な方法は、タブ "ページ" を表す子コントロールボックスをタブごとに作成することです。 その後、他のすべての子コントロールを、対応するコントロールボックスの子コントロールとして作成します。 タブコントロールの[UI アクティブ(U)]STYLE フラグが設定されている場合、タブを切り替えるとコントロールボックスの表示/非表示の切り替えが自動的に行われます。したがって、対応する子コントロールの表示/非表示もコントロールボックスと一緒に切り替えられます(祖先のウィンドウが非表示になると、子コントロールは自動的に非表示になります)。 そうでない場合、プログラムで明示的にページを切り替える必要があります。これについては、次のセクションで説明します。

以下の図は、コントロールの構成を示しています。

Control organization

この図のように、各子コントロールボックスは、タブコントロールの背景テクスチャ(存在する場合)が表示されるように、透過にする必要があります。また、タブコントロールのサイズが変更されると必ず直ちにタブコントロールの内部エリアがコントロールボックスによって自動的かつ正確に埋められるように、[親と同サイズ(z)]STYLE を設定する必要があります。 また、タブコントロールが UI アクティブでない場合、常に 1 つの子コントロールボックスのみが表示されるように、各コントロールボックスは "排他的" である必要があります。

Top of page

異なるタブに属するコントロール間の切り替え

注意:
このセクションでは、UI アクティブではないタブコントロールについてのみ説明します。 UI アクティブの場合、コントロールの切り替えは Natural によって自動的に実行されます。

ダイアログエディタ上で、現在表示されていない、排他的なコントロールボックスに属するコントロール(またはコントロールボックス自体)を選択すると、ダイアログエディタによって自動的に切り替えが行われます。 ダイアログエディタによって、現在表示されている排他的なコントロールボックス(存在する場合)が非表示にされ(このコントロールボックス内に配置されているコントロールも非表示になります)、選択したコントロールが含まれているコントロールボックスが表示されます(このコントロールボックス内に配置されているコントロールもすべて表示されます)。 このプロセスは、選択方法(明示的、ステータスバーの選択ボックスから、暗黙的、Tab キーでコントロール間を移動してなど)の影響を受けません。

注意:
ステータスバーが表示されていない場合、[ツール]メニューの[オプション]コマンドで開く[オプション]ダイアログの[ダイアログエディタ]タブにある[ステータスバー]を設定します。

ランタイム時は、当然ながら、ユーザーによるタブの選択に応じて、対応するコントロールボックスが表示されたり、非表示になったりします。 これは、タブコントロールの CHANGE イベントでアクティブなタブをクエリし、対応するコントロールボックスの VISIBLE 属性を TRUE に設定することによって実現できます。 タブとコントロールボックスを関連付ける方法の 1 つは、ダイアログの AFTER-OPEN イベントで、コントロールボックスのハンドルを対応するタブの CLIENT-HANDLE 属性に設定することです。

次に例を示します。

/* Map control boxes to tabs:
#TAB-1.CLIENT-HANDLE := #CTLBOX-1
#TAB-2.CLIENT-HANDLE := #CTLBOX-2
..
#TAB-N.CLIENT-HANDLE := #CTLBOX-N

#CONTROLHANDLE OF GUI として定義されている場合、タブコントロール(#TABCTRL-1)の CHANGE イベントは次のようになります。

/* Get active tab
#CONTROL := #TABCTRL-1.SELECTED-SUCCESSOR
/* Switch to control box belonging to active tab:
#CONTROL := #CONTROL.CLIENT-HANDLE
IF #CONTROL <> NULL-HANDLE
  #CONTROL.VISIBLE := TRUE
END-IF

Top of page

タブ依存コントロールとタブ非依存コントロールの混在

状況によって、現在どのタブが選択されているかに関係なく、コントロールを表示させておきたい場合があります。

これを実現するには、以下の 2 つの方法があります。

  1. コントロールボックスを使用している場合、タブコントロールの内部エリアの一部だけを占めるようにコントロールボックスを小さくして、常に表示するコントロールのためのスペースを残すことができます。 この場合、コントロールボックスの[親と同サイズ(z)]STYLE をオフにする必要があります。

  2. コントロールボックスを使用せず、タブコントロールが UI アクティブの場合、常に表示する子コントロールを作成している間、タブコントロールの[UI アクティブ(U)]STYLE を一時的にオフにすることにより、常に表示されるコントロールを作成できます。

タブコントロールが UI アクティブでない場合、2 階層のコントロールボックスを使用できます。この場合、前述の子コントロールボックスを透過の最上位コントロールボックス(タブコントロールの子として作成)の子コントロールとして作成します。 これにより、([親と同サイズ(z)]フラグが設定されていない)最上位コントロールボックスで適切な位置とサイズを指定して、置換可能なリージョンを定義できます。

注意:
これは、ダイアログウィザードに使用されている手法によく似ています。 詳細については、「コントロールボックスの操作」を参照してください。

Top of page

キーボードナビゲーション

タブコントロール内のタブ間をキーボードで移動するには、以下の 3 つの方法があります。これらの方法は同時に組み合わせて使用できます。

  1. タブコントロールの[ブラウズ可能(z)]STYLE フラグが設定されている場合、そのタブコントロールはタブシーケンスに含まれています(つまり、Tab キーで移動できます)。 タブコントロールがフォーカスを受け取ると、矢印キーでタブ間を移動できます。 この場合、最初のタブと最後のタブとの間は "ラップアラウンド" されません。

  2. タブのキャプション(STRING 属性)には、次の文字がニーモニック文字であることを示すアンパサンド記号(&)を含むことができます。 Alt キーを押したままニーモニック文字を押すと、該当するタブが選択されます。 これにより、希望するタブにキーボードで "直接" 移動できます。

  3. ダイアログの[プロパティシート(p)]STYLE が設定されている場合、キーボードショートカットの Ctrl + Tab および Ctrl + Shift + Tab を使用して、それぞれ次のタブおよび前のタブにラップアラウンド付きで移動できます。

最後の手法は、タブコントロールまたはタブコントロール内のダイアログエレメントにフォーカスがなくても実行できることに注意してください。 フォーカスのあるコントロールから始まり、1 つ以上のタブコントロールを持つコンテナが見つかるまで、Natural によって各コンテナ(祖先)が確認されます。 見つかったコンテナにタブコントロールが 1 つだけ含まれている場合、キーボードショートカットはこのタブコントロールに適用されます。 複数のタブコントロールが含まれている場合、これらのショートカットは無効になります。 ダイアログにタブコントロールが含まれていない場合、ショートカットは、[プロパティシート(p)]STYLE が設定されていなかったかのように、通常の機能を実行します。

キーの組み合わせ Ctrl + Tab および Ctrl + Shift + Tab のデフォルトの処理は、ACCELERATOR 属性で再定義することによって上書きできることに注意してください。

Top of page

タブの切り替えイベント

タブの切り替えが実行されるたびに(実行したのがユーザーとプログラムのどちらであっても)、以下の一連のイベントが発生します。

  1. 現在選択されているタブが LEAVE イベントを受け取ります(抑制されていない場合)。 このイベントは通常、タブページ上のデータを検証および/または確定するために使用します。

  2. タブコントロールの MODIFIABLE 属性が確認されます。 この属性が FALSE に設定されている場合、タブの切り替えは実行されません。 現在選択されているタブが選択されたままになり、これ以上イベントは発生しません。 LEAVE イベント中に実行したデータ検証でエラーがあり、処理を続行する前にユーザーに訂正してもらう必要がある場合、これは有効です。

  3. 現在選択されているタブを OWNER として持つ、すべての直接的な子コントロール(存在する場合)が自動的に非表示になります。

  4. 新しいタブが選択されます。

  5. 新しく選択されたタブを OWNER として持つ、すべての直接的な子コントロール(存在する場合)が、VISIBLE 属性が TRUE に設定されている場合、自動的に表示されます。

  6. 新しく選択されたタブが ENTER イベントを受け取ります (抑制されていない場合)。 このイベントは通常、新しいタブページ上のコントロールを初期化するために使用します。

  7. タブコントロールが CHANGE イベントを受け取ります。 これは、各タブのイベントハンドラを変更せずにタブの切り替えを追跡し、対応するのに便利です。

コントロールの作成時は、選択されているタブは最初の ENTER イベントを受け取らず、タブコントロールも最初の CHANGE イベントを受け取らないことに注意してください。 また、タブコントロールを含むダイアログが閉じられるときは、現在選択されているタブは LEAVE イベントを受け取りません。

Top of page