UserFormメソッド/モードレスダイアログ

Short ComposeForm

モードレス・ダイアログを表示します。

戻り値

成功した場合は0以外が返されます。

なお、旧Version1.0ではフォームがすでに表示されている場合は0を返しましたが、 Version2.0ではエラーとなります。

備考

フォームがすでに表示されていてはなりません。

実際にモードレスダイアログを機能させるには、WaitEventメソッドを繰り返し呼び出す必要があります。

モードレスダイアログの場合、チェックボックス、ラジオボタン、リストボックス、コンボボックス、ドロップダウンリストでの選択操作によりイベントが発生するようになります。

DestroyForm

モードレス・ダイアログを終了します。

備考

フォームがすでに表示されている必要があります。

Short WaitEvent(Variant timeout)

モードレス・ダイアログ用イベントループを処理します。

引数

timeoutは10mSec単位の待ち時間を指定します。

省略した場合は待ち時間なしとなります。

指定した時間が経過するか、何らかのコマンド番号が発生すると制御が返されます。

戻り値

何らかのコマンド番号が発生した場合は、待ち時間を待たず、そのコマンド番号を直ちに返します。

チェックボックス、ラジオボタン、リストボックス、ドロップダウンリスト、コンボボックスでの選択操作があった場合にも、 そのコントロール番号のイベントが返されます。

そうでない場合は待ち時間を経過後、NULLを返します。

備考

バックグラウンドで何か処理をしたい場合はtimeout値には小さな値を指定しループ中で処理を行います。

フォームのイベントを待つだけなら大きな値を指定します。

イベントはボタンやウィンドウを閉じる場合はモーダル・ダイアログの場合と同様な戻り値が返ります。

そのほかに、チェックボタンやラジオボタン、リストボックスが操作された場合には、そのコントロール番号が返ります。

イベントがなければNULLが返ります。

SeraphyScriptDialogオブジェクトの基本クラスのDoEventsと同等な機能を果たしますが、 モードレスダイアログのイベントを受け取る場合は、こちらを使ってください。

注意

スクリプトが実行されている同一スレッド上でスクリプト以外によって管理されているウィンドウがある場合、 本メソッドにより、それらのスレッドメッセージもまとめて処理されます。

その結果として、スクリプトの完了を待たずにボタンやメニューなどが操作、実行されうるので、状況により、 擬似的なマルチスレッド的な動作となる場合があり、その副作用には注意してください。

モードレスの例

ソースコード

Option Explicit
Dim obj: Set obj = CreateObject("SeraphyScriptDialog")
Dim frm: Set frm = obj.CreateForm()
frm.FormTitle = "ユーザー情報の入力"

frm.DefineLabel "姓を入れてください"
Dim nEdit1: nEdit1 = frm.DefineEdit()
frm.DefineLabel "名前を入れてください"
Dim nEdit2: nEdit2 = frm.DefineEdit()

Dim btn1: btn1 = frm.DefineButton("了解;キャンセル")

Dim lbl1: lbl1 = frm.DefineLabel("")
frm.Enable(lbl1) = False

dim cnt
frm.ComposeForm()
Do
    cnt = cnt + 1
    frm.Value(lbl1) = FormatDateTime(Now, vbLongTime) & ":cnt=" & cnt

    Dim ret: ret = frm.WaitEvent(100)
    If Not IsNull(ret) Then
        ' コマンド番号あり
        If ret = btn1 Then
            ' 了解ボタン押下か?
            Dim name
            name = frm.Value(nEdit1) & frm.Value(nEdit2)
            If Len(name) > 0 Then
                ' 空でなければメッセージボックスに表示
                obj.MessageBox name, "ユーザ名", 0
                Exit Do
            Else
                obj.MessageBox "ユーザ名を入れてください"
            End If
        Else
            ' ×ボタンで閉じたか、キャンセルボタンか?
            Exit Do
        End If
    End If
Loop
frm.DestroyForm()

実行結果


例: モードレスの例

解説

フォーム上にDefineButtonメソッドにより2個のボタンを定義しています。

明示的にcommandnumberを指定しない場合、最初のボタンのcommandnumberはコントロール番号と同じです。

そのため、「了解」ボタンが押された場合のみ、エディットボックス1,2の内容をメッセージボックスに表示しています。

ESCキー、あるいは×ボタンによりウィンドウを閉じるか、あるいはキャンセルボタンを押下した場合は無視しています。

モードレスではコマンドボタンが押下されなくてWaitEventメソッドの制御が返るため、ウィンドウを閉じるべきと判断できるまでループで繰り返し呼び出す必要があります。

ループしていることが視覚的にわかるようにフォームの下に現在時刻とループ回数を示すラベルを設置しています。

ボタンのイベントを判定する時点では、まだフォームは閉じられていないため、フォームを表示したまま、テキストボックスの中身を検証してエラーを表示する、などの動作ができます。

2つのモードレスの例

ソースコード

Option Explicit
Dim obj: Set obj = CreateObject("SeraphyScriptDialog")

Dim frm1: Set frm1 = obj.CreateForm()
frm1.FormTitle = "フォーム1"
Dim lbl1: lbl1 = frm1.DefineLabel("")
Dim btn1: btn1 = frm1.DefineButton("了解1;終了")
frm1.FormPos = "200,200"

Dim frm2: Set frm2 = obj.CreateForm()
frm2.FormTitle = "フォーム2"
Dim lbl2: lbl2 = frm2.DefineLabel("")
Dim btn2: btn2 = frm2.DefineButton("了解2")
frm2.FormPos = "200,300"

dim cnt

frm1.ComposeForm()
frm2.ComposeForm()

Do
    cnt = cnt + 1
    frm1.Value(lbl1) = "cnt=" & cnt
    frm2.Value(lbl2) = "cnt=" & cnt

    ' コマンドが発生していれば受け取る
    Dim ret1: ret1 = frm1.WaitEvent()
    If Not IsNull(ret1) Then
        If ret1 = btn1 + 1 Or ret1 = -1 Then
            ' 終了ボタンもしくは×ボタンの場合
            Exit Do
        Else
	        MsgBox "frm1=" & ret1
        End If
    End If

    ' コマンドが発生していれば受け取る
    Dim ret2: ret2 = frm2.WaitEvent()
    If Not IsNull(ret2) Then
        MsgBox "frm2=" & ret2
    End If

    ' 二つのフォームのメッセージを一括処理する
    obj.DoEvents 100
Loop

frm1.DestroyForm()
frm2.DestroyForm()

実行結果


例: 2つのモードレスの例

解説

同時に2つ以上のモードレスを操作する場合、それぞれのイベントはフォームに対するWaitEventメソッドで取得できます。

ただし待ち時間を指定するとレスポンスが悪くなるため、WaitEventの待機時間はゼロにします。

かわりに、DoEventsメソッドを使いメッセージ処理を一括で行わせます。

ウィンドウが表示されているかぎりメッセージ処理は随時必要とされるため、通常、 DoEventに指定した待機時間よりも早く待機解除されますが、待機を指定しないよりは無駄な処理は少なくなります。