2013-10-04 173 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