研究開発

はじめてのVectorScript

第5章 モダンダイアログ

Vw2015より、旧ダイアログ関数群は廃止になり、カスタムダイアログはモダンダイアログのみ有効になりました。そのため、旧手続き、関数を使っているプログラムは

Error: Identifier not declared.

が出てしまい書きなえなければ動きません。そこで今回はモダンダイアログについてご説明したいと思います。

まず、ダイアログの種類は2つのカテゴリーに分かれます。定義済みアラートとカスタムダイアログです。
定義済みアラートとは、

AlrtDialog( message : STRING );

や、

IntDialog( request : STRING; default : STRING ) : INTEGER;

のような手続き、関数が用意されていて完結しているもので、UIは固定です。
これらは用意されたUIを表示し、表示内容を引数で渡したり、入力内容を戻り値で受けたりして、結果を得るタイプのものです。
一方、カスタムダイアログとは、UIはプログラムする人が比較的自由に作ることが可能であり、ダイアログ上で起こるアクション(イベント)を自由に処理できます。
今回旧関数から移行するために使うのですが、UIや情報を取得するための処理を自分で制御しなければいけません。
ただし、旧関数群と違うのは、UIの位置を座標による制御から、基準となるUIの下にとか右にとかのようにVw任せに位置を決められるようになりました。
そこにはどのようなメリットがあるかというと、あとからUIを追加することになった場合、旧関数群のときには関係するUIの座標はすべて変えなければなりませんでしたが、モダンの場合にはすべての位置が自動変更になります。

・Hello World!!

PROCEDURE Example501;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
				END;
				kCancel:
				BEGIN
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'Hello, world!', FALSE, 'OK', 'キャンセル' );
		CreateStaticText( dialogID, 3, 'こんにちは 世界!', 16 );
		SetFirstLayoutItem( dialogID, 3 );
		result := RunLayoutDialog( dialogID, DialogHandler );
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example501 );

レイアウトの宣言(CreateLayout)とダイアログの表示(RunLayoutDialog)の間で、ダイアログ上に配置するアイテムを宣言(APIをコール)します。
そののち、ダイアログが表示(RunLayoutDialog)されている間の処理がコールバックルーチンとして、DialogHandler(任意の手続き名)に飛び、OKかCancelボタンが押されるまで、ダイアログの処理をし、OKかCancelボタンが押されたら、ダイアログを閉じ、ダイアログの表示(RunLayoutDialog)以降に進みます。

ダイアログの台紙は

CreateLayout( dialogTitle : STRING; hasHelp : BOOLEAN; defaultButtonName, cancelButtonName : STRING ) : LONGINT;

を使います。
dialogTitleにダイアログのタイトル名、ヘルプエリアを追加したい場合には、引数hasHelpをTRUEとし、デフォルトボタンとキャンセルボタンの文字列を入れます。
デフォルトボタンとはリターンキーを押したときに反応するボタンになります。
キャンセルボタンとはescキー(Macはコマンドキー+ピリオドも)に反応するボタンになります。

dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'はい', 'いいえ' );

また、
dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', '' );

や、
dialogID := CreateLayout( 'モダンダイアログ', FALSE, '', '終了' );

さらにこの台紙にアイテムを乗せていくのですが、そこは後述しますが、

RunLayoutDialog(dialogID : LONGINT; callback : PROCEDURE):LONGINT;

を発行すると、ダイアログ表示ルーチンに行きます。
第一引数にダイアログの台紙になるCreateLayoutの戻り値を渡し、第二引数にコールバック関数名を渡すことで、ダイアログを開いてユーザの操作を待つことになります。
ダイアログ上で起きたアクションは、

PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );

のitemにどのアイテムをいじったかで、アイテム番号が返ります。アイテム番号はレイアウトダイアログ上にプログラマが任意でつけたIDが返ってきます。
例えば、ID5番のボタンをクリックされると、DialogHandler関数に飛んできて、itemが5と入ってきますので、
ケース文を使って処理する事になります。固定で、OKボタンを押されたときは1、キャンセルボタンを押されたときは2が返ります。
また、初めてダイアログが開かれたときにはSetupDialogC、ダイアログが閉じられる直前に、SetdownDialogCが必ず返ります。

・スタティックテキスト、エディットテキスト、エディット整数、エディット実数

