简体   繁体   中英

Initialize ExtendedWebBrowser in VB.NET, problem parsing from C# to VB.Net

Following a previous answer open link in new tab WebBrowser control .

And thanks to Mauricio Rojas who posted a good example in C#:
Extended WebBrowser Control for C# .

I'm trying to convert code provided for C# to VB.NET, but I have a problem:
I don't understand why, when I try to implement the DWebBrowserEvents2 Interface in the WebBrowserExtendedEvents Class, Visual Studio gives me an Error:

Class WebBrowserExtendedEvents must implements Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean) for the Interface DWebBrowserEvents2

It seems to me that I've correctly implemented that Method, in the Class and the Interface.

Note: I though about removing parts of code not related to the question, as jmcilhinney suggested, but since I didn't find, in the Web, clear examples of ExtendedWebBrowser for VB.Net, I decided to leave the full code, for the benefit of others.

Here the full code translated to VB.Net

'First define a new EventArgs class to contain the newly exposed data
Public Class NewWindow2EventArgs
    Inherits CancelEventArgs

    Private _ppDisp As Object
    Public Property PPDisp As Object
        Get
            Return _ppDisp
        End Get
        Set(value As Object)
            _ppDisp = value
        End Set
    End Property

    Public Sub New(ByRef ppDisp As Object, ByRef cancel As Boolean)
        MyBase.New()
        Me.ppDisp = Me.ppDisp
        Me.Cancel = cancel
    End Sub
End Class

Public Class DocumentCompleteEventArgs
    Inherits EventArgs

    Private _ppDisp As Object
    Public Property PPDisp As Object
        Get
            Return _ppDisp
        End Get
        Set(value As Object)
            _ppDisp = value
        End Set
    End Property

    Private _url As Object
    Public Property Url As Object
        Get
            Return _url
        End Get
        Set(value As Object)
            _url = value
        End Set
    End Property

    Public Sub New(ByVal ppDisp As Object, ByVal url As Object)
        MyBase.New()
        Me.ppDisp = Me.ppDisp
        Me.url = Me.url
    End Sub
End Class

Public Class CommandStateChangeEventArgs
    Inherits EventArgs

    Private _command As Long
    Public Property Command As Long
        Get
            Return _command
        End Get
        Set(value As Long)
            _command = value
        End Set
    End Property

    Private _enable As Boolean
    Public Property Enable As Boolean
        Get
            Return _enable
        End Get
        Set(value As Boolean)
            _enable = value
        End Set
    End Property

    Public Sub New(ByVal command As Long, ByRef enable As Boolean)
        MyBase.New()
        Me.command = Me.command
        Me.enable = Me.enable
    End Sub

End Class

