HOW TO: Invoke the Find, View Source, and Options Dialog Boxes for the WebBrowser Control from Visual Basic .NET (311288)



The information in this article applies to:

  • Microsoft Visual Basic .NET (2003)
  • Microsoft Visual Basic .NET (2002)

This article was previously published under Q311288

SUMMARY

This article describes how to invoke the Microsoft Internet Explorer Find, Internet Options, and View Source dialog boxes in an application that hosts the WebBrowser control.

WARNING: This sample uses an undocumented command-group GUID that is subject to change in the future. Although this sample has been tested to work correctly with all versions of Internet Explorer up to version 6, there is no guarantee that these techniques will continue to work successfully in future versions.

back to the top

Defining IOleCommandTarget in Visual Basic .NET

You can define a .NET interface to obtain a reference to a COM interface by assigning the interface the GUID of the appropriate COM interface, and including type declarations for all of the methods that are contained on the interface. Because this requires a reference to the Mshtml IOleCommandTarget, create a Visual Basic .NET .vb file. To do this, follow these steps:
  1. In Project Explorer, right-click References, and then click Add Reference.
  2. Click .NET Framework.
  3. In the Component Name list, click Microsoft.mshtml, click Select, and then click OK.
  4. Include the following interface declaration:
Imports System
Imports System.Runtime.InteropServices
Public Class Class1
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure OLECMDTEXT
        Public cmdtextf As UInt32
        Public cwActual As UInt32
        Public cwBuf As UInt32
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=100)> _
        Public rgwz As Char
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure OLECMD
        Public cmdID As UInt32
        Public cmdf As UInt32
    End Structure

    ' Interop definition for IOleCommandTarget. To reproduce the problem, the method order 
    ' here does not match the Vtable layout of the IOleCommandTarget interface.
    ' For more information about the IOleCommandTarget interface, see MSDN. 

    <ComImport(), Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), _
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IOleCommandTarget

        Sub QueryStatus(ByRef pguidCmdGroup As Guid, _
        ByVal cCmds As UInt32, <MarshalAs(UnmanagedType.LPArray, _
        SizeParamIndex:=1)> ByVal prgCmds() As OLECMD, _
        ByRef pCmdText As OLECMDTEXT)

        Sub Exec(ByRef pguidCmdGroup As Guid, _
        ByVal nCmdId As UInt32, ByVal nCmdExecOpt As UInt32, _
        ByRef pvaIn As Object, ByRef pvaOut As Object)
    End Interface

End Class
				
back to the top

Defining the Command GUID for CGID_IWebBrowser

You must also define the GUID for CGI_IWebBrowser so that you can instruct Mshtml about how to process your command IDs. Use the Microsoft .NET Framework class GUID to do this:
     Private cmdGUID As New Guid(&HED016940, -17061, _
   &H11CF, &HBA, &H4E, &H0, &HC0, &H4F, &HD7, &H8, &H16)
				
Also, define the command IDs that are used for each of the commands:
     Private Enum MiscCommandTarget
        ViewSource = 2
        Options
        Find = 1
    End Enum
				
back to the top

Calling Exec()

Finally, encapsulate the calls to Exec in three separate method calls. Each call assumes the existence of a hosted instance of the WebBrowser control that is named webBrowser:
      Private Function GetDocument() As mshtml.HTMLDocument
        Try
            Dim htm As mshtml.HTMLDocument = AxWebBrowser1.Document
            GetDocument = htm
        Catch
            Throw (New Exception("Cannot retrieve the document from the WebBrowser" + _
            "Control: " + Err.GetException().Message))
        End Try
    End Function
    Public Sub ViewSource()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.ViewSource), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)
        Catch
            Throw (New Exception(Err.GetException().Message))
        End Try
    End Sub

    Public Sub Find()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.Find), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)

        Catch
            Throw (New Exception(Err.GetException().Message))
        End Try
    End Sub

    Public Sub InternetOptions()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.Options), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)
        Catch
            ' NOTE: Due to the way this CMDID is handled inside of Internet Explorer,
            ' this Catch block will always fire, even though the dialog
            ' and its operations completed successfully. Suppressing this
            ' error will cause no harm to your host.
        End Try
    End Sub
				
