How to automate Internet Explorer in a contained UserControl control by using Visual C++ .NET 2003 or Visual C++ 2005 (815727)



The information in this article applies to:

  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET (2003)
  • Microsoft .NET Framework 1.1

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

This article refers to the following Microsoft .NET Framework Class Library namespace:
  • System::ComponentModel

IN THIS TASK

INTRODUCTION

This article describes how to develop a control library by using Microsoft Visual C++ .NET 2003 or Microsoft Visual C++ 2005. The control library demonstrates how to do the following:
  • Access the automation model and the scripting model in Microsoft Internet Explorer from a contained Visual C++ .NET UserControl control.
  • Enumerate all controls, links, and other tags in a page and in sub pages. This includes an algorithm that you can recursively enumerate floating frames and framesets.
Back to the top

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Microsoft Visual Studio .NET 2003 or Microsoft Visual Studio 2005
  • Microsoft Internet Explorer (Programming) version 5.5 or later
Back to the top

Download the UserControl control

The following file is available for download from the Microsoft Download Center:
DownloadDownload the VCNetCtrl.exe package now. Release Date: March 16, 2004

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

About the UserControl control

The UserControl control has the following important functions:

RecurseFrames function

void RecurseFrames( mshtml::HTMLDocument * iDoc , TreeNode * iNode )
{
	String* Title = S"";  
	String* tagName = S"";  
	
	TreeNode * TNode;
	
	mshtml::IHTMLElementCollection *pColl = 0;
	mshtml::FramesCollection* framesCol = 0;
	
	Object *nullObject = 0;
	
	Int32 i;

	//Get the document title
	if( iDoc != NULL )
	{
		Title = iDoc->get_title();
		if (Title->Length == 0)
			Title = S"Untitled Document";
	}

	TNode = new TreeNode(Title);
	
	// Add a root or a child node
	if (iNode == 0) 
		treeView1->Nodes->Add(TNode); // Root node
	else
		iNode->Nodes->Add(TNode);     // Child node
	
	if (iDoc != NULL)
	{
		DocCollection(iDoc, S"OBJECT", TNode, S"ActiveX Controls");
		DocCollection(iDoc, S"A", TNode, S"Anchors");
		DocCollection(iDoc, S"IMG", TNode, S"Images");
		DocCollection(iDoc, S"", TNode, S"All");
		
		// Get the Frames collection
		framesCol = iDoc->get_frames();

		// Recurse all the frames
		if (framesCol != NULL)
		{
			int nFrameLength = framesCol->length;
			for (i = 0; i < nFrameLength; i++)
			{
				Object* objNum = __box(i);
				Object* objNextFrame = framesCol->item(&objNum);

				// Get the HTMLWindow2 object
				mshtml::HTMLWindow2* objWin2 = 
					__try_cast<mshtml::HTMLWindow2*>(objNextFrame);

				// Get the HTMLDocument object
				mshtml::HTMLDocument* objDoc = 
					__try_cast<mshtml::HTMLDocument*>(objWin2->document);

				// Make the call to Recurse frames
				RecurseFrames( objDoc, TNode );
			}
		}
	}
}
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.

This function is a recursive function that is called for all the frame elements in the HTML file. First, the TITLE tag of the HTML file is read, and a tree node is created in the TreeView control with the name of title text. Next, the function calls the DocCollection function that passes different HTML tag names. After different HTML tags are grouped by the DocCollection function, the function verifies whether any Frame elements are present in the HTML document, and then performs the same actions recursively for the source HTML document of the frame.

DocCollection function

void DocCollection(mshtml::HTMLDocument * iDoc, String * iMatchTag ,TreeNode * iNode,String * iCategory)
{
	TreeNode * TNode;
	TreeNode * CatNode;
	int i;
	String * Name;
	mshtml::IHTMLElementCollection *pColl = 0;
	Object *nullObject = 0;
	CatNode = 0;

	if( iDoc != NULL )
	{
		// Get a pointer to all elements collections.
		pColl = iDoc->get_all();
		
		// Loop through the Elements Collection.
		int j = pColl->length;

		for (i=0;i < j ; i++)
		{
		    	
			// Read Tag Name of Each element in the Element Collection.
			Object *objNum = __box(i);
			String * str = __try_cast<String*>( __try_cast<mshtml::IHTMLElement*>(iDoc->get_all()->item(objNum,nullObject))->get_tagName());

			//if the tag is the that you want tag or you want all tags
			if (iMatchTag == S"" || String::Compare(str,iMatchTag)== 0)
			{
				Name = S"";
				if (String::Compare(str,S"IMG")== 0 ||  String::Compare(str,S"A")== 0)
				{
					Name = __try_cast<String*>(__try_cast<mshtml::IHTMLAnchorElement*>(iDoc->get_all()->item(objNum,nullObject))->get_href());
				}
				if (String::Compare(str,S"OBJECT")== 0)
				{
					Name = __try_cast<String*>(__try_cast<mshtml::IHTMLElement*>(iDoc->get_all()->item(objNum,nullObject))->get_id());
				}
		    	
				Name = String::Concat(str,S" ", Name); 
		    	
				//'add the category node if it is not there
				if (CatNode == 0)
				{
					CatNode = new TreeNode(iCategory);
					iNode->Nodes->Add(CatNode);
				}
				TNode = new TreeNode(Name);
				CatNode->Nodes->Add(TNode);
			}
		}
		// if there are no elements in the document, add category nodes
		if (j == 0)
		{
			//'add the category node if its not there
			if (CatNode == 0)
			{
				CatNode = new TreeNode(iCategory);
				iNode->Nodes->Add(CatNode);
			}
			TNode = new TreeNode(Name);
			CatNode->Nodes->Add(TNode);
		}
	}
}
This function is called from the RecurseFrames function. This function retrieves the TagName property of each HTML element and compares it with the second parameter that is passed to it. Then it groups different HTML tags and creates child nodes for each element occurrence. OBJ tags, A tags, and IMG tags are grouped under respective nodes, and all the remaining tags are grouped under the All node. A child node is created in the TreeView control for each HTML element in the HTML document.

