从webbrowser打印两次

时间:2013-10-04 08:02:15

标签: vb.net

当我尝试不止一次打印时,我遇到了COM webbrowser的问题 复制问题:

1)创建一个新的“Windows Forms”项目
2)将COM引用添加到“Microsoft Internet Controls”
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时,一切都按预期运行(打印开始),但是当我点击button1进行多次打印时 - 而不是打印我收到错误消息:

  

my.exe中发生'System.Runtime.InteropServices.COMException'类型的第一次机会异常   试图撤销尚未注册的放置目标(HRESULT异常:0x80040100(DRAGDROP_E_NOTREGISTERED))

什么可能导致此错误,如何摆脱它以便能够使用所描述的组件多次打印文档?

1 个答案:

答案 0 :(得分:1)

在您再次致电documentLoaded之前,您似乎忘了将documentPrintedfalse设置回Navigate。它们从上次打印输出仍然是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

还有另一个问题。显然,您不会在InternetExplorer中重复使用PrintHTMLDocument对象,并在每次打印时创建一个新实例。如果由于某种原因您不想重复使用它,您至少应该在ie.Quit结束时调用PrintHTMLDocument。否则,您依靠.NET垃圾收集器来释放对象(这是一个进程外的COM自动化对象,每个对象占用一些实质性的系统资源)。如果您打算重新使用它,请确保只添加一次事件处理程序。