「武器を身につけよう」へ戻る

4.独自の設定ファイルを作る

プラグインならばレジストリーにデータを確保するのでしょうが、
スクリプトで使うので気軽にテキストでファイルに保存してもいいのではないでしょうか。
いざとなったらファイルをメモ帳で開いて変更できるし..
今回はレンダリング設定をファイルに保存するケースを題材にします。
これを少し工夫すればレンダリング設定を変えながら連続レンダリングができたりします。
考え方としてはダイアログでレンダリング設定値入力画面を出し、データを取得して、それをFileに書き込む
という単純なものです。

それではレンダリング設定値を入力するダイアログ作りからはじめましょう。(基本的な設定値だけにします)
ここでは都合上functionにさせていただきます。

Topへ
function ShowInputDialog(Value)
  XShade.BeginDialog(0)
    XShade.AppendSelectionDialogItem"レンダリング手法/レイトレース/分散レイトレース/スキャンライン/"'0
    XShade.AppendSelectionDialogItem"面分割/なし/荒い/普通/細かい/最も細かい/"   '1
    XShade.AppendBoolDialogItem"アンチエリアシング"   '2
    XShade.AppendBoolDialogItem"背景の表示"           '3
    XShade.AppendBoolDialogItem"背景の反映"          '4
    XShade.AppendBoolDialogItem"影を表示"            '5
    XShade.AppendIntDialogItem"画像解像度width"     '6
    XShade.AppendIntDialogItem"画像解像度height"      '7

    XShade.SelectionPropertyValue(0)=0
    XShade.SelectionPropertyValue(1)=2
    XShade.BoolPropertyValue(2)=true
    XShade.BoolPropertyValue(3)=False
    XShade.BoolPropertyValue(4)=False
    XShade.BoolPropertyValue(5)=true
    XShade.IntPropertyValue(6)=600
    XShade.IntPropertyValue(7)=600
    if XShade.AskDialog() then
      Value(0)=XShade.SelectionPropertyValue(0)
      Value(1)=XShade.SelectionPropertyValue(1)
      Value(2)=XShade.BoolPropertyValue(2)
      Value(3)=XShade.BoolPropertyValue(3)
      Value(4)=XShade.BoolPropertyValue(4)
      Value(5)=XShade.BoolPropertyValue(5)
      Value(6)=XShade.IntPropertyValue(6)
      Value(7)=XShade.IntPropertyValue(7)
      ShowInputDialog=true                     'OKが押された場合はtrueを返す。
      XShade.EndDialog()
      exit function
    else
      ShowInputDialog=false                    'キャンセルが押された場合falseを返す。
      XShade.EndDialog()
      exit function 
    end if
end function

このfunctionを呼び出すと右図のようなダイアログが画面に現れるようになります。

そして入力したデータが引数のValueを通して返されます。
戻り値はOKの時true、キャンセルの時falseが返ります。


データを入力する画面はできたのでこのfunctionを呼んでFSOを使いデータを保存する部分を作ります。
FSOでデータを保存する方法は2と基本的に同じなので説明は省きます。

dim Value(7)
dim strPath
dim fso,objStream
dim i

strPath="c:\Setting1.txt"

if ShowInputDialog(Value) then     'ShowInputDialogの戻り値がtrueの時(つまりOKボタンが押された時)
  Set fso=CreateObject("Scripting.FileSystemObject")
  objStream=fso.OpenTextFile(strPath, 2, true)

  for i=0 to 7
    objStream.WriteLine Value(i)
  next
  objStream.close()
  Set fso=nothing
  Set objStream=nothing
else       'ShowInputDialogの戻り値がFalseの時(キャンセルボタンが押されたとき)
  'Do nothing(何もしない)
end if
Topへ

以上です。
以上なんですが、実はこの形だと呼び出した時に常に初期状態になります。
本題とは関係ありませんが、普通は同じファイルを読み込んだときには保存したデータがあればそれをダイアログに表示したいのではないでしょうか
BeginDialogの引数にId番号を付ければ前回の入力分を覚えていてくれますが
どんなファイルを開いても一つまえに入力したデータが表示されてしましますのでちょっと目的は果たせません。
指定したファイルのデータが表示されるようにしてみましょう。