PROCEDURE Example502;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;
		theStr : STRING;
		thrInt : INTEGER;
		thrReal : REAL;
		boo : BOOLEAN;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
					SetItemText( dialogID, 5, '左よせ' );
					SetItemText( dialogID, 6, '中央揃え' );
					SetItemText( dialogID, 7, '右よせ' );
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
					GetItemText( dialogID, 4, theStr );
					IF Len( theStr ) = 0 THEN
					BEGIN
						SelectEditText( dialogID, 4 );
						item := -1;
					END;

					IF NOT GetEditInteger( dialogID, 9, thrInt ) THEN
					BEGIN
						SelectEditText( dialogID, 9 );
						item := -1;
					END;

					IF NOT GetEditReal( dialogID, 11, 1, thrReal ) THEN
					BEGIN
						SelectEditText( dialogID, 11 );
						item := -1;
					END;
				END;
				kCancel:
				BEGIN
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', 'キャンセル' );

		CreateStaticText( dialogID, 3, '文字列:', 16 );
		SetFirstLayoutItem( dialogID, 3 );
		CreateEditText( dialogID, 4, 'あいう', 16 );
		SetRightItem( dialogID, 3, 4, 0, 0 );
		CreateStaticText( dialogID, 5, 'default text', 16 );
		SetBelowItem( dialogID, 3, 5, 0, 0 );
		CreateCenteredStaticText( dialogID, 6, 'default text', 32 );
		SetBelowItem( dialogID, 5, 6, 0, 0 );
		CreateRightStaticText( dialogID, 7, 'default text', 32 );
		SetBelowItem( dialogID, 6, 7, 0, 0 );
		CreateStaticText( dialogID, 8, '整数:', 16 );
		SetBelowItem( dialogID, 7, 8, 0, 0 );
		CreateEditInteger( dialogID, 9, 123, 16 );
		SetRightItem( dialogID, 8, 9, 0, 0 );
		CreateStaticText( dialogID, 10, '実数:', 16 );
		SetBelowItem( dialogID, 8, 10, 0, 0 );
		CreateEditReal( dialogID, 11, 1, 123.456, 16 );
		SetRightItem( dialogID, 10, 11, 0, 0 );

		result := RunLayoutDialog( dialogID, DialogHandler );
		IF result = 1 THEN
		BEGIN
		END;
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example502 );

ユーザが変更不能なテキストは

CreateStaticText(dialogID, itemID : LONGINT; text : STRING; widthInCharacters : LONGINT);

を使います。ユーザは変更不能ですが、プログラムからは変更可能です。見出しや計算結果等文字列を表示させるために使います。
すでにIDの1と2は予約済みですので3以降を使います。連番でなくても大丈夫です。
そのあとに、このアイテムはすべてのアイテムの基準になりますと宣言する、

SetFirstLayoutItem(dialogID, firstItemID : LONGINT);

をコールします。このアイテムを基準に、
次のアイテムは下

SetBelowItem(dialogID, srcItemID, belowtItemID : LONGINT; indent, lineSpacing : INTEGER);

次のアイテムは右

SetRightItem(dialogID, srcItemID, rightItemID : LONGINT; indent, lineSpacing : INTEGER);

と設定していきます。これのおかげで、アイテムの位置が座標でなく自動的に配置されるわけです。
ユーザが編集可能なテキストは

CreateEditText(dialogID, itemID : LONGINT; defaultText : STRING; widthInCharacters : LONGINT);

を使います。
また、CreateStaticTextは、「左よせ」のスタティックテキストになりますが、
中央揃え

CreateCenteredStaticText(dialogID, controlID : LONGINT; text : STRING; widthInCharacters : INTEGER);

右よせ

CreateRightStaticText(dialogID, itemID : LONGINT; text : STRING; widthInCharacters : INTEGER);

も用意されています。

さらに、文字列だけではなく、
ユーザが編集可能な整数は、

CreateEditInteger(dialogID, itemID, defaultValue, widthInCharacters : LONGINT);

ユーザが編集可能な実数は、

CreateEditReal(dialogID, itemID, editRealType : LONGINT; defaultValue : REAL; widthInCharacters : LONGINT);

を使って入力させるエディットフィールドも用意されています。
エディットテキストとの大きな違いは、数値の入力の判断が可能となり、プログラマ側でエラー処理ができます。

ダイアログを表示したあとの処理として、CASE文を使って処理の分岐をします。
初期化をする場合には、ケース文のSetupDialogC:のところに書くことで、ダイアログを開いた最初に1回だけ実行します。
スタティックテキストのそれぞれの文字列を、