'Extend the WebBrowser control
Public Class ExtendedWebBrowser
    Inherits WebBrowser

    Private cookie As AxHost.ConnectionPointCookie

    Private Shadows events As WebBrowserExtendedEvents

    'This method will be called to give you a chance to create your own event sink
    Protected Overrides Sub CreateSink()
        'MAKE SURE TO CALL THE BASE or the normal events won't fire
        MyBase.CreateSink()
        Me.events = New WebBrowserExtendedEvents(Me)
        Me.cookie = New AxHost.ConnectionPointCookie(Me.ActiveXInstance, Me.events, GetType(DWebBrowserEvents2))
    End Sub

    Public ReadOnly Property Application As Object
        Get
            Dim axWebBrowser As IWebBrowser2 = CType(Me.ActiveXInstance, IWebBrowser2)
            If (Not (axWebBrowser) Is Nothing) Then
                Return axWebBrowser.Application
            Else
                Return Nothing
            End If

        End Get
    End Property

    Protected Overrides Sub DetachSink()
        If (Not (Me.cookie) Is Nothing) Then
            Me.cookie.Disconnect()
            Me.cookie = Nothing
        End If

        MyBase.DetachSink()
    End Sub

    'This new event will fire for the NewWindow2
    Public Event NewWindow2 As EventHandler(Of NewWindow2EventArgs)

    Protected Sub OnNewWindow2(ByRef ppDisp As Object, ByRef cancel As Boolean)
        'Dim h As EventHandler(Of NewWindow2EventArgs) = NewWindow2

        Dim args As NewWindow2EventArgs = New NewWindow2EventArgs(ppDisp, cancel)
        If Not IsNothing(NewWindow2Event) Then
            RaiseEvent NewWindow2(Me, args)
        End If

        'Pass the cancellation chosen back out to the events
        'Pass the ppDisp chosen back out to the events
        cancel = args.Cancel
        ppDisp = args.PPDisp
    End Sub

    'This new event will fire for the DocumentComplete
    Public Event DocumentComplete As EventHandler(Of DocumentCompleteEventArgs)

    Protected Sub OnDocumentComplete(ByVal ppDisp As Object, ByVal url As Object)
        'Dim h As EventHandler(Of DocumentCompleteEventArgs) = DocumentComplete
        Dim args As DocumentCompleteEventArgs = New DocumentCompleteEventArgs(ppDisp, url)
        If Not IsNothing(DocumentCompleteEvent) Then
            RaiseEvent DocumentComplete(Me, args)
        End If

        'Pass the ppDisp chosen back out to the events
        ppDisp = args.PPDisp
        'I think url is readonly
    End Sub

    'This new event will fire for the CommandStateChange
    Public Event CommandStateChange As EventHandler(Of CommandStateChangeEventArgs)

    Protected Sub OnCommandStateChange(ByVal command As Long, ByRef enable As Boolean)
        'Dim h As EventHandler(Of CommandStateChangeEventArgs) = CommandStateChange
        Dim args As CommandStateChangeEventArgs = New CommandStateChangeEventArgs(command, enable)
        If Not IsNothing(CommandStateChangeEvent) Then
            RaiseEvent CommandStateChange(Me, args)
        End If

    End Sub

    'This class will capture events from the WebBrowser
    Public Class WebBrowserExtendedEvents
        Inherits System.Runtime.InteropServices.StandardOleMarshalObject

        '******************* HERE THE ERROR ********************
        Implements DWebBrowserEvents2
        '*******************************************************

        Private _Browser As ExtendedWebBrowser

        Public Sub New(ByVal browser As ExtendedWebBrowser)
            MyBase.New()
            Me._Browser = browser
        End Sub

        'Implement whichever events you wish
        Public Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean)
            Me._Browser.OnNewWindow2(pDisp, cancel)
        End Sub

        'Implement whichever events you wish
        Public Sub DocumentComplete(ByVal pDisp As Object, ByRef url As Object)
            Me._Browser.OnDocumentComplete(pDisp, url)
        End Sub

        'Implement whichever events you wish
        Public Sub CommandStateChange(ByVal command As Long, ByVal enable As Boolean)
            Me._Browser.OnCommandStateChange(command, enable)
        End Sub

    End Class

    <ComImport(), _
     Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), _
     InterfaceType(ComInterfaceType.InterfaceIsIDispatch), _
     TypeLibType(TypeLibTypeFlags.FHidden)> _
    Public Interface DWebBrowserEvents2

        <DispId(105)> _
        Sub CommandStateChange(ByVal command As Long, ByVal enable As Boolean)

        <DispId(259)> _
        Sub DocumentComplete(ByVal pDisp As Object, ByRef URL As Object)

        <DispId(251)> _
        Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean)

    End Interface

    <ComImport(), _
     Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E"), _
     TypeLibType((TypeLibTypeFlags.FOleAutomation _
                Or (TypeLibTypeFlags.FDual Or TypeLibTypeFlags.FHidden)))> _
    Public Interface IWebBrowser2

        <DispId(100)> _
        Sub GoBack()

        <DispId(101)> _
        Sub GoForward()

        <DispId(102)> _
        Sub GoHome()

        <DispId(103)> _
        Sub GoSearch()

        <DispId(104)> _
        Sub Navigate(ByVal Url As String, ByRef flags As Object, ByRef targetFrameName As Object, ByRef postData As Object, ByRef headers As Object)

        <DispId(-550)> _
        Sub Refresh()

        <DispId(105)> _
        Sub Refresh2(ByRef level As Object)

        <DispId(106)> _
        Sub [Stop]()

        <DispId(200)> _
        ReadOnly Property Application As Object

        <DispId(201)> _
        ReadOnly Property Parent As Object

        <DispId(202)> _
        ReadOnly Property Container As Object

        <DispId(203)> _
        ReadOnly Property Document As Object

        <DispId(204)> _
        ReadOnly Property TopLevelContainer As Boolean

        <DispId(205)> _
        ReadOnly Property Type As String

        <DispId(206)> _
        Property Left As Integer

        <DispId(207)> _
        Property Top As Integer

        <DispId(208)> _
        Property Width As Integer

        <DispId(209)> _
        Property Height As Integer

        <DispId(210)> _
        ReadOnly Property LocationName As String

        <DispId(211)> _
        ReadOnly Property LocationURL As String

        <DispId(212)> _
        ReadOnly Property Busy As Boolean

        <DispId(300)> _
        Sub Quit()

        <DispId(301)> _
        Sub ClientToWindow(ByRef pcx As Integer, ByRef pcy As Integer)

        <DispId(302)> _
        Sub PutProperty(ByVal _property As String, ByVal vtValue As Object)

        <DispId(303)> _
        Function GetProperty(ByVal _property As String) As Object

        <DispId(0)> _
        ReadOnly Property Name As String

        <DispId(-515)> _
        ReadOnly Property HWND As Integer

        <DispId(400)> _
        ReadOnly Property FullName As String

        <DispId(401)> _
        ReadOnly Property Path As String

        <DispId(402)> _
        Property Visible As Boolean

        <DispId(403)> _
        Property StatusBar As Boolean

        <DispId(404)> _
        Property StatusText As String

        <DispId(405)> _
        Property ToolBar As Integer

        <DispId(406)> _
        Property MenuBar As Boolean

        <DispId(407)> _
        Property FullScreen As Boolean

        <DispId(500)> _
        Sub Navigate2(ByRef URL As Object, ByRef flags As Object, ByRef targetFrameName As Object, ByRef postData As Object, ByRef headers As Object)

        <DispId(503)> _
        Sub ShowBrowserBar(ByRef pvaClsid As Object, ByRef pvarShow As Object, ByRef pvarSize As Object)

        <DispId(-525)> _
        ReadOnly Property ReadyState As WebBrowserReadyState

        <DispId(550)> _
        Property Offline As Boolean

        <DispId(551)> _
        Property Silent As Boolean

        <DispId(552)> _
        Property RegisterAsBrowser As Boolean

        <DispId(553)> _
        Property RegisterAsDropTarget As Boolean

        <DispId(554)> _
        Property TheaterMode As Boolean

        <DispId(555)> _
        Property AddressBar As Boolean

        <DispId(556)> _
        Property Resizable As Boolean
    End Interface