考え方としては、
「最初にファイルの有無を確かめ,ファイルがあったらそのファイルのデータをFSOで取り出して表示し
、ファイルが無かったら初期状態で表示する」
といったようなことです。
ファイルの有無を確かめるのは前出のfunction(FileCheck)を使います。

'---ファイルチェック
function FileCheck(FilePath)
'  引数 ファイルpath(文字列)
'  戻り値 Bool(ない時にfalse)
  dim fso
  set fso=CreateObject("Scripting.FileSystemObject")
  if fso.FileExists(FilePath) then
   FileCheck=true
  else
   FileCheck=false
  end if
  set fso=nothing
end function
【余談】 なぜFileExistsを直接使わずFunctionの中でFSOをわざわざ作って使っていいるのか疑問に思う人もいるのではないでしょうか。
確かにデータを取り出す時にはどちらにしてもFSOを作るのだからその時にFileExistsを使えば効率的ですし処理時間も実際には早くなるからです。
しかしこのように一つの処理をまとめておくと他に流用できるのでそうしてます。たとえば「連続レンダリングスクリプト」では、入力したパスが正しいかどうかを調べるだけの為にこのFunctionを使います。
どちらが本当に良いのか判りませんが私は多少の重複があっても、いろいろなスクリプトを楽に作れて、管理がしやすい方がいいのでこのようにしてます。

このfunctionを呼び出しその結果がtrue(ファイルが有る)ならばデータを取り出します。
逆にfalse(ファイルが無い)ならば初期設定値を設定します。

if FileCheck(strPath) then     '----ファイルがあるとき
  Set fso=CreateObject("Scripting.FileSystemObject")
  objStream=fso.OpenTextFile(strPath,1,false)
  for i=0 to 7
    Value(i)=objStream.ReadLine()
  next
  objStream.close()
  Set fso=nothing
  Set objStream=nothing
else                           '----ファイルがないとき
  Value(0)=0       '手法:レイトレース
  Value(1)=2       '面分割:普通
  Value(2)=true    'アンチエイリアス:ON
  Value(3)=False   '背景の表示:OFF
  Value(4)=False   '背景の反映:OFF
  Value(5)=true    '影を表示:ON
  Value(6)=600     '画像解像度width:600px
  Value(7)=600     '画像解像度height:600px
end if

さらにダイアログの表示functionの初期値代入部分を下記のように改良します。
これは、引数で受け取った配列Valueを初期設定値として代入しています。
もちろんValueは上記のスクリプトで設定した値です。

Topへ
    XShade.SelectionPropertyValue(0)=Value(0)
    XShade.SelectionPropertyValue(1)=Value(1)
    XShade.BoolPropertyValue(2)=Value(2)
    XShade.BoolPropertyValue(3)=Value(3)
    XShade.BoolPropertyValue(4)=Value(4)
    XShade.BoolPropertyValue(5)=Value(5)
    XShade.IntPropertyValue(6)=Value(6)
    XShade.IntPropertyValue(7)=Value(7)

こうすることにより引数で渡されたValue(配列)のデータが表示されるようになります。
以前にデータを指定したファイルに保存していればそのファイルが表示され、それを変更したならファイルの内容が書き換えられるようになります。

保存された"Setting1.txt"をメモ帳で開いたのが右図です。
どのように保存されたか確認してください。

別のファイルに保存するように書き換えて実行し、その後またもとのファイルを保存するようにして実行してみてください。
ひつ前の設定ではなくファイルの設定が表示されていることが確認できるでしょう。

ちょっと内容が前後したので最後にまとめておきます。

option explicit
'===============主スクリプト部分=======================================
dim Value(7)
dim strPath
dim fso,objStream
dim i

strPath="c:\Setting1.txt"

'-----初期設定値の準備の部分
if FileCheck(strPath) then
  Set fso=CreateObject("Scripting.FileSystemObject")
  Set objStream=fso.OpenTextFile(strPath,1,false)
  for i=0 to 7
    Value(i)=objStream.ReadLine()
  next
  objStream.close()
  Set fso=nothing
  Set objStream=nothing
