HOW TO: Invoke the Find, View Source, and Options Dialog Boxes for the WebBrowser Control from Visual C# .NET

Summary
Define IOleCommandTarget in Visual C# .NET
Define the Command GUID for CGID_IWebBrowser
Call Exec()
Complete Code Listing
References

SUMMARY

This article describes how to invoke the Microsoft Internet Explorer Find, the Internet Options, and the 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 was tested to work correctly with Internet Explorer 6 and earlier, there is no guarantee that these techniques will continue to work successfully in future versions.

back to the top

Define IOleCommandTarget in Visual C# .NET

To define a .NET interface to obtain a reference to a Component Object Model (COM) interface, follow these steps:
1.Assign the interface the GUID of the appropriate COM interface.
2.Include type declarations for all the methods of the interface.
3.Include references to the Mshtml.dll file and the Shdocvw.dll file. To do this in your Visual C# .NET project, follow these steps:
a.Click Add Reference on the Project menu.
b.Click the COM tab.
c.Double-click Microsoft HTML Object Library and Microsoft Internet Controls.
4.Include the following interface declaration just before your application's namespace declaration to add a reference to the Microsoft HTML (MSHTML) IOleCommandTarget interface:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
public struct OLECMDTEXT
{
        public uint cmdtextf;
        public uint cwActual;
        public uint cwBuf;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst=100)]public char rgwz;
}

[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
        public uint cmdID;
        public uint cmdf;
}

// Interop definition for IOleCommandTarget.
[ComImport,
Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
        //IMPORTANT: The order of the methods is critical here. You
        //perform early binding in most cases, so the order of the methods
        //here MUST match the order of their vtable layout (which is determined
        //by their layout in IDL). The interop calls key off the vtable ordering,
        //not the symbolic names. Therefore, if you switched these method declarations
        //and tried to call the Exec method on an IOleCommandTarget interface from your
        //application, it would translate into a call to the QueryStatus method instead.
        void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
        void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut);
}
                                
back to the top

Define the Command GUID for CGID_IWebBrowser

You must also define the GUID for CGI_IWebBrowser to inform MSHTML how to process your command IDs. Use the Microsoft .NET Framework class GUID to do this:
    private Guid cmdGuid = new Guid("ED016940-BD5B-11CF-BA4E-00C04FD70816");
                                
Also, define the command IDs that are used for each of the commands:
    private enum MiscCommandTarget
    {
        Find = 1,
        ViewSource,
        Options
    }
                                
back to the top

Call Exec()

Finally, encapsulate the calls to the Exec method in three separate method calls. Each call assumes the existence of a hosted instance of the WebBrowser control that is named webBrowser:
private mshtml.HTMLDocument GetDocument()
                {
                        try
                        {
                                mshtml.HTMLDocument htm = (mshtml.HTMLDocument)axWebBrowser2.Document;
                                return htm;
                        }
                        catch
                        {
                                throw (new Exception("Cannot retrieve the document from the WebBrowser control"));
                        }
                }

                public void ViewSource()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.ViewSource,
                                (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch(Exception e)
                        {
                                System.Windows.Forms.MessageBox.Show(e.Message);
                        }
                }

                public void Find()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Find,
                                (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch(Exception e)
                        {
                                System.Windows.Forms.MessageBox.Show(e.Message);
                        }
                }
                public void InternetOptions()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Options,
                                (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch
                        {
                                // NOTE: Because of the way that this CMDID is handled in Internet Explorer,
                                // this catch block will always fire, even though the dialog box
                                // and its operations completed successfully. You can suppress this
                                // error without causing any damage to your host.
                        }
                }
back to the top

Complete Code Listing

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

