How to invoke the View Source dialog box, the Find dialog box, and the Internet Options dialog box for the WebBrowser control in Visual C++ .NET or in Visual C++ 2005 (815716)



The information in this article applies to:

  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET (2003)
  • Microsoft .NET Framework 1.1
  • Microsoft Internet Explorer (Programming) version 6.0

For a Microsoft Visual Basic .NET version of this article, see 311288.

For a Microsoft Visual C# .NET version of this article, see 329014.

This article refers to the following Microsoft .NET Framework Class Library namespaces:
  • System::ComponentModel
  • System::Collections
  • System::Windows::Forms
  • System::Runtime::InteropServices

SUMMARY

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

IN THIS TASK

INTRODUCTION

You can invoke various dialog boxes for a Microsoft WebBrowser control. Three of these dialog boxes are: View Source, Find, and Internet Options. Before you can invoke these dialog boxes by means of a hosted UserControl object, you have to define the IOleCommandTarget interface and then implement the methods that are exposed in that interface. This step-by-step article outlines the steps to follow to invoke these three dialog boxes.

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

MORE INFORMATION

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Microsoft Visual C++ .NET 2003 or Microsoft Visual C++ 2005
  • Microsoft .NET Framework 1.1
  • Microsoft Internet Explorer 6.0
This article assumes that you are familiar with the following topics:
  • Programming with Microsoft Visual C++ .NET or Microsoft Visual C++ 2005
  • Hosting the WebBrowser control (Shdocvw.dll)
back to the top

Define the IOleCommandTarget interface

To define a .NET interface to obtain a reference to a Component Object Model (COM) interface (IOleCommandTarget), follow these steps:
  1. Open your UserControl library project that is hosting the WebBrowser control.
  2. In Solution Explorer, right-click the project node, and then click Add Reference.

    Note In Visual Studio 2005, Add Reference is changed to Reference.
  3. In the Add Reference dialog box, click the COM tab.
  4. To add items to the Selected Components list, double-click both Microsoft HTML Object Library and Microsoft Internet Controls in the list of COM components, and then click OK.
  5. Include the IOleCommandTarget interface declaration inside the namespace declaration of your control to add a reference to the Microsoft HTML (MSHTML) IOleCommandTarget interface. To do this, insert the following code before the UserControl class definition:
    [StructLayout(LayoutKind::Sequential)] 
    public __gc struct OLECMDTEXT
    {
    public:
    	unsigned int cmdtextf;
    	unsigned int cwActual;
    	unsigned int cwBuf;
    	char rgwz;
    };
    
    [StructLayout(LayoutKind::Sequential)] 
    public __gc struct OLECMD
    {
    public:
    	long cmdID;
    	UInt64 cmdf;
    };
    // Interop definition for IOleCommandTarget. 
    [ComImport, 
    Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
    InterfaceType(ComInterfaceType::InterfaceIsIUnknown)]
    public __gc __interface IOleCommandTarget
    { 
    	//IMPORTANT: The order of the methods is critical here. You will perform
    	//early binding in most cases, and therefore, 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 off the symbolic names, and therefore, if you switched these method
    	//declarations and tried to call the Exec() function on an IOleCommandTarget
    	//interface from your application, it would translate into a call to
     //QueryStatus() instead. 
    	void QueryStatus(Guid* pguidCmdGroup, UInt32 cCmds, 
     [MarshalAs(UnmanagedType::LPArray, SizeParamIndex=1)] OLECMD* prgCmds, OLECMDTEXT* CmdText);
    	void Exec(Guid* pguidCmdGroup, long nCmdId, long nCmdExecOpt, Object* pvaIn, Object* pvaOut);
    };
    Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile the previous code sample. To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
    1. Click Project, and then click <ProjectName> Properties.

      Note <ProjectName> is a placeholder for the name of the project.
    2. Expand Configuration Properties, and then click General.
    3. Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting in the right pane, click Apply, and then click OK.
    For more information about the common language runtime support compiler option, visit the following Microsoft Web site:

    /clr (Common Language Runtime Compilation)
    http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

    These steps apply to the whole article.

    Note You have to assign to the interface the GUID of the appropriate COM interface. Also, you have to include type declarations for all the methods of the interface.
  6. Add a ComSourceInterfaces attribute to the UserControl class to identify the list of interfaces that are exposed as COM event sources. To do this, insert the following code before the UserControl class definition:
    //Add a ComSourceInterfaces attribute to the control class to 
    //identify the list of interfaces that are exposed as COM event sources.
    [ClassInterface(ClassInterfaceType::None),ComSourceInterfaces(__typeof(IOleCommandTarget))]
back to the top

Define the Command GUID for the CGID_IWebBrowser control

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 declare the GUID. To do this, follow these steps:
  1. Add the following code in your UserControl class:
    private:
    	//Define the command group GUID for the WebBrowser control
    	Guid cmdGuid;
  2. Insert the following code in the UserControl class constructor, after the call to the InitializeComponent function:
    cmdGuid = Guid(S"ED016940-BD5B-11CF-BA4E-00C04FD70816");
Also, define the command IDs that are used for each of the commands. To do this, insert the following code in the UserControl class:
private:
	// Constants for the commands that are named earlier
	__value enum MiscCommandTarget
	{
		Find = 1,
		ViewSource,
		Options
	};
Also, define an mshtml::HTMLDocument member variable to implement the Document property of the WebBrowser control. To do this, insert the following variable declaration in the UserControl class:
private:
	// The current instance of MSHTML
	mshtml::HTMLDocument *document;
back to the top

Call the Exec() method

Implement a property getter function to return the document property. To do this, insert the following code after the InitializeComponent function:
public:
	__property mshtml::HTMLDocument* get_Document()
	{
		try
		{
			//mshtml::IHTMLDocument2* doc;
			document = __try_cast<mshtml::HTMLDocument*>(axWebBrowser1->Document);
			return document;
		}
		catch(Exception* e)
		{
			System::Windows::Forms::MessageBox::Show(e->Message->ToString());
		}
	}
Finally, encapsulate the calls to the Exec method in three separate method calls. To do this, insert the following code in the UserControl class:
public:
	void viewsource()
	{
		IOleCommandTarget* cmdt;
		Object * o = new Object();
		// If the doc object is not set to anything, or if there is
		// some bizarre error in accessing IOleCommandTarget,
		// exit gracefully.
		try
		{
			cmdt = __try_cast<IOleCommandTarget*>(get_Document());				
			cmdt->Exec(&cmdGuid, (long)MiscCommandTarget::ViewSource, (long)Interop::SHDocVw::OLECMDEXECOPT::OLECMDEXECOPT_DODEFAULT, o, o);				
		}
		catch(Exception* e) 
		{
			System::Windows::Forms::MessageBox::Show(e->Message->ToString());				
		}
	}

	void find()
	{
		IOleCommandTarget* cmdt;
		Object * o = new Object();

		// If the doc object is not set to anything, or if there is
		// some bizarre error in accessing IOleCommandTarget,
		// exit gracefully.
		try
		{
			cmdt = __try_cast<IOleCommandTarget*>(get_Document());
			cmdt->Exec(&cmdGuid, (long)MiscCommandTarget::Find, (long)Interop::SHDocVw::OLECMDEXECOPT::OLECMDEXECOPT_DODEFAULT, o, o);
		}
		catch(Exception * e)
		{
			System::Windows::Forms::MessageBox::Show(e->Message->ToString());
		}
	}
	void options()
	{    
		IOleCommandTarget* cmdt;
		Object * o = new Object();
		try
		{
			cmdt = __try_cast<IOleCommandTarget*>(get_Document());
			cmdt->Exec(&cmdGuid, (long)MiscCommandTarget::Options, (long)Interop::SHDocVw::OLECMDEXECOPT::OLECMDEXECOPT_DODEFAULT, o, o);
		}
		catch(Exception * e)
		{
		// 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.
			String * s = e->Message->ToString();
		}
	}
back to the top

REFERENCES

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

311303 WebOCHostVB.exe hosts the WebBrowser control in Visual Basic .NET

326217 INFO: WebOCHostCSharp.exe hosts the WebBrowser control in C# .NET


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

Modification Type:MajorLast Reviewed:4/21/2006
Keywords:kbcode kbWindowsForms kbForms kbDLL kbDlg kbCtrl kbControl kbCOMInterop kbCollections kbActivexEvents kbinterop kbInetDev kbEvent kbHOWTOmaster KB815716 kbAudDeveloper