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

ダイアログバーコントロールの操作

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


はじめに

ダイアログバーは、ダイアログのフレームの内部側辺の 1 つにドッキングまたは(オプションで)別個のフローティングウィンドウに表示可能なツールバーコントロールに類似しています。 ただし、ツールバーコントロールと異なり、ダイアログバーコントロールは、汎用コンテナコントロールとして考えられており、主にツールバー項目を含むためだけのものとしては考えられていません。 さらに、ツールバーコントロールとダイアログバーコントロールには表示や動作に多数の違いがあります。その一部を説明します。

ダイアログバーコントロールのよい例が Natural スタジオのライブラリワークスペースウィンドウです。

Top of page

ダイアログバーコントロールの作成

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

Top of page

ダイアログバーコントロールのタイプ

ダイアログバーコントロールは以下の 3 つの基本形式(複雑さの順番)のいずれかで存在します。

  1. ドッキングもサイズ変更も不可能。

  2. ドッキングは可能だが、サイズ変更は不可能。

  3. ドッキングもサイズ変更も可能。

DRAGGABLE 属性が設定されている場合、ダイアログバーコントロールはドッキング可能です。 [ダイナミック(Y)]STYLE フラグが設定されている場合、サイズ変更可能です。

以下の例は、ドッキングもサイズ変更もできないダイアログバーの例を示しています。 右側の編集エリアはダイアログのクライアントエリア全体を満たしています。 ダイアログバーは、ドラッグ不可能で、配置されている側辺の長さいっぱいに拡張します。

ダイアログエディタ[ダイアログバー属性]ウィンドウで"[ドッキング可能]"状態を設定すると、ウィンドウがドラッグ可能になります。 ダイアログバーは、ドッキングする側辺の全長を使用するために拡張しないことにも注意してください(別のダイアログバーコントロールまたはツールバーコントロールをその下にドッキングできます)。

ユーザーは、ダイアログバーコントロールをドラッグし、それをオーナーダイアログの別の側辺に再度ドッキングしたり、以下のように別個のフローティングウィンドウにしたりできます。

ダイアログバーコントロールを(属性ウィンドウの[ダイナミック(Y)]スタイルフラグをチェックして)サイズ変更可能にすると、垂直スプリットバーが表示され、ダイアログバーコントロールがサイズ変更可能になります。 サイズ変更可能なダイアログバーコントロールは、ドッキングする側辺(サイズ変更不可能なバーが使用していない側辺)の全長を満たすために拡張することに注意してください。

グリッパバー、ズームボタン、および閉じるボタンが(属性ウィンドウの[グリッパ(g)]、[ズームボタン(z)]、および[閉じるボタン(x)]の各スタイルフラグをチェックして)追加されると、ダイアログバーコントロールは、Natural スタジオのライブラリワークスペースを表示するために使われているコントロールに似た外観になります。 同じ列にサイズ変更可能なダイアログバーが他にないので、ズームボタンが無効になっていることに注意してください。

2 つ目のサイズ変更可能なダイアログバーコントロールを追加して、同じ列の最初のもののそばにドッキングすると、水平スプリットバーが表示され、2 つのダイアログバーコントロールの相対的なサイズが変更可能になります。 ズームボタンが有効になったことに注意してください。

ズームボタンをクリックすると、サイズ変更可能なダイアログバーコントロールの最大化の状態と元の状態とが切り替わります。 ダイアログバーコントロールの最大化により、同じ列の他のサイズ変更可能なダイアログバーコントロールは最小化され、以下のように、最大化したバーが使用できるようにスペースが解放されます。

最大化したバー上のズームボタンの近くに表示される矢印の方向が、次にこのボタンが押されるとバーが(最大化ではなく)元のサイズに戻されることを示すために変わっていることに注意してください。 バーが復元されると、列上のすべてのサイズ変更可能なダイアログバーは標準のサイズに戻ります。 このサイズは通常、それまで列に表示されていたバーに変更(例:表示されているバーを非表示にする、非表示のバーを表示する、新規バーを列にドッキングするなど)がない限り、最大化される前のサイズになります。