SetItemText(dialogID, componentID : LONGINT; text : DYNARRAY of CHAR);

を使って初期設定しています。
終了する時にする場合には、ケース文のSetdownDialogC:のところに書くことで、ダイアログを閉じる前に1回だけ実行します。

OKボタン(ID 1)を押されたときに、

GetItemText(dialogID, componentID : LONGINT; VAR text : STRING);

を使ってエディットテキスト内の文字列を取って、空でないかを、

Len(v : DYNARRAY of CHAR):INTEGER;

を使って文字数を調べる事で確認できる。
その結果、問題有りと判断すれば、

SelectEditText(dialogID, componentID : LONGINT);

を使ってエディットテキストを選択状態にし注意を促し、itemに-1を入れる事で、OKを無効にします。

エディット整数は、

GetEditInteger(dialogID, itemID : LONGINT; VAR value : LONGINT):BOOLEAN;

エディット実数、

GetEditReal(dialogID, itemID, editRealType : LONGINT; VAR value : REAL):BOOLEAN;

を使って数値を確認できますが、数値以外のものが入っていた場合FALSEが返りますのでやはり同じようにして、OKを無効にします。

・ラジオボタン、チェックボックス、3状態チェックボックス

PROCEDURE Example503;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;
		RadioButton1 : BOOLEAN;
		RadioButton2 : BOOLEAN;
		RadioButton3 : BOOLEAN;
		RadioButton4 : BOOLEAN;
		RadioButton5 : BOOLEAN;
		RadioButton6 : BOOLEAN;
		RadioButton7 : BOOLEAN;
		RadioButton8 : BOOLEAN;
		RadioButton9 : BOOLEAN;
		CheckBox1 : BOOLEAN;
		CheckBox2 : BOOLEAN;
		gState : INTEGER;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		VAR
			oneBoo, twoBoo : BOOLEAN;
			iState : INTEGER;
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
					SetBooleanItem( dialogID, 20, TRUE );
					SetBooleanItem( dialogID, 40, TRUE );
					SetBooleanItem( dialogID, 80, TRUE );
					SetBooleanItem( dialogID, 110, TRUE );
					SetThreeStateCheckBoxState( dialogID, 60, 2 );
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
					GetBooleanItem( dialogID, 10, RadioButton1 );
					GetBooleanItem( dialogID, 20, RadioButton2 );
					GetBooleanItem( dialogID, 30, RadioButton3 );
					GetBooleanItem( dialogID, 40, CheckBox1 );
					GetBooleanItem( dialogID, 50, CheckBox2 );
					GetThreeStateCheckBoxState( dialogID, 60, gState );
					GetBooleanItem( dialogID, 70, RadioButton4 );
					GetBooleanItem( dialogID, 80, RadioButton5 );
					GetBooleanItem( dialogID, 90, RadioButton6 );
					GetBooleanItem( dialogID, 100, RadioButton7 );
					GetBooleanItem( dialogID, 110, RadioButton8 );
					GetBooleanItem( dialogID, 120, RadioButton9 );
				END;
				kCancel:
				BEGIN
				END;
				40..50:
				BEGIN
					GetBooleanItem( dialogID, 40, oneBoo );
					GetBooleanItem( dialogID, 50, twoBoo );
					IF oneBoo AND twoBoo = TRUE THEN
					BEGIN
						SetThreeStateCheckBoxState( dialogID, 60, 1 );
					END
					ELSE IF oneBoo OR twoBoo = FALSE THEN
					BEGIN
						SetThreeStateCheckBoxState( dialogID, 60, 0 );
					END
					ELSE
					BEGIN
						SetThreeStateCheckBoxState( dialogID, 60, 2 );
					END;
				END;
				60:
				BEGIN
					GetThreeStateCheckBoxState( dialogID, 60, iState );
					IF iState = 1 THEN
					BEGIN
						SetBooleanItem( dialogID, 40, TRUE );
						SetBooleanItem( dialogID, 50, TRUE );
					END
					ELSE IF iState = 0 THEN
					BEGIN
						SetBooleanItem( dialogID, 40, FALSE );
						SetBooleanItem( dialogID, 50, FALSE );
					END;
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', 'キャンセル' );

		CreateRadioButton( dialogID, 10, 'ラジオボタン1' );
		SetFirstLayoutItem( dialogID, 10 );

		CreateRadioButton( dialogID, 20, 'ラジオボタン2' );
		SetBelowItem( dialogID, 10, 20, 0, 0 );

		CreateRadioButton( dialogID, 30, 'ラジオボタン3' );
		SetBelowItem( dialogID, 20, 30, 0, 0 );

		CreateCheckBox( dialogID, 40, 'チェックボックス1' );
		SetBelowItem( dialogID, 30, 40, 0, 0 );

		CreateCheckBox( dialogID, 50, 'チェックボックス2' );
		SetBelowItem( dialogID, 40, 50, 0, 0 );

		CreateThreeStateCheckBox( dialogID, 60, '3状態チェックボックス' );
		SetBelowItem( dialogID, 50, 60, 0, 0 );

		CreateGroupBox( dialogID, 200, 'グループボックス1', TRUE );
		SetBelowItem( dialogID, 60, 200, 0, 0 );

		CreateRadioButton( dialogID, 70, 'ラジオボタン4' );
		SetFirstGroupItem( dialogID, 200, 70 );

		CreateRadioButton( dialogID, 80, 'ラジオボタン5' );
		SetBelowItem( dialogID, 70, 80, 0, 0 );

		CreateGroupBox( dialogID, 300, 'グループボックス2', TRUE );
		SetBelowItem( dialogID, 200, 300, 0, 0 );

		CreateRadioButton( dialogID, 90, 'ラジオボタン6' );
		SetFirstGroupItem( dialogID, 300, 90 );

		CreateRadioButton( dialogID, 100, 'ラジオボタン7' );
		SetBelowItem( dialogID, 90, 100, 0, 0 );

		CreateRadioButton( dialogID, 110, 'ラジオボタン8' );
		SetBelowItem( dialogID, 100, 110, 0, 0 );

		CreateRadioButton( dialogID, 120, 'ラジオボタン9' );
		SetBelowItem( dialogID, 110, 120, 0, 0 );

		result := RunLayoutDialog( dialogID, DialogHandler );
		IF result = 1 THEN
		BEGIN
		END;
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example503 );

