イベントのハンドルと、オブジェクトの管理に、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オブジェクトを使うことがよいでしょう。
ところで、現在のウィンドウは、リターンキーまたはエスケープキーで終了してしまいます。
実は、ボタンを押さなくても、この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ボタンをつけるのが普通です。
その場合、SetEventNameメソッドで「OnOK」「OnCancel」を指定しても動作します。
しかし、ボタンの外見がわかりません。
ボタンを定義するときに、SetEventNameのかわりに、SetIDメソッドを使ってください、
SetIDメソッドで「1」が指定されたボタンは、自動的に標準のボタンという扱いになる特殊コードになっています。
Cancelボタンは、「2」を指定してください。外見はかわりませんが、動作はOnCacelと同じになります。
サンプルを参考にしてみてください。
マウスのダウン・アップ、移動をはじめ、メニューの選択など、いろいろなイベントが発生します。
これらは、同様に、クラスに公開プロシージャを設定することで処理することができるようになります。
サンプルを参考にしてみてください。
サブウィンドウも同様な方法で開くことができます。
ただし、注意してほしいのは、「メッセージループ」を処理しているウィンドウ以外の操作ができないことです。
ダイアログの中で、さらに別のダイアログを開く場合は、親になるウィンドウを「Enable
= FALSE」で使用禁止にしてください。
そうしないと不自然になります。
同時に複数のウィンドウを利用可能にする場合は、Instanceオブジェクトからメッセージループを処理してください。
このオブジェクトからメッセージループを処理すると、生成されている、すべてのウィンドウのメッセージループを適切に処理することができます。
サンプルを参考にしてみてください。