列上のバーの長さが水平スプリットバーによって変更された場合、列上に表示されているすべてのバーは自動的に復元されます。

Top of page

UI 透過

ドッキング可能なダイアログバーコントロールは、通常はそのグリッパバー(存在する場合)またはその背景をつかんでドラッグできます。 ただし、[UI 透過(T)]スタイルが設定されている場合、バーはグリッパバー(存在する場合)経由でのみドラッグできます。 そのような(サイズ変更可能な)バーにグリッパバーがない場合、コントロールのサイズ変更はスプリットバー(複数可能)経由でのみ可能です。これは状況によっては適切な機能です。 また、グリッパバー経由のドラッグのみを可能にすると、意図しないドラッグ操作の実行を回避できます。

Top of page

Client-Size イベント

ダイアログのクライアントウィンドウは、ツールバー、ステータスバー、およびダイアログバーコントロールによって使われている領域を排除するためにサイズを縮小します。 ドッキング可能なウィンドウ(ツールバーまたはダイアログバーコントロール)がフローティングになる、オーナーウィンドウの別の側辺に再ドッキングされる、または表示されたり非表示にされたりすると、ウィンドウの外側の大きさが変わっていなくても、クライアントウィンドウのサイズが変更されます。 SIZE イベントは、ダイアログの外側のサイズの変更のために確保されているため、クライアントウィンドウのサイズを把握する必要のあるアプリケーションは、この目的のために SIZE イベントではなく CLIENT-SIZE イベントを使用します。 ダイアログクライアントウィンドウの実際のサイズは、このイベントで INQ-INNER-RECT アクションを使用することによって、確認できます。

Top of page

閉じるボタン

閉じるボタン(存在する場合)はダイアログバーコントロールを閉じるのではなく、非表示にします。これは、フローティングツールバーコントロールの閉じるボタンでも同様です。 バーを再表示する方法は、アプリケーションによって提供されます。 次のセクションでは、これを実行するコードを(他の内容と一緒に)紹介します。

Top of page

サンプルコード

以下のリストは、ユーザーによるツールバーとダイアログバーの表示の制御を可能にする、ほとんどのケースで "このまま" 使用できる外部サブルーチンの完全なリストです。 コードは、MDI アプリケーションで動作できるように設計されていますが、MDI 以外(つまり、SDI)のアプリケーションでも動作します。

サブルーチンは、ツールバーおよびダイアログバーのキャプション(STRING 属性)をダイアログのコンテキストメニューに付加します。 ダイアログにコンテキストメニューがない場合、コンテキストメニューが 1 つ作成され、自動的にダイアログに割り当てられます。 MDI アプリケーションでは、ツールバーとダイアログバーの一部はグローバル(すべてのタイプの MDI 子ダイアログが該当)であり、一部はプライベート(1 つのタイプの MDI 子ダイアログだけが該当)であることが想定されています。 例えば、Natural スタジオでは、オブジェクトツールバーはグローバルツールバーであり、ダイアログエディタオプションツールバーはダイアログエディタに対するプライベートなツールバーです。 ユーザーが MDI 子ダイアログを切り替えると、グローバルツールバーと現在アクティブなダイアログに関連付けられているプライベートツールバーだけが表示されるように、コンテキストメニューが変更されます。 さらに、このダイアログが最後に表示されたときと同じプライベートバーが表示されます([ダイアログ属性]ウィンドウの[レイアウト保存]チェックボックスがチェックされている場合、表示されたバーのサブセットもセッション間で保持されます)。

