SeraphyScriptToolsの使い方2 応用編


[VBS Ver5を利用した、もっとも簡単なウィンドウ生成方法]

 イベントのハンドルと、オブジェクトの管理に、VBScriptのクラスを使うと簡単です。
 まず、スクリプトは、独自に作成したクラス「MainFrame」を生成させます。
 これだけで、スクリプトの実行は終わります。

dim obj
set obj = new MainFrame

 このコードを実行するには、「MainFrame」というクラスの定義が必要です。
 クラスは、つぎのように定義します。

class mainframe
  public instance

  public sub class_initialize
    set instance = createobject("seraphyscripttools.instance")
    with instance.mainframe
      .classobject = me
      .domodal
    end with
  end sub
end class

 このクラスはウィンドウを生成するだけです。
 これがウィンドウを生成する最低の構造となります。

 クラスの中身をみてゆきましょう。

 public instance

 という行があります。
 これはクラスがもつ、オブジェクト変数です。
 ここに、SeraphyScriptToolsオブジェクトを生成し保存します。

 public sub class_initialize
 …
 end sub

 というサブプロシージャがあります。
 このサププロシージャはクラスが生成されると、自動的に呼び出されます。
 つまり、冒頭で「set obj = new MainFrame」という行によって、このクラスが生成されると同時に呼び出されます。

 このルーチンの中で、CreateObject関数によって、SeraphyScriptToolsが生成され、クラスのメンバ「instance」に保存されています。

 つづいて、SeraphyScriptToolsが最初に生成したMainFrameオブジェクトにアクセスします。

 .ClassObject = me

 というのがポイントです。
 この「me」はクラス自身を示すオブジェクトです。
 MainFrameは、ClassObjectにスクリプトのクラスを渡すことで、さまざまなイベントに応じて、クラスの公開プロシージャを呼び出すことが可能になります。

 ただし、VB、VBAでは「me」は正式なドキュメントに掲載されていますが、VBScriptでは、なぜか「me」はドキュメントに載ってません!
 しかし、動作しますし、JScriptには同様な機能がありますから、VBScriptに「me」が載ってないのはマニュアルの不備かもしれません。
 もちろん、VB/VBAで使えて、VBSに使えない機能、の制限の中には、これは含まれていません。
 まあ、使えるので気にしないことにします。
 気になる方は、クラスではなく、基礎編で説明した「オブジェクトの接続」による方法を利用してください。

 つぎに、DoModalメソッドを呼び出します。
 これにより、ウィンドウの表示を表示させます。
 DoModalを呼び出した場合、ユーザーがウィンドウを閉じるまで戻ってきません。

 ユーザーがウィンドウを閉じるとDoModalの次のステップに進みます。
 Set obj = new MainFrame
 の次の行に進むわけですが、もう何もありません。
 クラスは自動的に破棄され、そのときに、クラス・メンバである「Instance」も破棄されます。
 SeraphyScriptToolsが破棄されて、スクリプトは終了します。

 

[フォームの定義と、その応答について]

 さて、何も無いウィンドウを表示しても面白くないので、ウィンドウの中に文字入力ボックスとボタンを作ります。
 そのボタンに反応するようにしてみます。

 まず、文字入力ボックスとボタンをコントロールできるように、2つのオブジェクトを作ります。
 poublic instanceの次の行に、あらたに2つのオブジェクト変数を定義します。

public instance
public edt,cmd

 つぎに、public sub class_initialize サブプローシジャで、DoModalの前にフォームを作成とウィンドウを作成させます。

with .form
  .label "ラベル"
  set edt = .edit("エデイットボックス")
  set cmd = .button("表示").SetClassEvent("CMD_SHOW")
end with
.open "テスト
"
DoModal

 これを実行すれば、「テスト」というウィンドウの中に、ラベルという表示と、文字入力ボックスとボタンが作られています。

 ただし、まだ、なにも動作しません。

 クラスに、CMD_SHOWという公開サブプローシジャを作成します。

