2010年5月16日日曜日

WebBrowser : .Document.Write()は使わない方がよい

WebBrowserコントロールにテキストを設定する手段として、.DocumenetTextにHTMLテキストを設定する手法が一般的である。

しかし、この方法ではHTMLテキストを設定した直後から DocumentComplete()イベントが発生するまで .DocumentTextは以前の設定された内容になっている

また、DocumentComplete()を待たずに、DocumentTextに連続してHTMLテキストを設定すると、2回目以降に設定したテキストが無視される。


さて、設定した内容を即時反映するにはどうすればよいか?
都合の良いことに Write() というメソッドが存在する。

.Document.OpenNew(False)
.Document.Write( HTMLテキスト )

上記の様にテキストを設定すると、DocumentCompleteイベントが発生しないが、DocumentTextにはWrite()で設定した文字列が設定されている。

喜んで Write() を使うと大変な目に遭う。

  1. HTMLテキスト中にある JavaScriptが実行されない
  2. WebBrowserコントロールが張り付いたFormがフォーカスを奪う


やっぱり DocumentTextプロパティを使うしかないそうだ。

DocumentTextにHTMLテキストを設定してその直後に DocumentCompleteを待つコードを次に示す

<定義部>    
    Friend Enum POSTMESSAGE_FLAGS
        PM_NOREMOVE = 0
        PM_REMOVE = 1
    End Enum
  

    Private Shared Function PeekMessage(ByRef m As System.Windows.Forms.Message, _
                                ByVal hWnd As IntPtr, _
                                ByVal FilterMin As Integer, _
                                ByVal FilterMax As Integer, _
                                ByVal RemoveMsg As POSTMESSAGE_FLAGS) As Integer
    End Function


    Private Shared Function DispatchMessage(ByRef m As System.Windows.Forms.Message) As Integer
    End Function

<コード部>

    '
    ' WebBrowserコントロールにテキストを設定する
    '

    Private Sub SetWebbrowserDocumentText(ByVal ctlWeb As WebBrowser, ByVal strValue As String)
        mblnWebWaitForComplete = True

        ctlWeb.DocumentText = strValue

        '完了待ち
        With ctlWeb
            Do Until (.ReadyState = WebBrowserReadyState.Complete AndAlso mblnWebWaitForComplete = False)
                Dim _m As System.Windows.Forms.Message
                '                                                   メッセージループ
                Dim _get As Integer = PeekMessage(_m, IntPtr.Zero, &H400, &HFFFF, POSTMESSAGE_FLAGS.PM_REMOVE Or &HF0000) '入力イベント以外
                Do Until (_get = 0)
                    DispatchMessage(_m)
                    _get = PeekMessage(_m, IntPtr.Zero, &H400, &HFFFF, POSTMESSAGE_FLAGS.PM_REMOVE Or &HF0000) '入力イベント以外
                Loop
            Loop
        End With
    End Sub

    Private mblnWebWaitForComplete As Boolean = False                               '完了待ちフラグ

    '
    'Webプラウザの完了
    '

    Private Sub webKarteEdit_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles webKarteEdit.DocumentCompleted

        mblnWebWaitForComplete = False

        '以下コード

    End Sub

0 件のコメント:

コメントを投稿