else
  Value(0)=0       '手法:レイトレース
  Value(1)=2       '面分割:普通
  Value(2)=true    'アンチエイリアス:ON
  Value(3)=False   '背景の表示:OFF
  Value(4)=False   '背景の反映:OFF
  Value(5)=true    '影を表示:ON
  Value(6)=600     '画像解像度width:600px
  Value(7)=600     '画像解像度height:600px
end if

'-----ダイアログを表示してユーザーからデータを取得しデータをファイルに格納する部分
if ShowInputDialog(Value) then     'ShowInputDialogの戻り値がtrueの時(つまりOKボタンが押された時)
  Set fso=CreateObject("Scripting.FileSystemObject")
  Set objStream=fso.OpenTextFile(strPath, 2, true)

  for i=0 to 7
    objStream.WriteLine Value(i)
  next
  objStream.close()
  Set fso=nothing
  Set objStream=nothing
else       'ShowInputDialogの戻り値がFalseの時(キャンセルボタンが押されたとき)
  'Do nothing(何もしない)
end if 

'========================使用するfunctionの部分========================
'---ファイルチェック
function FileCheck(FilePath)
'  引数 Fileのpath(文字列)
'  戻り値 Bool(ない時にfalse
  dim fso
  set fso=CreateObject("Scripting.FileSystemObject")
  if fso.FileExists(FilePath) then
   FileCheck=true
  else
   FileCheck=false
  end if
  set fso=nothing
end function

'---レンダリング設定ダイアログの表示
function ShowInputDialog(Value)
  XShade.BeginDialog(0)
    XShade.AppendSelectionDialogItem"レンダリング手法/レイトレース/分散レイトレース/スキャンライン/"'0
    XShade.AppendSelectionDialogItem"面分割/なし/荒い/普通/細かい/最も細かい/"   '1
    XShade.AppendBoolDialogItem"アンチエリアシング"   '2
    XShade.AppendBoolDialogItem"背景の表示"           '3
    XShade.AppendBoolDialogItem"背景の反映"          '4
    XShade.AppendBoolDialogItem"影を表示"            '5
    XShade.AppendIntDialogItem"画像解像度width"     '6
    XShade.AppendIntDialogItem"画像解像度height"      '7

    XShade.SelectionPropertyValue(0)=Value(0)
    XShade.SelectionPropertyValue(1)=Value(1)
    XShade.BoolPropertyValue(2)=Value(2)
    XShade.BoolPropertyValue(3)=Value(3)
    XShade.BoolPropertyValue(4)=Value(4)
    XShade.BoolPropertyValue(5)=Value(5)
    XShade.IntPropertyValue(6)=Value(6)
    XShade.IntPropertyValue(7)=Value(7)
    if XShade.AskDialog() then
      Value(0)=XShade.SelectionPropertyValue(0)
      Value(1)=XShade.SelectionPropertyValue(1)
      Value(2)=XShade.BoolPropertyValue(2)
      Value(3)=XShade.BoolPropertyValue(3)
      Value(4)=XShade.BoolPropertyValue(4)
      Value(5)=XShade.BoolPropertyValue(5)
      Value(6)=XShade.IntPropertyValue(6)
      Value(7)=XShade.IntPropertyValue(7)
      ShowInputDialog=true                     'OKが押された場合はtrueを返す。
      XShade.EndDialog()
      exit function
    else
      ShowInputDialog=false                    'キャンセルが押された場合falseを返す。
      XShade.EndDialog()
      exit function 
    end if
end function

ちょっと余計なことも書いたので長くなってしましました。
実際にレンダリングする部分は本題から外れますので記述しません。
FSOを使ってデータを呼び出し、レンダリング関係のプロパティーを使って設定して、XShade.Renderを使えばファイルのデータによるレンダリング制御ができます。
実際に作った 「連続レンダリングスクリプト」 をこのTipと同じ時期にスクリプト集にUPしてありますのでそちらを参考にして下さい。(かなり大きくなってしまいましたが)
色々な入力ミスチェックも入っていますので参考になると思います。

「武器を身につけよう」へ戻る Topへ