2011年11月23日 星期三

[dotnet]webbrowser 做為 UI log 的眉眉角角

一開始的動作

'WebBrowser1 一開始,可以設定 DocumentText 來顯示第一個畫面。
若是想用,WebBrowser1.Document.Write,
因為一開始,WebBrowser1.Document 是 nothing,所以此路不通。
網路上也滿多人提出,先 WebBrowser1.Navigate("about:blank"),
然後用迴圈加上 Application.DoEvents() 等待 'WebBrowser1.Document 長好,
再用 WebBrowser1.Document.Write。

最後我的決定是,準備好一個檔案直讀進來就好。
因為程式是 multithread,保險起見,還是用 while 等 Document 長好。
但我不確定是否真有用,因為一定要用 Application.DoEvents() 讓 WebBrowser 去做事,
當然這時有其他事情發生也沒辦法阻止。

    Sub initUILogComponet()
        WebBrowser1.Navigate("UI.html")
        WebBrowser1.IsWebBrowserContextMenuEnabled = False
        While (True)
            Application.DoEvents()
            If Not WebBrowser1.Document.Body Is Nothing Then
                Exit While
            End If
        End While
    End Sub

更新畫面

要更新 UI 畫面,基本要做的就是檢查 thread 是否回到 form。
這裡用 Document 物件新增新的 tr。
等待之後,取出 Document 的 html 元素的 OuterHtml 再寫進檔案。
接著Navigate。
清除舊資料的方式就是把最舊的那一個元素的 OuterHtml 取出,
把它從 html 元素的 OuterHtml 裡消掉,
再寫進檔案後Navigate。

    Sub UpdateUILog(ByVal inType As EQS_ScreenType, ByVal intxt As String)
        If Me.InvokeRequired Then
            Me.Invoke(New LogDele(AddressOf UpdateUILog), New Object() {inType, intxt})
        Else
            Try
                Dim tr As HtmlElement
                Dim td As HtmlElement
                tr = WebBrowser1.Document.CreateElement("tr")
                td = WebBrowser1.Document.CreateElement("td")
                td.InnerText = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
                tr.AppendChild(td)
                td = WebBrowser1.Document.CreateElement("td")
                td.InnerText = intxt
                tr.AppendChild(td)
                Select Case inType
                    Case ERROR
                        tr.SetAttribute("class", "error")
                    Case M_INFO
                        tr.SetAttribute("class", "info")
                    Case M_MES
                End Select
                WebBrowser1.Document.Body.FirstChild.FirstChild.FirstChild.InsertAdjacentElement(HtmlElementInsertionOrientation.AfterEnd, tr)
                While (True)
                    Application.DoEvents()
                    If Not WebBrowser1.Document.Body Is Nothing Then
                        Exit While
                    End If
                End While
                Dim n_html = "<!doctype html>" & WebBrowser1.Document.GetElementsByTagName("html").Item(0).OuterHtml
                Dim n_sw As System.IO.StreamWriter = System.IO.File.CreateText("UI.html")
                n_sw.Write(n_html)
                n_sw.Close()
                WebBrowser1.Navigate("UI.html")
                Dim v As Integer
                v = 5
                If WebBrowser1.Document.Body.FirstChild.FirstChild.Children.Count > v Then
                    Dim t As String = WebBrowser1.Document.Body.FirstChild.FirstChild.Children(v).OuterHtml
                    Dim new_html As String = WebBrowser1.Document.GetElementsByTagName("html").Item(0).OuterHtml
                    t = t.Replace(vbNewLine, "")
                    new_html = new_html.Replace(vbNewLine, "")
                    new_html = new_html.Replace(t, "")
                    new_html = "<!doctype html>" & new_html

                    Dim sw As System.IO.StreamWriter = System.IO.File.CreateText("UI.html")
                    sw.Write(new_html)
                    sw.Close()
                    WebBrowser1.Navigate("UI.html")
                End If
            Catch ex As Exception

            End Try
        End If
    End Sub

 

保證一定得到更新後內容的方式

在 DocumentCompleted 事件去拿一定可以。
要注意的是,當初設定 DocumentText 的話,更新的內容會在 DocumentText。
而使用 Document 物件操作的,更新的內容要從 Document 物件拿。

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
        If firstContextSetComplete = False Then
            firstContextSetComplete = True
            'UpdateUILog(FACETEA.EQS_ScreenType.M_INFO, "StartUp")
        End If
        Dim control As Control = Me.ActiveControl
        WebBrowser1.Focus()
        control.Focus()
    End Sub

用jQuery清除舊資料

因為 WebBrowser 控制項沒辦法支援 addEventHandler,所以我的腦筋動到 setInterval。
這個方法可行,但是無法存檔。
而且考量到使用 class 控制外觀非得存檔再Navigate,在兩個因素考量下,
所以清舊資料的事只能交給主程式本身來做。

沒有留言:

張貼留言