複数の選択肢から項目を選ぶにはラジオボタン

CreateRadioButton(dialogID, itemID : LONGINT; text : STRING);

を使います。続けて宣言することで、ラジオボタンは目に見えないグループとして扱われます。この意味は後述します。

選択する、しないをオンオフで選ぶにはチェックボックス

CreateCheckBox(dialogID, itemID : LONGINT; text : STRING);

を使います。続けて宣言してもお互いに影響しません。

オンオフとそれ以外の3状態を表すには、3状態チェックボックス

CreateThreeStateCheckBox(dialogID, componentID : LONGINT; strName : STRING);

を使います。どんな場合に使うかというと、複数のチェックボックスがあり、まとめてチェックするすべてをチェックボックスのように使ったりします。まとめてチェックされるチェックボックスが一つでも状態が違い場合にオンでもオフでもないハイフンのようなチェックになります。

また、ラジオボタンのグループを分けたい場合などは、

CreateGroupBox(dialogID, itemID : LONGINT; text : STRING; hasFrame : BOOLEAN);

を使います。このグループボックスの中に、アイテムを入れるには、

SetFirstGroupItem(dialogID, groupID, firstItemID : LONGINT);

を使います。続くアイテムは、SetBelowItem、SetRightItemなどで入れ子にしていきます。


イベントの処理は、ラジオボタンはそれ自身のオン処理と、同一グループとして関係のあるラジオボタンのオフ処理は自動で行われます。チェックボックスは、それ自体のオンオフは自動で行われます。初期処理として、

SetBooleanItem(dialogID, componentID : LONGINT; setState : BOOLEAN);

を使って、前回の状態にするために、オンにしておくアイテムをTRUEにします。

オンオフの状態を知るには、

GetBooleanItem(dialogID, componentID : LONGINT; VAR outState : BOOLEAN);

を使ってTRUE、FALSEで確認できます。

3状態チェックボックスの処理は、それ自身のオンオフ処理は自動で行いますが、それ以外は自分で描きます。設定は、

SetThreeStateCheckBoxState(dialogID, componentID : LONGINT; iState : INTEGER);

を使います。この例ですと上2つのチェックボックスと連動するようにしていますので、上2つのチェックボックスに変更があったときには、その状態に応じてSetThreeStateCheckBoxStateを使って受胎を変えます。また、3状態チェックボックスに変更があったときには、