public sub CMD_SHOW
  instance.dialog.messagebox edt.text
end sub

 ボタンが押されると「CMD_SHOW」プロシージャが呼び出されます。
 どうして、「CMD_SHOW」という名前のプローシジャが呼び出されるかといえば、「.SetClassEvent」というメソッドで指定しているからです。
 このメソッドは、クラスの、どのプロシージャを呼び出すか決定付けるものです。

 instance.dialog.messageboxは、Instanceオブジェクトが管理しているダイアログボックス・オブジェクトのメッセージボックスを表示するものです。
 edt.textは、文字入力ボックスオブジェクトから、現在入力されている文字を取得します。

 msgbox edt.text でもよいように思われるかもしれません。
 msgboxはVBScriptの標準のメッセージボックスです。
 しかし、ウィンドウの親子関係がないので、表示されているウィンドウとメッセージボックスとが独立して見えます。
 不自然な動きであったり、場合によっては、ウィンドウに隠れてしまう可能性があります。
 親子関係がある、Instance.Dialogオブジェクトを使うことがよいでしょう。

 

[OK/CANCEL動作の定義方法]

 ところで、現在のウィンドウは、リターンキーまたはエスケープキーで終了してしまいます。

 実は、ボタンを押さなくても、この2つは自動的にコマンドイベントが発生しています。

 public sub OnOKと、public sub OnCancelを作成してみてください。

public sub OnOK
  instance.dialog.messagebox "OK"
end sub

public sub OnCancel
  instance.dialog.messagebox "CANCEL"
end sub

 リターンキーまたはエスケープキーに反応して、サブプローシジャが実行されたあと、ウィンドウが閉じると思います。

 ただし、DefaultActionプロパティーがFALSEの場合は、イベントが発生しますが自動的には閉じません。
 また、OnOK、OnCacelプロシージャ内で、QuitプロパティをFALSEにした場合も閉じられません。

 たとえば、

public sub OnOK
  if(instance.dialog.messagebox("閉じてもよいですか?",1) = -1) then
    instance.mainframe.quit = false
  end if
end sub

 このようにすれば、状況におうじて閉じたり、閉じなかったりすることができます。
 QuitプロパティーをTRUEにすれば自動的に閉じられますが、Closeメソッドで閉じてもかまいません。

 

[OK/CANCELのディフォルトのボタンの定義]

 キーボードによるOK.CANCELの定義方法だけでは不十分です。
 通常は、フォームにもOK/CANCELボタンをつけるのが普通です。

 その場合、SetEventNameメソッドで「OnOK」「OnCancel」を指定しても動作します。
 しかし、ボタンの外見がわかりません。

 ボタンを定義するときに、SetEventNameのかわりに、SetIDメソッドを使ってください、
 SetIDメソッドで「1」が指定されたボタンは、自動的に標準のボタンという扱いになる特殊コードになっています。

 Cancelボタンは、「2」を指定してください。外見はかわりませんが、動作はOnCacelと同じになります。

 サンプルを参考にしてみてください。

 

[このほかのイベントのハンドル方法]

 マウスのダウン・アップ、移動をはじめ、メニューの選択など、いろいろなイベントが発生します。
 これらは、同様に、クラスに公開プロシージャを設定することで処理することができるようになります。

 サンプルを参考にしてみてください。

 

[サブ・ウィンドウの生成について]

 サブウィンドウも同様な方法で開くことができます。

 ただし、注意してほしいのは、「メッセージループ」を処理しているウィンドウ以外の操作ができないことです。
 ダイアログの中で、さらに別のダイアログを開く場合は、親になるウィンドウを「Enable = FALSE」で使用禁止にしてください。
 そうしないと不自然になります。

 同時に複数のウィンドウを利用可能にする場合は、Instanceオブジェクトからメッセージループを処理してください。
 このオブジェクトからメッセージループを処理すると、生成されている、すべてのウィンドウのメッセージループを適切に処理することができます。

 サンプルを参考にしてみてください。