Form1.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace _329014
{
        /// <summary>
        /// Summary description for Form1.
        /// </summary>
        public class Form1 : System.Windows.Forms.Form
        {
                /// <summary>
                /// Required designer variable.
                /// </summary>
                private System.ComponentModel.Container components = null;
                public Form1()
                {
                        //
                        // Required for Windows Form Designer support
                        //
                        InitializeComponent();
                        //
                        // TODO: Add any constructor code after InitializeComponent call
                        //
                        object flags= 0;
                        object targetframe= "";
                        object headers="";
                        object post = "";
                        axWebBrowser1.Navigate("http://www.microsoft.com",
                        ref flags, ref targetframe, ref post, ref headers);
                }

                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if (components != null)
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows Form Designer generated code
                /// <summary>
                /// Required method for Designer support - do not modify
                /// the contents of this method with the code editor.
                /// </summary>
                private void InitializeComponent()
                {
                        System.Resources.ResourceManager resources = new
                        System.Resources.ResourceManager(typeof(Form1));
                        this.button1 = new System.Windows.Forms.Button();
                        this.axWebBrowser1 = new AxSHDocVw.AxWebBrowser();
                        ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).BeginInit();
                        this.SuspendLayout();
                        //
                        // button1
                        //
                        this.button1.Location = new System.Drawing.Point(0, 0);
                        this.button1.Name = "button1";
                        this.button1.TabIndex = 0;
                        this.button1.Text = "button1";
                        this.button1.Click += new System.EventHandler(this.button1_Click_1);
                        //
                        // axWebBrowser1
                        //
                        this.axWebBrowser1.Enabled = true;
                        this.axWebBrowser1.Location = new System.Drawing.Point(0, 104);
                        this.axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)
                        (resources.GetObject("axWebBrowser2.OcxState")));
                        this.axWebBrowser1.Size = new System.Drawing.Size(300, 150);
                        this.axWebBrowser1.TabIndex = 1;
                        //
                        // Form1
                        //
                        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                        this.ClientSize = new System.Drawing.Size(292, 273);
                        this.Controls.Add(this.axWebBrowser1);
                        this.Controls.Add(this.button1);
                        this.Name = "Form1";
                        ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).EndInit();
                        this.ResumeLayout(false);

                }
                #endregion

                private System.Windows.Forms.Button button1;
                private AxSHDocVw.AxWebBrowser axWebBrowser1;

                private Guid cmdGuid = new Guid("ED016940-BD5B-11CF-BA4E-00C04FD70816");
                private enum MiscCommandTarget
                {
                        Find = 1,
                        ViewSource,
                        Options
                }
                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main()
                {
                        Application.Run(new Form1());
                }
                private mshtml.HTMLDocument GetDocument()
                {
                        try
                        {
                                mshtml.HTMLDocument htm = (mshtml.HTMLDocument)axWebBrowser1.Document;
                                return htm;
                        }
                        catch
                        {
                                throw (new Exception("Cannot retrieve document from WebBrowser Control"));
                        }
                }

                public void ViewSource()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.ViewSource,
                                (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch(Exception e)
                        {
                                System.Windows.Forms.MessageBox.Show(e.Message);
                        }
                }

                public void Find()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Find,
                         (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch(Exception e)
                        {
                                System.Windows.Forms.MessageBox.Show(e.Message);
                        }
                }
                public void InternetOptions()
                {
                        IOleCommandTarget cmdt;
                        Object o = new object();
                        try
                        {
                                cmdt = (IOleCommandTarget)GetDocument();
                                cmdt.Exec(ref cmdGuid, (uint)MiscCommandTarget.Options,
                                (uint)SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref o, ref o);
                        }
                        catch
                        {
                                // NOTE: Because of the way that this CMDID is handled in Internet Explorer,
                                // this catch block will always fire, even though the dialog box
                                // and its operations completed successfully. You can suppress this
                                // error without causing any damage to your host.
                        }
                }
                private void button1_Click_1(object sender, System.EventArgs e)
                {
                        InternetOptions();
                        ViewSource();
                        Find();
                }
        }
}

Class1.cs
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
public struct OLECMDTEXT
{
        public uint cmdtextf;
        public uint cwActual;
        public uint cwBuf;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst=100)]public char rgwz;
}

[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
        public uint cmdID;
        public uint cmdf;
}

// Interop definition for IOleCommandTarget.
[ComImport,
Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
        //IMPORTANT: The order of the methods is critical here. You
        //perform early binding in most cases, so the order of the methods
        //here MUST match the order of their vtable layout (which is determined
        //by their layout in IDL). The interop calls key off the vtable ordering,
        //not the symbolic names. Therefore, if you switched these method declarations
        //and tried to call the Exec method on an IOleCommandTarget interface from your
        //application, it would translate into a call to the QueryStatus method instead.
        void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
                OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
        void Exec(ref Guid pguidCmdGroup,
                uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut);
}

public class Class1
{
        public Class1()
        {

        }
}

back to the top

REFERENCES

For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

311303 WebOCHostVB.exe Hosts the WebBrowser Control in Visual Basic

For more information about developing Web-based solutions for Microsoft Internet Explorer, visit the following Microsoft Web sites:

http://msdn.microsoft.com/workshop/entry.asp

http://msdn.microsoft.com/ie/

http://support.microsoft.com/highlights/iep.asp?FR=0&SD=MSDN