GetThreeStateCheckBoxState(dialogID, componentID : LONGINT; VAR iState : INTEGER);

で、自身の状況を取得し、状態に応じて、上2つのチェックボックスの状態を変えるようにします。
・ラジオボタン、チェックボックス、つづき

PROCEDURE Example504;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;
		RadioButton10 : BOOLEAN;
		RadioButton11 : BOOLEAN;
		RadioButton12 : BOOLEAN;
		RadioButton13 : BOOLEAN;
		RadioButton14 : BOOLEAN;
		RadioButton15 : BOOLEAN;
		CheckBox3 : BOOLEAN;
		CheckBox4 : BOOLEAN;
		RadioBoxGroupBox1 : BOOLEAN;
		RadioBoxGroupBox2 : BOOLEAN;
		CheckBoxGroupBox1 : BOOLEAN;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
					SetBooleanItem( dialogID, 130, TRUE );
					SetBooleanItem( dialogID, 170, TRUE );
					SetBooleanItem( dialogID, 190, TRUE );
					SetBooleanItem( dialogID, 500, TRUE );
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
					GetBooleanItem( dialogID, 120, RadioButton10 );
					GetBooleanItem( dialogID, 130, RadioButton11 );
					GetBooleanItem( dialogID, 140, RadioButton12 );
					GetBooleanItem( dialogID, 150, RadioButton13 );
					GetBooleanItem( dialogID, 160, RadioButton14 );
					GetBooleanItem( dialogID, 170, RadioButton15 );
					GetBooleanItem( dialogID, 180, CheckBox3 );
					GetBooleanItem( dialogID, 190, CheckBox4 );
					GetBooleanItem( dialogID, 400, RadioBoxGroupBox1 );
					GetBooleanItem( dialogID, 500, RadioBoxGroupBox2 );
					GetBooleanItem( dialogID, 600, CheckBoxGroupBox1 );
				END;
				kCancel:
				BEGIN
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', 'キャンセル' );

		CreateRadioButtonGroupBox( dialogID, 400, 'ラジオボックスグループボックス1', TRUE );
		SetFirstLayoutItem( dialogID, 400 );

		CreateRadioButton( dialogID, 120, 'ラジオボタン10' );
		SetFirstGroupItem( dialogID, 400, 120 );

		CreateRadioButton( dialogID, 130, 'ラジオボタン11' );
		SetBelowItem( dialogID, 120, 130, 0, 0 );

		CreateRadioButton( dialogID, 140, 'ラジオボタン12' );
		SetBelowItem( dialogID, 130, 140, 0, 0 );

		CreateRadioButtonGroupBox( dialogID, 500, 'ラジオボックスグループボックス2', TRUE );
		SetBelowItem( dialogID, 400, 500, 0, 0 );

		CreateRadioButton( dialogID, 150, 'ラジオボタン13' );
		SetFirstGroupItem( dialogID, 500, 150 );

		CreateRadioButton( dialogID, 160, 'ラジオボタン14' );
		SetBelowItem( dialogID, 150, 160, 0, 0 );

		CreateRadioButton( dialogID, 170, 'ラジオボタン15' );
		SetBelowItem( dialogID, 160, 170, 0, 0 );

		CreateCheckBoxGroupBox( dialogID, 600, 'チェックボックスグループボックス1', TRUE );
		SetBelowItem( dialogID, 500, 600, 0, 0 );

		CreateCheckBox( dialogID, 180, 'チェックボックス3' );
		SetFirstGroupItem( dialogID, 600, 180 );

		CreateCheckBox( dialogID, 190, 'チェックボックス4' );
		SetBelowItem( dialogID, 180, 190, 0, 0 );

		result := RunLayoutDialog( dialogID, DialogHandler );
		IF result = 1 THEN
		BEGIN
		END;
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example504 );

グループボックスの選択系で、ラジオボタン付きグループボックス

CreateRadioButtonGroupBox(dialogID, itemID : LONGINT; name : STRING; hasFrame : BOOLEAN);

チェックボックス付きグループボックス

CreateCheckBoxGroupBox(dialogID, itemID : LONGINT; name : STRING; hasFrame : BOOLEAN);

があります。どちらもグループの内容を丸ごとオンオフすることができます。

イベントの処理は、ラジオボタンやチェックボックスと同じで、ラジオボタングループボックス自身のオン処理と、同一グループとして関係のあるラジオボタングループボックスのオフ処理は自動で行われます。チェックボックスグループボックスは、それ自体のオンオフは自動で行われます。初期処理として、SetBooleanItemを使って、前回の状態にするために、オンにするのも、オンオフの状態を知るのに、GetBooleanItemを使うのも同じです。

・プルダウンメニュー

PROCEDURE Example505;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		VAR
			outSelectedIndex : INTEGER;
			outSelectedChoiceText : STRING;
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
					AddChoice( dialogID, 10, '昇順', 0 );
					AddChoice( dialogID, 10, '降順', 1 );
					AddChoice( dialogID, 20, 'a', 0 );
					AddChoice( dialogID, 20, 'b', 1 );
					AddChoice( dialogID, 20, 'c', 2 );
					AddChoice( dialogID, 100, 'Fundamentals', 0 );
					AddChoice( dialogID, 100, 'Designer', 1 );
					AddChoice( dialogID, 100, 'Architect', 2 );
					AddChoice( dialogID, 100, 'Landmark', 3 );
					AddChoice( dialogID, 100, 'Spotlight', 4 );
					SetItemText( dialogID, 30, 'プロダクトや汎用デザイン向けベーシック製品' );
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
				END;
				kCancel:
				BEGIN
				END;
				10:
				BEGIN
					DeleteAllItems( dialogID, 20 );
					GetSelectedChoiceIndex( dialogID, item, 0, outSelectedIndex );
					IF outSelectedIndex = 0 THEN
					BEGIN
						AddChoice( dialogID, 20, 'a', 0 );
						AddChoice( dialogID, 20, 'b', 1 );
						AddChoice( dialogID, 20, 'c', 2 );
					END
					ELSE
					BEGIN
						AddChoice( dialogID, 20, 'z', 0 );
						AddChoice( dialogID, 20, 'y', 1 );
						AddChoice( dialogID, 20, 'x', 2 );
					END;
				END;
				20:
				BEGIN
					GetSelectedChoiceInfo( dialogID, item, 0, outSelectedIndex, outSelectedChoiceText );
					AlrtDialog( outSelectedChoiceText );
				END;
				100:
				BEGIN
					GetSelectedChoiceIndex( dialogID, 100, 1, outSelectedIndex );
					IF outSelectedIndex = 1 THEN
					BEGIN
						SetItemText( dialogID, 30, '建築、土木、舞台照明。あらゆる分野のデザインワークに対応する最上位製品' );
					END
					ELSE IF outSelectedIndex = 2 THEN
					BEGIN
						SetItemText( dialogID, 30, 'BIMデザインを含む建築設計やディスプレイデザインに適した製品' );
					END
					ELSE IF outSelectedIndex = 3 THEN
					BEGIN
						SetItemText( dialogID, 30, '都市計画や公園、造園計画など、ランドスケープデザインに適した製品' );
					END
					ELSE IF outSelectedIndex = 4 THEN
					BEGIN
						SetItemText( dialogID, 30, 'ステージやライティングなど、エンタテインメントデザインに適した製品' );
					END
					ELSE
					BEGIN
						SetItemText( dialogID, 30, 'プロダクトや汎用デザイン向けベーシック製品' );
					END;
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', 'キャンセル' );

		CreatePullDownMenu( dialogID, 10, 20 );
		SetFirstLayoutItem( dialogID, 10 );

		CreatePullDownMenu( dialogID, 20, 20 );
		SetBelowItem( dialogID, 10, 20, 0, 0 );

		CreatePullDownMenuGroupBox( dialogID, 100, 30, 'Vectorworks:', TRUE );
		SetBelowItem( dialogID, 20, 100, 0, 0 );

		CreateStaticText( dialogID, 30, '建築、土木、舞台照明。あらゆる分野のデザインワークに対応する最上位製品', 30 );
		SetFirstGroupItem( dialogID, 100, 30 );

		result := RunLayoutDialog( dialogID, DialogHandler );
		IF result = 1 THEN
		BEGIN
		END;
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example505 );

プルダウンメニューを利用するには、

CreatePullDownMenu(dialogID, itemID, widthInCharacters : LONGINT);

を使います。宣言時には枠だけ確保され、中身はダイアログを開いたとき(RunLayoutDialog後)に追加します。

グループボックス付きプルダウンメニューを利用するには、

CreatePullDownMenuGroupBox(liDialogID, liComponentID : LONGINT; iPullDownWidth : INTEGER; strLabel : STRING; bHasFrame : BOOLEAN);

を使います。

プルダウンメニューに中身を追加するには、

AddChoice(dialogID, componentID : LONGINT; choiceText : STRING; itemIndex : INTEGER);

を使います。このサンプルでは上のプルダウンメニューがかわるごとに、下のプルダウンメニューが変化するようにしているため、上のプルダウンメニュー(10)にイベントが発生したときに、下のプルダウンメニュー(20)の内容を随時書き換えるようにします。
下のプルダウンメニューの中身をカラにするために、

DeleteAllItems(dialogID, itemID : LONGINT);

を使います。そして上のプルダウンメニューの選択状態を知るためには、

GetSelectedChoiceIndex(dialogID, componentID : LONGINT; startIndex : INTEGER; VAR outSelectedIndex : INTEGER);

を使います。また、選択されている中身を知るには、

GetSelectedChoiceInfo(dialogID, componentID : LONGINT; startIndex : INTEGER; VAR outSelectedIndex : INTEGER; VAR outSelectedChoiceText : STRING);

を使います。

・ポップアップコントロール

PROCEDURE Example506;
VAR
	err : BOOLEAN;

	FUNCTION DialogRoutine : BOOLEAN;
	CONST
		kOk = 1;
		kCancel = 2;
	VAR
		dialogID, result : LONGINT;

		PROCEDURE DialogHandler( VAR item : LONGINT; data : LONGINT );
		VAR
			red, green, blue : LONGINT;
			colorIndex : INTEGER;
			patternIndex, foreColor, backColor : INTEGER;
			lineStyle : INTEGER;
			lineType : LONGINT;
			lineWeight : INTEGER;
			styleInt, angleInt, basis : INTEGER;
			lengthR, widthR, thicknessR : REAL;
			outSelectedIndex : INTEGER;
			outSelectedChoiceText : STRING;
		BEGIN
			CASE item OF
				SetupDialogC:
				BEGIN
				END;
				SetdownDialogC:
				BEGIN
				END;
				kOk:
				BEGIN
				END;
				kCancel:
				BEGIN
				END;
				10:
				BEGIN
					GetColorChoice( dialogID, item , colorIndex );
					ColorIndexToRGB( colorIndex, red, green, blue );
					AlrtDialog( Concat( Num2Str( 0, colorIndex ), ',', Num2Str( 0, red ), ',', Num2Str( 0, green ), ',', Num2Str( 0, blue ) ) );
				END;
				20:
				BEGIN
					GetPatternData( dialogID, item, patternIndex, foreColor, backColor );
					AlrtDialog( Concat( Num2Str( 0, patternIndex ), ',', Num2Str( 0, foreColor ), ',', Num2Str( 0, backColor ) ) );
				END;
				30:
				BEGIN
					GetLineWeightChoice( dialogID, item, lineWeight );
					AlrtDialog( Num2Str( 0, lineWeight ) );
				END;
				40:
				BEGIN
					GetLineStyleChoice( dialogID, item, lineStyle );
					AlrtDialog( Num2Str( 0, lineStyle ) );
				END;
				50:
				BEGIN
					GetLineTypeAttriData( dialogID, item, lineType, lineWeight );
					AlrtDialog( Concat( Num2Str( 0, lineType ), ',', Num2Str( 0, lineWeight ) ) );
				END;
				60:
				BEGIN
					GetMarkerValue( dialogID, item, styleInt, angleInt, lengthR, widthR, basis, thicknessR );
					AlrtDialog( Concat( Num2Str( 0, styleInt ), ',', Num2Str( 0, angleInt ), ',', Num2Str( 0, lengthR ), ',', Num2Str( 0, widthR ), ',', Num2Str( 0, basis ), ',', Num2Str( 0, thicknessR ) ) );
				END;
				70..90:                                                                                        
				BEGIN
					GetSelectedChoiceInfo( dialogID, item, 0, outSelectedIndex, outSelectedChoiceText );
					AlrtDialog( outSelectedChoiceText );
				END;
			END;
		END;

	BEGIN
		dialogID := CreateLayout( 'モダンダイアログ', FALSE, 'OK', 'キャンセル' );

		CreateColorPopup( dialogID, 10, -1 );
		SetFirstLayoutItem( dialogID, 10 );

		CreatePatternPopup( dialogID, 20 );
		SetBelowItem( dialogID, 10, 20, 0, 0 );

		CreateLineWeightPopup( dialogID, 30 );
		SetBelowItem( dialogID, 20, 30, 0, 0 );

		CreateLineStylePopup( dialogID, 40 );
		SetBelowItem( dialogID, 30, 40, 0, 0 );

		CreateLineAttributePopup( dialogID, 50 );
		SetBelowItem( dialogID, 40, 50, 0, 0 );

		CreateMarkerPopup( dialogID, 60 );
		SetBelowItem( dialogID, 50, 60, 0, 0 );

		CreateDesignLayerPullDownMenu( dialogID, 70, 15 );
		SetBelowItem( dialogID, 60, 70, 0, 0 );

		CreateClassPullDownMenu( dialogID, 80, 15 );
		SetBelowItem( dialogID, 70, 80, 0, 0 );

		CreateSheetLayerPullDownMenu( dialogID, 90, 15 );
		SetBelowItem( dialogID, 80, 90, 0, 0 );

		result := RunLayoutDialog( dialogID, DialogHandler );
		IF result = 1 THEN
		BEGIN
		END;
	END;