End Class

VB.Net requires that an Implements keyword is added to the members that implement the corresponding Interface members.

Your WebBrowserExtendedEvents class defines the implementation but its members are missing the Implements keyword, that's all. For example:

Public Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean)
    Me._Browser.OnNewWindow2(pDisp, cancel)
End Sub

needs to changed in (keeping it here in one line since it cannot be written in two lines):

Public Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean) Implements DWebBrowserEvents2.NewWindow2
    Me._Browser.OnNewWindow2(pDisp, cancel)
End Sub

I also suggest to keep the MarshalAs attributes you found in the C# sample code.
For example, in the DWebBrowserEvents2 Interface definition, change:

<ComImport(), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), [...]
Public Interface DWebBrowserEvents2
    '[...]
    <DispId(251)> _
    Sub NewWindow2(ByRef pDisp As Object, ByRef cancel As Boolean)
End Interface

in:

<ComImport(), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), [...]
Public Interface DWebBrowserEvents2
    '[...]
    <DispId(251)>
    Sub NewWindow2(<MarshalAs(UnmanagedType.IDispatch)> ByRef pDisp As Object, ByRef cancel As Boolean)
End Interface

▶ Note that, when you receive a notification as the class must implement... , you can select the member that is underlined and press ALT+ENTER to let Visual Studio implement the interfaces for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM