2013-10-04 222 views
1

當我嘗試通過它們多次打印時,COM瀏覽器出現問題。
用於複製一個問題:從網絡瀏覽器打印兩次

1)創建一個新的 「Windows窗體」 項目
2)COM引用添加到 「Microsoft Internet控制」
3)添加WebBrowser控件 「webbrowser1」 和按鈕 「Button1的」 到表格(工具箱)
4)請確保您有文件 「C:\ index.html在」
5)添加此代碼...

Option Explicit On 

Imports System.IO 
Imports System.Reflection 
Imports System.Diagnostics.Process 
Imports System.Runtime.InteropServices 
Imports SHDocVw 

Public Class Form1 
Dim WithEvents p As New PrintHTML 
Dim htmlfilename As String 

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 
    p = Nothing 
End Sub 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    htmlfilename = "c:\index.html" 
    WebBrowser1.Navigate(htmlfilename) 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    p.PrintHTMLDocument(htmlfilename) 
End Sub 
End Class 

Public Class PrintHTML 

Dim documentLoaded As Boolean = False 
Dim documentPrinted As Boolean = False 

Public Sub PrintHTMLDocument(ByVal htmlfilename As String) 

    Dim ie As New InternetExplorer 
    AddHandler DirectCast(ie, InternetExplorer).PrintTemplateTeardown, AddressOf PrintedCB 
    AddHandler DirectCast(ie, InternetExplorer).DocumentComplete, AddressOf LoadedCB 

    ie.Navigate(htmlfilename) 
    While Not documentLoaded AndAlso ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) <> OLECMDF.OLECMDF_ENABLED 
     Application.DoEvents() 
     Threading.Thread.Sleep(100) 
    End While 

    Try 
     ie.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, vbNull, vbNull) 
     While Not documentPrinted 
      Application.DoEvents() 
      Threading.Thread.Sleep(100) 
     End While 
    Catch ex As Exception 
     Debug.Print(ex.Message) 
    End Try 
End Sub 

Private Sub LoadedCB(ByVal obj As Object, ByRef url As Object) 
    documentLoaded = True 
End Sub 

Private Sub PrintedCB(ByVal obj As Object) 
    documentPrinted = True 
End Sub 
End Class 

當我點擊Button1的首次everiything行爲與預期(打印開始),但是當我點擊Button1的打印一次以上 - 而不是印刷的,我得到錯誤信息:

「System.Runtime.InteropServices.COMException」類型的第一次機會異常出現在my.exe
試圖撤銷尚未註冊的拖放目標(異常來自HRESULT:0x80040100(DRAGDROP_E_NOTREGISTERED))

什麼可能導致這個錯誤,我怎麼能擺脫它能夠不止一次打印文檔所描述的組件?

回答

1

在您再次致電Navigate之前,您似乎忘記將documentLoadeddocumentPrinted重新設置爲false。它們仍然是上一次打印輸出的true,並且您的等待事件迴路邏輯不起作用。即,它應該是:

documentLoaded = False 
documentPrinted = False 
ie.Navigate(htmlfilename) 
While Not documentLoaded AndAlso ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) <> OLECMDF.OLECMDF_ENABLED 
    Application.DoEvents() 
    Threading.Thread.Sleep(100) 
End While 

還有另一個問題。顯然,您不會在PrintHTMLDocument中重新使用InternetExplorer對象,並且每次打印時都會創建一個新實例。如果由於某種原因你不想重複使用它,你至少應該在PrintHTMLDocument的末尾呼叫ie.Quit。否則,您將依賴.NET垃圾收集器來釋放該對象(這是一個進程外COM自動化對象,每個對象都需要一些實質性的系統資源)。如果您打算重新使用它,請確保只添加一次事件處理程序。

+1

是的,就是這樣!謝謝Noseratio。我的代碼現在可以按照預期工作。我不得不使用新的實例來打印文檔,但我不知道爲什麼我的代碼部分缺失?也許我貼「太快」了。是的,每次印刷後,我刪除處理程序,調用ie.Quit並設置ie = Nothing。我覺得這足以清潔一個物體。 –

+0

沒問題,很高興幫助。你應該沒問題,如果你進行這樣的清理。 – Noseratio