BEGIN
	err := DialogRoutine;
END;
Run( Example506 );

Vectorworks本体の書類やパレットに付いているポップアップコントロールを自前のダイアログに追加する事ができます。

カラーポップアップを利用する場合には、

CreateColorPopup(dialogID, itemID, widthInCharacters : LONGINT);

を使います。

パターンポップアップを利用する場合には、

CreatePatternPopup(dialogID, itemID : LONGINT);

を使います。

線の太さポップアップを利用する場合には、

CreateLineWeightPopup(dialogID, itemID : LONGINT);

を使います。

線種ポップアップを利用する場合には、

CreateLineStylePopup(dialogID, itemID : LONGINT);

を使います。

線の属性ポップアップを利用する場合には、

CreateLineAttributePopup(dialogID, itemID : LONGINT);

を使います。

マーカーポップアップを利用する場合には、

CreateMarkerPopup(dialogID, componentID : LONGINT);

を使います。

デザインレイヤプルダウンメニューを利用する場合には、

CreateDesignLayerPullDownMenu(nDialogID, nComponentID : LONGINT; nWidthInChars : INTEGER);

を使います。

クラスプルダウンメニューを利用する場合には、

CreateClassPullDownMenu(nDialogID, nComponentID : LONGINT; nWidthInChars : INTEGER);

を使います。

シートレイヤプルダウンメニューを利用する場合には、

CreateSheetLayerPullDownMenu(nDialogID, nComponentID : LONGINT; nWidthInChars : INTEGER);

を使います。


カラーポップアップから情報を取得するには、

GetColorChoice(dialogID, itemID : LONGINT; VAR colorIndex : INTEGER);

を使います。選択されているカラーインデックスから、

ColorIndexToRGB(color : INTEGER; VAR red, green, blue : LONGINT);

を使いRGBの数値を得る事ができます。

パターンポップアップから情報を取得するには、

GetPatternData(dialogID, itemID : LONGINT; VAR patternIndex, foreColor, backColor : INTEGER);

を使います。選択されているパターンのインデックス番号がわかります。

線の太さポップアップから情報を取得するには、

GetLineWeightChoice(dialogID, itemID : LONGINT; VAR lineWeight : INTEGER);

を使います。

線種ポップアップから情報を取得するには、

GetLineTypeChoice(dialogID, itemID : LONGINT; VAR lineType : LONGINT);

を使います。

線の属性ポップアップから情報を取得するには、

GetLineTypeAttriData(dialogID, itemID : LONGINT; VAR lineType : LONGINT; VAR lineWeight : INTEGER);

を使います。

マーカーポップアップから情報を取得するには、

GetMarkerValue(dialogID, itemID : LONGINT; VAR style, angle : INTEGER; VAR length, width : REAL; VAR basis : INTEGER; VAR thickness : REAL);

を使います。

デザインレイヤプルダウンメニュー、クラスプルダウンメニュー、シートレイヤプルダウンメニューから情報を取得するには、

GetSelectedChoiceInfo(dialogID, componentID : LONGINT; startIndex : INTEGER; VAR outSelectedIndex : INTEGER; VAR outSelectedChoiceText : STRING);

を使います。

つづく...