Microsoft Knowledge Base Email Alertz

(815727) - Describes how to develop a control library by using Microsoft Visual C++ .NET 2003 and how to access the methods from Internet Explorer script.

Search KbAlertz

Advanced Search

Receive Microsoft Knowledge Base articles by E-Mail?

Every night we scan the Microsoft Knowledge Base. If technologies you're interested in are updated, we'll send you an e-mail. You only get one e-mail a day, and only when new articles are added.

Click here to create a
FREE account
Already have an account?
[Click here to Login]











Microsoft Knowledge Base Article

This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks

Article ID: 815727 - Last Review: April 21, 2006 - Revision: 3.1

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

On This Page

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.

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

Download the UserControl control

The following file is available for download from the Microsoft Download Center:
Collapse this imageExpand this image
Download
Download the VCNetCtrl.exe package now. (http://download.microsoft.com/download/0/4/c/04c9e602-d415-4181-bba6-15c2e9cd55bd/vcnetctrl.exe) 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  (http://kbalertz.com/Feedback.aspx?kbNumber=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 (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.

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.

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>

REFERENCES

For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
311299  (http://kbalertz.com/Feedback.aspx?kbNumber=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:
http://msdn.microsoft.com/ie (http://msdn.microsoft.com/ie)

APPLIES TO
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft .NET Framework 1.1
Keywords: 
kbdownload kbsecurity kbauthentication kbhowtomaster KB815727
       

Community Feedback System

Very often, it takes hours to solve a problem. Very often, you've looked high and low, and have tried a lot of solutions. When you finally found it, chances are, it was because someone else helped you. Here's your chance to give back. Use our community feedback tool to let others know what worked for you and what didn't.

Please also understand that the community feedback system is not warranted to be correct, it's simply a system that we've built to let people try and help each other. If something in a feedback response doesn't make sense to you, or you're not comfortable making changes that the feedback talks about (like registry edits), please consult a professional.

Thank you for using kbAlertz.com Feedback System.

-- Scott Cate