Back to the top

Run the sample

The UserControl control is embedded in an HTML document and accesses the HTML Document Object Model (DOM). For the control to run, the permissions of the control must be set to Full Trust. To set the security permissions of the control to Full Trust by using the .NET Framework Configuration Wizard (Mscorcfg.msc), use one of the following methods:

Method 1

Set up the code group of the client computer. For the site where the control resides, set the security permissions for the client computer to Full Trust.

To set the security permissions for the sample from a computer that is named ServerName on a local intranet, follow these steps.

NoteServerName is a placeholder for the name of the computer on the local intranet.
  1. Start the .NET Framework configuration tool, Mscorcfg.msc.
  2. Expand each element in the following path: My Computer/Runtime Security Policy/Machine/Code Groups/All Code/LocalIntranet_Zone.
  3. Right-click the LocalIntranet_Zone node, and then click New.
  4. Name the new code group TestVCNetCtrl, and then click Next.
  5. On the Choose a condition type page in the Create Code Group dialog box, click URL as the condition type, and then type http://ServerName/* in the URL text box.
  6. Click Next to continue to the Assign a Permission Set to the Code Group page.
  7. Click to select Use existing permission set:, and then click FullTrust.
  8. Click Next, and then click Finish.
  9. Copy all the files in the debug directory to any location under http://ServerName, and then locate http://ServerName/testautoie.htm.

Method 2

Set the level of trust for the Assembly to Full Trust. To do this, follow these steps:
  1. Start Mscorcfg.msc.
  2. Expand each element in the My Computer/Runtime Security Policy path.
  3. Right-click the Runtime Security Policy node, and then click Trust Assembly to open the Trust an Assembly dialog box.
  4. Click to select Make changes to this computer, and then click Next to continue to the next page.
  5. Type the full path of the Assembly (for example, type: http://ServerName/VCNetCtrl.dll) in the appropriate field, or locate the Assembly.
  6. Click Next to proceed to the Choose the Minimum Level of Trust for this Assembly page of the Trust an Assembly dialog box.
  7. Adjust the trust level to Full Trust, click Next, and then click Finish.
  8. Copy all the files in the debug directory to any location under http://ServerName, and then locate http://ServerName/testautoie.htm.
The Web page is displayed with a TreeView control, a button control, and a frame. The frame displays links to different HTML and Web pages. If you click any one of the links, the respective Web page is loaded in the frame. If you click Re-Calculate, the TreeView control displays different nodes that correspond to different HTML tags that are present in the Web page that is loaded in the frame.

Back to the top

Technical notes

  • Make sure that you add a reference to the Microsoft HTML Object Library (MSHTML.dll) in your project.

    Note All post-Beta 2 releases of the Microsoft .NET Framework Software Development Kit (SDK) now include a primary interop assembly for Mshtml.dll. However, any organization that distributes the .NET Framework through the .NET Framework Redistributable must not depend on the existence of this interop assembly on clients. You can find the assembly that is named Microsoft.Mshtml.dll in the following location: INSTALL_DIR\Microsoft.NET\Primary Interop, where INSTALL_DIR is the installation directory for the .NET Framework. You can reference this from your projects and deploy your application on any system where the .NET Framework SDK is pre-installed.
  • This is an unmanaged COM component that allows only full-trusted callers. Therefore, you must have Full Trust code access permissions to run the control. This is discussed in the Run the sample section of this article.
  • .NET UserControl control instances cannot directly access the Document Object Model of their hosting page, as ActiveX controls do. To work around this issue, you must expose a property in your UserControl control that retrieves the HTML document from the page. This is demonstrated in the following sample code:
    private:
    mshtml::HTMLDocument* docVal;
    	
    public:
    
    __property mshtml::HTMLDocument* get_DocVal()
    {
        return docVal;
    }
    __property void set_DocVal(mshtml::HTMLDocument* val)
    {
        docVal = (val);
    } 
    	
  • The following is the syntax to access the control from an HTML page:
    <OBJECT id="theId" classid="YourControl.dll#NameSpace.NameOfControl">
    </OBJECT>
Back to the top

REFERENCES

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

311299 PRB: Cannot retrieve top-level IWebBrowser2 interface from a .NET UserControl

For more information about how to develop Web-based solutions for Internet Explorer, visit the following Microsoft Developer Network (MSDN) Web sites:

Back to the top

Modification Type:MajorLast Reviewed:4/21/2006
Keywords:kbdownload kbSecurity kbAuthentication kbHOWTOmaster KB815727 kbAudDeveloper