温まって来たところで、dotNET+MAXscriptで実際にいろいろ作っていきたいと思います。
まずは、dotNETを使ったUIの基本。フォームの生成です。
こんな感じですね。
(
--メインフォーム設定--------------------------------------------------------------
MainFrm = dotNetObject "System.Windows.Forms.Form"
--フォームのタイトル-----------------------
MainFrm.text = "testform"
--フォームサイズ--
MainFrm.bounds = dotNetObject "system.drawing.rectangle" 50 50 200 200
--フォームを表示--
MainFrm.Show()
)
この4行でフォームが生成されます。
まず1行目。
mainFrmが生成されるフォームになるので、ここはなんの名前でもOKです。
「=」以降、ここで作るものがdotnetobjectである、というのを決めます。
たいてい、dotnetobject "なんちゃら~"でブツを作ってくれます。
2行目以降
ブツを作っただけで、中身(プロパティと言います)が空、もしくはデフォルト値なので、プロパティを決めていきます。
.text これはフォームのタイトルバー部分に表示される名前です。
.bounds これはmainFrmが表示されるx.y座標と、ウィンドウサイズの指定です。
ここで注意しないといけないのが、.boundsは直接値を入れてもいうことを聞いてくれないということです。
ブツを作った上で、その中に値を入れてあげないといけません。
dotNetObject "system.drawing.rectangle"でブツを作ってあげます。
""内は、どんなタイプのブツを作るか、という宣言なのですが、これはプロパティごとに決まってますので、随時調べて行きましょう。
プロパティによっては、.textのように値を直接入れてもOKなものも有りますが、どれがOKでどれがダメなものかまでは理解出来てませんので、
値を直接入れてダメなら、ブツが必要なんだなーくらいの認識でやっております。
値は、左から表示されるx座標、表示されるy座標、ウィンドウサイズ横、ウィンドウサイズ縦、となっています。
最後に、.show()で生成されます。
さて、次はこのフォームに画像を表示してみましょう。
画像の表示にはフォームのバックグラウンドに表示させる方法と、PictureBoxというdotNETオブジェクトを利用して表示させる方法とが有りますが、
ここは後から手を加えやすいようにPictureBoxを利用します。
(
--画像読み込み&変数定義--
mainimgfiles = "C:\\Users\\Public\\Pictures\\Sample Pictures\\sample.jpg" --表示したい画像を変数に格納--
mainimgClass = dotNetClass "System.Drawing.Image" --クラスの定義--
mainimg =(mainimgClass.FromFile mainimgfiles) --mainimgはmainimgクラスのファイル読み込みタイプでファイルのパスはmainimgfiles--
mainimgWidth = mainimg.Size.Width as integer --mainimgのサイズ(幅)を参照して、intに変換--
mainimgHeight = mainimg.Size.Height as integer --mainimgのサイズ(高さ)を参照してint型に変換--
--dotNetオブジェクトを生成--
imgview = dotNetObject "System.Windows.Forms.PictureBox" --imgviewはdotnetobjectでpictureboxを使います--
imgview.bounds = dotNetObject "system.drawing.rectangle" 0 0 mainimgWidth mainimgHeight --画像の表示位置はフォームの(0,0)の位置--
imgview.Image = mainimg --imgviewのイメージプロパティはmainimgです--
imgview.backColor = (dotNetClass "system.drawing.color").Transparent --imgviewの背景色はカラーのクラスで、透過です。--
--メインフォーム設定--------------------------------------------------------------
MainFrm = dotNetObject "System.Windows.Forms.Form"
--フォームのタイトル-----------------------
MainFrm.text = "testform"
--フォームサイズ--
MainFrm.bounds = dotNetObject "system.drawing.rectangle" 50 50 200 200
--pitureboxをフォームに追加--
MainFrm.Controls.Add imgview --mainformにimgviewを追加します。--
--フォームを表示--
MainFrm.Show()
)
初めて出てきました「dotnetClass」
これはdotNetobjectと同じく、dotNet関連の物ですよ~という宣言なのですが、
正直なところなところ正確な違いは理解出来てません。
ブツは生成せずに、型を決めてくれる・・・程度の認識です。
興味のある方はMAXのヘルプ読んでみてください。
なんとなーくやってることはわかるんじゃないでしょうか。
ドット以降はすべてdotNETobjectもしくはdotNetclassのプロパティです。
幾つか注意点として上げるならば、
7行目のimgview.boundsですが、mainFrm内に表示するので、表示位置はフォームの(0,0)となります。
ここの値を変えることで、mainFrmの右下や左下なんかに表示させることが出来ます。
また、ingview.backcolorですが、これは背景色を変えることが出来ます。
今は透過していますが、違う色に変えたい場合は”picturebox .backcolor”あたりで検索するとヒットするので
調べてみてください。
わかる範囲で質問には答えようと思ってますので、twitterでもこちらのコメントでもどうぞ。
2015年7月13日月曜日
2015年6月13日土曜日
fileinのナゾ
MAXscriptには、「filein」という別のmsファイルをスクリプト内に読んでくる物があります。
例えば、
main.ms
(
aaa = undefined
filein "C:\\Program Files\\Autodesk\\3ds Max 2015\\scripts\\testA.ms"
print aaa
)
testA.ms
(
aaa = "fileinのナゾ。"
)
こういった2つのscriptがあるとします。
testA.msをmain.msで記述されているパスに置いて、main.msをMAXscriptエディタ実行すると、testAは実行せずとも、main.msはtestA.msの内容を読んで、変数aaaは”fileinのナゾ。”というstring値に置き換えられます。
しかし、main.msを
macroScript testmain category:"test" internalCategory:"test" toolTip:"testmain" buttonText:"testmain"
(
aaa = undefined
filein "C:\\Program Files\\Autodesk\\3ds Max 2015\\scripts\\testA.ms"
print aaa
)
と書き換えてツールバーに登録して実行すると、変数aaaはundefinedのまま、置き換わってくれません。
なんでや。
・・・しばらくナゾだったんですが、
こちらの記事で多分こういうことだろうと納得しました。
http://0303.blogspot.jp/2012/12/blog-post_5.html
はじめに、macroscript宣言をして、エディタからCtrl+Eで実行すると、usermacrosフォルダに登録されます。
なので、上記記事の5のところで、main.msは評価されているということになります。
しかしながら、fileinについては、ここでコンパイルされなんじゃないかと予想。
次に、上記6のスタートアップスクリプトにmain.msを入れてMAXを再起動。
結果としてはこちらもダメでした。
どうやらMAXのGUI構築前に、fileinは実行しとかないとダメなようですね・・・。
というわけで、stdscriptsにmain.msを入れて、testA.msを読むことが出来ました。
実際にツールを作るときには、ツール本体、filein宣言のみのmsファイル(stdscriptsにいれる)読み込む対象のmsファイル(場所はどこでもいい)
と、3つのmsファイルに分けて運用することになるかと思います。
これで、ツール本体をコンパイルしなおさなくても、対象ファイルを書き換えるだけでツールの内容を更新出来ますね。
問題があるとすれば、stdscritsで読んだ変数はグローバル変数になるというところです。
上記例でいうと、変数aaaがグローバル変数に・・・。
でも実際には読み込む対象は構造体などだと思うので、ほとんど問題無いんじゃないでしょうか。
例えば、
main.ms
(
aaa = undefined
filein "C:\\Program Files\\Autodesk\\3ds Max 2015\\scripts\\testA.ms"
print aaa
)
testA.ms
(
aaa = "fileinのナゾ。"
)
こういった2つのscriptがあるとします。
testA.msをmain.msで記述されているパスに置いて、main.msをMAXscriptエディタ実行すると、testAは実行せずとも、main.msはtestA.msの内容を読んで、変数aaaは”fileinのナゾ。”というstring値に置き換えられます。
しかし、main.msを
macroScript testmain category:"test" internalCategory:"test" toolTip:"testmain" buttonText:"testmain"
(
aaa = undefined
filein "C:\\Program Files\\Autodesk\\3ds Max 2015\\scripts\\testA.ms"
print aaa
)
と書き換えてツールバーに登録して実行すると、変数aaaはundefinedのまま、置き換わってくれません。
なんでや。
・・・しばらくナゾだったんですが、
こちらの記事で多分こういうことだろうと納得しました。
http://0303.blogspot.jp/2012/12/blog-post_5.html
はじめに、macroscript宣言をして、エディタからCtrl+Eで実行すると、usermacrosフォルダに登録されます。
なので、上記記事の5のところで、main.msは評価されているということになります。
しかしながら、fileinについては、ここでコンパイルされなんじゃないかと予想。
次に、上記6のスタートアップスクリプトにmain.msを入れてMAXを再起動。
結果としてはこちらもダメでした。
どうやらMAXのGUI構築前に、fileinは実行しとかないとダメなようですね・・・。
というわけで、stdscriptsにmain.msを入れて、testA.msを読むことが出来ました。
実際にツールを作るときには、ツール本体、filein宣言のみのmsファイル(stdscriptsにいれる)読み込む対象のmsファイル(場所はどこでもいい)
と、3つのmsファイルに分けて運用することになるかと思います。
これで、ツール本体をコンパイルしなおさなくても、対象ファイルを書き換えるだけでツールの内容を更新出来ますね。
問題があるとすれば、stdscritsで読んだ変数はグローバル変数になるというところです。
上記例でいうと、変数aaaがグローバル変数に・・・。
でも実際には読み込む対象は構造体などだと思うので、ほとんど問題無いんじゃないでしょうか。
2015年5月30日土曜日
dotNetObject "MaxCustomControls.Win32HandleWrapper"
maxHandlePointer = (Windows.GetMAXHWND())maxHwnd = dotNetObject "MaxCustomControls.Win32HandleWrapper" syspointer
このdotNetオブジェクト、MAXscriptのヘルプやチュートリアルを眺めてると
フォーム生成の最後あたりでよく見かけます。
最初はなんぞやーと思ってたのですが、どうやら、
「MAXを最小化した時に一緒にフォームも最小化される」だとかのコントロールをMAX側に委ねるdotNetオブジェクトのようです。
さて、ここでヘルプ通りにdotNetオブジェクトを設定すると、
MAX2013 まではエラーなく動いてくれるのですが、2014、2015だとエラーが出てしまいます。
ヘルプ通りなのに!(※2016は未検証)
これはどういうことかというと、
2014、2015では、 「Windows.GetMAXHWND()」から"MaxCustomControls.Win32HandleWrapper"
が削除されてしまったにもかかわらず、ヘルプは昔のまま・・・・
というのが原因らしいです。
というわけで代替コード。
sysPointer = DotNetObject "System.IntPtr" maxHandlePointer
mainwin = dotNetObject "System.Windows.Forms.Control"
mainwin.fromHandle sysPointer
--フォームを生成--
maxForm = dotNetObject "MaxCustomControls.MaxForm"
maxForm.Show(mainwin)
代替コードは何通りかあると思いますが、AREAで紹介されていたコードを紹介しました。
MAXscrpitでdotNetを扱おうとすると、経験上、標準ヘルプはほとんど役に立ってません。
元ネタ:http://forums.autodesk.com/t5/programming/is-win32handlewrapper-not-in-maxcustomcontrols-anymore/td-p/5115984
2015年5月28日木曜日
blogger始めました。
サイト閉じちゃったんでblogだけ初めました。
MAXscriptあたりの話題を書いていく予定。
MAXscriptとdotNetで苦戦した経験はきっと他の人の役にたつと信じて。
MAXscriptあたりの話題を書いていく予定。
MAXscriptとdotNetで苦戦した経験はきっと他の人の役にたつと信じて。
登録:
コメント (Atom)