back to the top

Complete Code Listing


Note Manually add the Microsoft Web Browser control to the form.

Form1.vb
Imports _311288.Class1
Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call.

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it by using the code editor.
    Friend WithEvents AxWebBrowser1 As AxSHDocVw.AxWebBrowser
    Friend WithEvents Button1 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1))
        Me.AxWebBrowser1 = New AxSHDocVw.AxWebBrowser
        Me.Button1 = New System.Windows.Forms.Button
        CType(Me.AxWebBrowser1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'AxWebBrowser1
        '
        Me.AxWebBrowser1.Enabled = True
        Me.AxWebBrowser1.Location = New System.Drawing.Point(0, 96)
        Me.AxWebBrowser1.OcxState = CType(resources.GetObject("AxWebBrowser1.OcxState"), System.Windows.Forms.AxHost.State)
        Me.AxWebBrowser1.Size = New System.Drawing.Size(576, 150)
        Me.AxWebBrowser1.TabIndex = 0
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(256, 24)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Button1"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(576, 273)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.AxWebBrowser1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.AxWebBrowser1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub

#End Region
    Private cmdGUID As New Guid(&HED016940, -17061, _
   &H11CF, &HBA, &H4E, &H0, &HC0, &H4F, &HD7, &H8, &H16)

    Private Enum MiscCommandTarget
        ViewSource = 2
        Options
        Find = 1
    End Enum
    Private Function GetDocument() As mshtml.HTMLDocument
        Try
            Dim htm As mshtml.HTMLDocument = AxWebBrowser1.Document
            GetDocument = htm
        Catch
            Throw (New Exception("Cannot retrieve the document from the WebBrowser" + _
            "Control: " + Err.GetException().Message))
        End Try
    End Function
    Public Sub ViewSource()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.ViewSource), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)
        Catch
            Throw (New Exception(Err.GetException().Message))
        End Try
    End Sub

    Public Sub Find()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.Find), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)

        Catch
            Throw (New Exception(Err.GetException().Message))
        End Try
    End Sub

    Public Sub InternetOptions()
        Dim cmdt As IOleCommandTarget
        Dim o As Object

        Try
            cmdt = CType(GetDocument(), IOleCommandTarget)
            cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.Options), _
            Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT), o, o)
        Catch
            ' NOTE: Due to the way this CMDID is handled inside of Internet Explorer,
            ' this Catch block will always fire, even though the dialog
            ' and its operations completed successfully. Suppressing this
            ' error will cause no harm to your host.
        End Try
    End Sub


    Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
        AxWebBrowser1.Navigate("http://www.microsoft.com")

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        InternetOptions()
        ViewSource()
        Find()
    End Sub
End Class
Class1.vb
Imports System
Imports System.Runtime.InteropServices
Public Class Class1
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure OLECMDTEXT
        Public cmdtextf As UInt32
        Public cwActual As UInt32
        Public cwBuf As UInt32
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=100)> _
        Public rgwz As Char
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure OLECMD
        Public cmdID As UInt32
        Public cmdf As UInt32
    End Structure

    ' Interop definition for IOleCommandTarget. To reproduce the problem, the method order 
    ' here does not match the Vtable layout of the IOleCommandTarget interface.
    ' For more information about the IOleCommandTarget interface, see MSDN. 

    <ComImport(), Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), _
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IOleCommandTarget

        Sub QueryStatus(ByRef pguidCmdGroup As Guid, _
        ByVal cCmds As UInt32, <MarshalAs(UnmanagedType.LPArray, _
        SizeParamIndex:=1)> ByVal prgCmds() As OLECMD, _
        ByRef pCmdText As OLECMDTEXT)

        Sub Exec(ByRef pguidCmdGroup As Guid, _
        ByVal nCmdId As UInt32, ByVal nCmdExecOpt As UInt32, _
        ByRef pvaIn As Object, ByRef pvaOut As Object)
    End Interface

End Class
back to the top

Modification Type:MajorLast Reviewed:2/12/2004
Keywords:kbHOWTOmaster KB311288 kbAudDeveloper