このチュートリアルでは、MAXScript ロールアウト内に、選択したシーン オブジェクトの詳細を表示する ActiveX コントロールを設定する方法を示します。
ActiveX コントロールは、DotNet フレームワークとそのコントロールを考慮して、最新バージョンの Microsoft Windows オペレーティング システムで非推奨となりました。
MAXScript では引き続き ActiveX コントロールがサポートされますが、これらは MAXScript にアクセス可能なシステムにインストールおよび登録する必要があります。
ActiveX コントロールの代わりに、MAXScript では、3ds Max 9 以降において DotNet コントロールがサポートされます。
「ActiveX ListView コントロールの DotNet ListView コントロールへの変換」を参照してください
関連トピック:
MAXScript ロールアウト内の ActiveX コントロール
全体の流れ:
簡単な macroScript を作成します。
フローティング ダイアログ ボックスの作成に使用するロールアウトを定義します。
ロールアウト内の UI コントロールはListView ActiveX コントロールだけです。
ListViewのレイアウトと外観を定義する関数を作成します。
選択したオブジェクトのデータをリストに入れるための関数を別に作成します。
この 2 つの関数は、ダイアログ ボックスが作成されるとき (ロールアウトが開くとき) のイベント ハンドラによって呼び出されます。
スクリプト:
macroScript SceneListView category:"HowTo" ( rollout listview_rollout "ListView Selected" ( fn initListView lv = ( lv.gridLines = true lv.View = #lvwReport lv.fullRowSelect = true layout_def = #("Object Name","Object Class","Verts","Faces","Material") for i in layout_def do ( column = lv.ColumnHeaders.add() column.text = I ) ) fn fillInSpreadSheet lv = ( for o in selection do ( li = lv.ListItems.add() li.text = o.name sub_li = li.ListSubItems.add() sub_li.text = (classof o) as string sub_li = li.ListSubItems.add() sub_li.text =try((o.mesh.numverts) as string)catch("--") sub_li = li.ListSubItems.add() sub_li.text =try((o.mesh.numfaces) as string)catch("--") sub_li = li.ListSubItems.add() sub_li.text = (o.material)as string ) ) activeXControl lv_objects "MSComctlLib.ListViewCtrl" width:490 height:190 align:#center on listview_rollout open do ( initListView lv_objects fillInSpreadSheet lv_objects ) ) createDialog listview_rollout500 200 )
結果:
macroScript SceneListView category:"HowTo" (
まず、SceneListview という名前のシンプルな MacroScript を定義することから始めます。 これは、[HowTo]カテゴリに表示されます。シンプルな (旧式の) macroScripts には on execute do または on isEnabled のイベント ハンドラはありません。MacroScript 定義内のコードは、MacroScript を表す ActionItem (ボタン、メニュー項目、またはキーボード ショートカット) がアクティブになると、すぐに実行されます。
rollout listview_rollout "ListView Selected" (
MacroScript が実行されると作成されるロールアウトです。[ListView Selected]を表示します。listview_rollout という変数は macroScript に対してローカルであり、後でロールアウト定義からダイアログ ボックスを作成するときに使用されます。
fn initListView lv = (
作成する TreeView ActiveX コントロールの初期化を行う関数です。コントロールそのものは、引数として関数に渡されます。
lv.gridLines = true
ListView コントロールにグリッド ラインを表示します。
lv.View = #lvwReport
列見出しも表示するので、ビューのタイプを lvwReport と定義します。
lv.fullRowSelect = true
このプロパティを true に設定することで、行を選択すると列をまたいで行全体が選択されます。
layout_def = #("Object Name","Object Class","Verts","Faces","Material")
このユーザ変数には、作成する列の名前を含む配列が割り当てられます。
for i in layout_def do (
上記で定義された配列のすべての要素について i ループ が実行されます。ループ内では、配列の各要素について新しい列が作成されます。
column = lv.ColumnHeaders.add()
ListView の ColumnHeaders プロパティの add() メソッドを呼び出して、新しい列をリストに追加します。列に対する参照はユーザ変数 column に書き出されて返されるので、列のプロパティにアクセスできます。
column.text =i
たとえば、ループで処理する配列に格納されている文字列を列見出しのテキストに設定することができます。
)
i ループはここまでです。
)
関数はここまでです。
fn fillInSpreadSheet lv =
(
選択したシーン オブジェクトのデータを ListView ActiveX コントロールに入れる関数です。コントロールそのものは、引数として関数に渡されます。
for o in selection do
(
このループは、シーンで現在選択されているすべてのオブジェクトについて繰り返し実行されます。変数 o にはオブジェクトが 1 つずつ入ります。 ループは選択セットにオブジェクトが入っている限り繰り返されます。
li = lv.ListItems.add()
ListView に新しい行を追加します。
li.text = o.name
次に、リストの最初の列に表示されるテキストをオブジェクトの名前に設定します。
sub_li = li.ListSubItems.add()
新しいサブ項目を追加します(これは基本的に次の列です)。現在の listItem(最初の列)の ListSubItems プロパティの .add()
メソッドを呼び出します。結果はユーザ変数 sub_li に書き出されます。
sub_li.text = (classof o) as string
新しい列の .text プロパティを現在のオブジェクトのクラスに設定できます。classof()
の結果が文字列ではないため、.text
プロパティに割り当てる前に明示的に文字列に変換する必要があります。
sub_li = li.ListSubItems.add()
sub_li.text = try((o.mesh.numverts) as string)catch("--")
上記と同様に 3 つ目の列を作成し、新しい列の .text プロパティに現在のオブジェクトのメッシュの頂点の数を割り当てます。頂点の数が整数として返されるため、.text
プロパティに割り当てる前に文字列に変換する必要があります。
選択されたオブジェクトの中には .mesh
プロパティを持たないものもある可能性があります(たとえば、ライト、ヘルパー、カメラ、targetObjects など)。 このような場合、o.mesh.numverts
にアクセスを試みるとエラーが発生します。このため、エラー トラップ try()catch()
を用意します。頂点の数の読み込みに失敗した場合は、サブリスト項目の .text
プロパティに「--」という文字列を割り当てます。
sub_li = li.ListSubItems.add()
sub_li.text = try((o.mesh.numfaces) as string)catch("--")
上記と同様に列をさらに 1 つ作成し、新しい列の .text
プロパティに現在のオブジェクトのメッシュの面の数を割り当てます。面の数が整数として返されるため、.text
プロパティに割り当てる前に文字列に変換する必要があります。
選択されたオブジェクトの中には .mesh プロパティを持たないものもある可能性があります (たとえば、ライト、ヘルパー、カメラ、targetObjects など)。このような場合、o.mesh.numfaces
にアクセスを試みるとエラーが発生します。このため、エラー トラップ try()catch()
を用意します。面の数の読み込みに失敗した場合、サブリスト項目の .text
プロパティに「--」という文字列を割り当てます。
sub_li = li.ListSubItems.add()
sub_li.text = (o.material) as string
最後に、上記と同様に列をもう 1 つ作成し、新しい列の .text
プロパティに現在のオブジェクトのマテリアルを割り当てます。マテリアルを持たないオブジェクトの場合は列に「未定義」と表示します。
)
)
activeXControl lv_objects "MSComctlLib.ListViewCtrl" width:490 height:190 align:#center
上述の関数で処理した ActiveX コントロールです。ロールアウト内の唯一のユーザ インタフェース要素です。ロールアウトの中央に配置されており、ダイアログ ボックスのサイズより少し小さめになっています。
on listview_rollout open do
(
ロールアウトを開いてダイアログ ボックスとして表示するとき、このイベント ハンドラが呼び出されます。
initListView lv_objects
fillInSpreadSheet lv_objects
このイベントは、ListView の初期化と現在選択されたオブジェクトのデータの入力の両方に使用できます。
)
ロールアウトを開くイベント ハンドラはここまでです。
)
ロールアウト定義はここまでです。
try(destroyDialog listview_rollout)catch()
ダイアログ ボックスを作成する前に、ダイアログ ボックスを閉じます。変数 listview_rollout
は MacroScript に対してローカルであるため、MacroScript を複数回呼び出しても必ず同じ変数がアクセスされ、新しいダイアログ ボックスを作成する前にすでに開いているダイアログ ボックスを閉じることができます。
createDialog listview_rollout 500 200
最後に、上で定義したロールアウトを使用してダイアログ ボックスを作成します。
)
スクリプトを評価すると、[ユーザ インタフェースをカスタマイズ](Customize User Interface)ダイアログ ボックス内の[HowTo]カテゴリに新しい ActionItem が表示されます。これをツールバー、メニュー、クアッドメニュー、またはキーボード ショートカットに割り当てると、すばやくアクセスできるようになります。
シーン オブジェクトをいくつか選択してボタンを押すか、メニュー項目を選択するか、キーボード ショートカットを押すと、その名前、クラス、頂点および面の数、割り当てられたマテリアルを示した ListView ActiveX コントロールの新しいダイアログ ボックスが表示されます。
別のオブジェクトを選択してからスクリプトをもう一度呼び出すと、先に表示されていたダイアログ ボックスは閉じられ、新しい選択のデータを示す新しいダイアログ ボックスが表示されます。
このスクリプトはとても基本的なものです。さらに改善し、カスタマイズする方法については、「チュートリアル - ListView ActiveX コントロールを使用した選択オブジェクト検査プログラムの開発 - 第 2 部」を参照してください。