このサブルーチンは、以下のように、メインダイアログ(MDI アプリケーションの MDI フレームダイアログ)の AFTER-ANY イベントハンドラで呼び出す必要があります(メインダイアログのハンドル変数名は #DLG$WINDOW のデフォルト値に設定されているとします)。

PERFORM PROCESS-BAR-COMMANDS #DLG$WINDOW

その他に、以下の手順を任意で実行します。

  1. バーは、コントロールシーケンスに表示される順番でコンテキストメニューにリストされます。 したがって、ツールバーおよびダイアログバーの順序付けの再実行が必要な場合があります(例:MDI アプリケーションでプライベートツールバーの前にグローバルツールバーが表示されるようにするため)。

  2. コードは、コンテキストメニューで有効なバーのリストの前にセパレータを挿入しません。 したがって、ダイアログに対してすでにコンテキストメニューを使用している場合、コンテキストメニューがセパレータで終了することを確認する必要がある場合があります。

  3. MDI アプリケーションでは、プライベートバーごとに、ダイアログエディタでバーの属性ウィンドウの[コントロール ID]フィールドに、そのツールバーが "属する" ダイアログの名前(例:ダイアログのファイル名が CHILD.NS3 であれば "CHILD")を入力する必要があります。 各グローバルバーに対しては、このフィールドは空にしておきます。 MDI 子ダイアログがアクティブでないときにのみバーを表示する場合、ここに MDI フレームダイアログの名前を入力します。

  4. MDI アプリケーションでは、デフォルトで表示しない各バーに対し、属性ウィンドウの[有効化]チェックボックスをオフにする必要があります。

DEFINE DATA
PARAMETER
  1 #DIALOG     HANDLE OF GUI
LOCAL
  1 #CONTROL       HANDLE OF GUI  
  1 #ACTIVE-DLG    HANDLE OF GUI  
  1 #CTXMENU       HANDLE OF CONTEXTMENU  
  1 #MITEM-DYN     HANDLE OF MENUITEM
LOCAL USING NGULKEY1
END-DEFINE
*
DEFINE SUBROUTINE PROCESS-BAR-COMMANDS
  DECIDE ON FIRST *EVENT  
    VALUE 'COMMAND-STATUS'   
       PERFORM COMMAND-STATUS    
    VALUE 'IDLE'   
       PERFORM IDLE
    VALUE 'CLICK' 
      PERFORM CLICK    
    VALUE 'BEFORE-OPEN'  
      PERFORM BEFORE-OPEN    
    VALUE 'AFTER-OPEN'   
      PERFORM AFTER-OPEN  
   NONE   
      IGNORE 
   END-DECIDE
*
   DEFINE SUBROUTINE COMMAND-STATUS 
     /* Must enable our commands, otherwise they're automatically disabled!    
     #CTXMENU := #DIALOG.CONTEXT-MENU    
     #MITEM-DYN := #CTXMENU.FIRST-CHILD    
     REPEAT WHILE #MITEM-DYN <> NULL-HANDLE  
        IF #MITEM-DYN.CLIENT-HANDLE <> NULL-HANDLE    
          #MITEM-DYN.ENABLED := TRUE      
        END-IF      
        #MITEM-DYN := #MITEM-DYN.SUCCESSOR   
     END-REPEAT  
   END-SUBROUTINE
*  
   DEFINE SUBROUTINE IDLE   
     PERFORM SWITCH-BARS  
   END-SUBROUTINE
*  
   DEFINE SUBROUTINE CLICK   
     #CONTROL := *CONTROL    
     IF #CONTROL.TYPE = MENUITEM AND #CONTROL.PARENT = #DIALOG.CONTEXT-MENU
          #MITEM-DYN := #CONTROL      
          #CONTROL := #MITEM-DYN.CLIENT-HANDLE      
          IF #CONTROL <> NULL-HANDLE     
             IF #MITEM-DYN.CHECKED = CHECKED           
                 #CONTROL.ENABLED := FALSE           
                 #CONTROL.VISIBLE := FALSE        
         ELSE           
                #CONTROL.ENABLED := TRUE           
                #CONTROL.VISIBLE := TRUE        
         END-IF      
       END-IF    
      END-IF  
   END-SUBROUTINE
*  
  DEFINE SUBROUTINE BEFORE-OPEN  
     #CTXMENU := #DIALOG.CONTEXT-MENU    
     #MITEM-DYN := #CTXMENU.FIRST-CHILD    
     REPEAT WHILE #MITEM-DYN <> NULL-HANDLE   
        IF #MITEM-DYN.CLIENT-HANDLE <> NULL-HANDLE        
          #CONTROL := #MITEM-DYN.CLIENT-HANDLE        
        IF #CONTROL.VISIBLE          
          #MITEM-DYN.CHECKED := CHECKED        
       ELSE          
          #MITEM-DYN.CHECKED := UNCHECKED        
       END-IF      
     END-IF      
     #MITEM-DYN := #MITEM-DYN.SUCCESSOR    
    END-REPEAT  
   END-SUBROUTINE
*  
   DEFINE SUBROUTINE AFTER-OPEN    
     /* for MDI frames, unsuppress IDLE event to track active child change    
     IF #DIALOG.TYPE = MDIFRAME    
       #DIALOG.SUPPRESS-IDLE-EVENT := NOT-SUPPRESSED    
     END-IF   
     /* if dialog has no context menu, create one    
     #CTXMENU := #DIALOG.CONTEXT-MENU    
     IF #CTXMENU = NULL-HANDLE   
         PROCESS GUI ACTION ADD WITH PARAMETERS         
            HANDLE-VARIABLE = #CTXMENU         
            TYPE = CONTEXTMENU         
            PARENT = #DIALOG      
     END-PARAMETERS GIVING *ERROR      
     #DIALOG.CONTEXT-MENU := #CTXMENU    
   END-IF    
   /* unsuppress context menu's BEFORE-OPEN event for item update    
   #CTXMENU.SUPPRESS-BEFORE-OPEN-EVENT := NOT-SUPPRESSED    
   /* display bars according to context    
   PERFORM SWITCH-BARS  
  END-SUBROUTINE
*  
  DEFINE SUBROUTINE SWITCH-BARS  
     IF #DIALOG.TYPE = MDIFRAME      
       #ACTIVE-DLG := #DIALOG.ACTIVE-CHILD    
     END-IF    
     IF #ACTIVE-DLG = NULL-HANDLE    
       #ACTIVE-DLG := #DIALOG    
     END-IF    
     IF #ACTIVE-DLG <> #DIALOG.CLIENT-HANDLE    
       #CTXMENU := #DIALOG.CONTEXT-MENU      
       IF #CTXMENU <> NULL-HANDLE      
         /* Remove any dynamic menu items previously created        
         #CONTROL := #CTXMENU.FIRST-CHILD        
         REPEAT WHILE #CONTROL <> NULL-HANDLE        
           #MITEM-DYN := #CONTROL.SUCCESSOR          
           IF #CONTROL.CLIENT-HANDLE <> NULL-HANDLE         
              PROCESS GUI ACTION DELETE WITH #CONTROL          
           END-IF          
           #CONTROL := #MITEM-DYN        
         END-REPEAT        
         /* Search for all tool bar and dialog bar controls        
         #CONTROL := #DIALOG.FOLLOWS        
         REPEAT WHILE #CONTROL <> #DIALOG          
            IF #CONTROL.TYPE = TOOLBARCTRL OR             
                #CONTROL.TYPE = DIALOGBAR            
              #CONTROL.CLIENT-KEY := 'CONTROL-ID'            
              IF #CONTROL.CLIENT-VALUE = ' ' OR               
                  #CONTROL.CLIENT-VALUE = #ACTIVE-DLG.NAME           
               #CONTROL.VISIBLE := #CONTROL.ENABLED              
               /* Create menu entry for bar              
               PROCESS GUI ACTION ADD WITH PARAMETERS              
                 HANDLE-VARIABLE = #MITEM-DYN                
                 TYPE = MENUITEM                
                 PARENT = #CTXMENU                
                 STRING = #CONTROL.STRING                
                 SUCCESSOR = #MITEM-DYN                
                 CLIENT-HANDLE = #CONTROL              
               END-PARAMETERS GIVING *ERROR            
             ELSE              
               #CONTROL.VISIBLE := FALSE            
             END-IF          
           END-IF          
           #CONTROL := #CONTROL.FOLLOWS        
         END-REPEAT      
       END-IF      
       /* Save handle of currently active dialog      
       #DIALOG.CLIENT-HANDLE := #ACTIVE-DLG    
     END-IF  
  END-SUBROUTINE
END-SUBROUTINE
END

Top of page