Microsoft KB Archive/815727

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

Article ID: 815727

Article Last Modified on 4/21/2006

-

APPLIES TO


 * Microsoft Visual C++ 2005 Express Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition
 * 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
 * Requirements
 * Download the UserControl control
 * About UserControl
 * Run the sample
 * Technical notes
 * REFERENCES



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:

Download 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&quot;&quot;; String* tagName = S&quot;&quot;; 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&quot;Untitled Document&quot;; }

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&quot;OBJECT&quot;, TNode, S&quot;ActiveX Controls&quot;); DocCollection(iDoc, S&quot;A&quot;, TNode, S&quot;Anchors&quot;); DocCollection(iDoc, S&quot;IMG&quot;, TNode, S&quot;Images&quot;); DocCollection(iDoc, S&quot;&quot;, TNode, S&quot;All&quot;); // 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(objNextFrame);

// Get the HTMLDocument object mshtml::HTMLDocument* objDoc = __try_cast(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   Properties.

Note  is a placeholder for the name of the project.
 * 1) Expand Configuration Properties, and then click General.
 * 2) 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( __try_cast(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&quot;&quot; || String::Compare(str,iMatchTag)== 0) {               Name = S&quot;&quot;; if (String::Compare(str,S&quot;IMG&quot;)== 0 || String::Compare(str,S&quot;A&quot;)== 0) {                   Name = __try_cast(__try_cast(iDoc->get_all->item(objNum,nullObject))->get_href); }               if (String::Compare(str,S&quot;OBJECT&quot;)== 0) {                   Name = __try_cast(__try_cast(iDoc->get_all->item(objNum,nullObject))->get_id); }               Name = String::Concat(str,S&quot; &quot;, 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  on a local intranet, follow these steps.

Note 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://, and then locate http:// /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:// /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://, and then locate http:// /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: \Microsoft.NET\Primary Interop, where   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.</li>  .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); }    </li>  The following is the syntax to access the control from an HTML page: <OBJECT id=&quot;theId&quot; classid=&quot;YourControl.dll#NameSpace.NameOfControl&quot;> </OBJECT> </li></ul>

Back to the top

<div class="references_section">