Microsoft KB Archive/816165

= How to sink managed Visual C++ .NET or Visual C++ 2005 events in Internet Explorer script =

Article ID: 816165

Article Last Modified on 5/17/2007

-

APPLIES TO


 * Microsoft Visual C++ .NET 2003 Standard Edition
 * Microsoft .NET Framework 1.1
 * Microsoft Visual C++ 2005 Express Edition

-







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



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

This article refers to the following Microsoft .NET Framework Class Library namespaces:
 * System::Runtime::InteropServices
 * System::ComponentModel



SUMMARY
This article describes how to sink Managed Visual C++ .NET or Visual C++ 2005 events in Microsoft Internet Explorer scripts. To do this, create a Windows Control Library (.NET) project, and then sink the managed control event in an Internet Explorer script.

IN THIS TASK

 * INTRODUCTION
 * Requirements
 * Sink a managed event in an Internet Explorer script
 * Complete code listing
 * REFERENCES



INTRODUCTION
This step-by-step article describes how to sink managed events from Component Object Model (COM) clients that use unmanaged code when you write Microsoft Visual Studio .NET or Microsoft Visual Studio 2005 Windows controls. For example, you sink managed events from COM clients when you run a script in Microsoft Internet Explorer.

For information about how to write and how to use managed types from COM, visit the following Microsoft Developer Network (MSDN) Web site:

http://msdn2.microsoft.com/en-us/library/zsfww439(vs.71).aspx

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

Sink a managed event in an Internet Explorer script
To create a .NET control library, and to sink a managed control event in Internet Explorer script, follow these steps:  Start Visual Studio .NET 2003 or Microsoft Visual Studio 2005 . On the File menu, click New, and then click Project. Under Project Types, click Visual C++ Projects, and then click Windows Control Library (.NET) under Templates.

Note In Visual Studio 2005, click Visual C++ under Project Types, and then click Windows Forms Control Library under Templates. In the Name text box, type ControlLib, and then click OK. This creates the ControlLibControl control and opens the control in Design mode. Right-click ControlLibControl, and then click ViewCode.</li>  Add the following code after the using directives in the ControlLibControl.h file: using namespace System::Runtime::InteropServices; </li>  Define a source interface for the events to be exposed. To do this, add the following code inside the ControlLib namespace definition before the ControlLibControl class definition in the ControlLibControl.h file: //Source interface for events to be exposed. public __gc __interface ControlEvents {   void ClickEvent(int x, int y); }; </li>  Add a GuidAttribute attribute to the source interface. You must format the string that you pass to the attribute as an acceptable constructor argument for the Guid type. You can use the Guidgen.exe file to create an unused GUID. To do this, add the following code above the interface that you defined in step 7: [GuidAttribute(&quot;0422D916-C11A-474e-947D-45A107038D14&quot;) ] </li>  Add an InterfaceTypeAttribute attribute to the source interface to expose COM as an IDispatch interface. To do this, add the following code before the source interface definition that you added in step 8 and after the GuidAttribute attribute that you added in step 8: [InterfaceTypeAttribute(ComInterfaceType::InterfaceIsIDispatch)] </li>  Add a DispIdAttribute attribute to any members in the source interface to specify the COM dispatch identifier (DISPID) of a method or a field. To do this, add the following code before the ClickEvent member of the source interface definition that you added in step 8: //Add a DispIdAttribute to any members in the source //interface to specify the COM DispId. [DispIdAttribute(0x60020000)] Your code should appear as follows: [GuidAttribute(&quot;0422D916-C11A-474e-947D-45A107038D14&quot;) ] [InterfaceTypeAttribute(ComInterfaceType::InterfaceIsIDispatch)] //Source interface for events to be exposed. public __gc __interface ControlEvents {   //Add a DisIdAttribute to any members in the source //interface to specify the COM DispId. [DispIdAttribute(0x60020000)] void ClickEvent(int x, int y); }; </li> Create a new event type to wrap the event that you want to expose. To do this, follow these steps: <ol style="list-style-type: lower-alpha;">  Use the __delegate keyword to define a reference type with the same signature to encapsulate the source interface method. To do this, add the following code after the source interface definition in the ControlLib namespace: //define a reference type to encapsulate the interface method public __delegate void ClickEventHandler(int x, int y); </li>  By using the __event keyword, declare a managed event data member of the delegate type in the ControlLibControl class. To do this, add the following code: // declare a delegate type data member as event __event ControlLib::ClickEventHandler *ClickEvent; </li></ol> </li>  Add a ComSourceInterfaces attribute to the control class to identify the list of interfaces that are exposed as COM event sources. To do this, add the following code before the ControlLibControl class definition: //Add a ComSourceInterfaces attribute to the control to //identify the list of interfaces that are exposed as COM event sources. [ClassInterface(ClassInterfaceType::None),ComSourceInterfaces(__typeof(ControlEvents))] </li>  Add a dummy interface, and then implement the dummy interface in the ControlLibControl class. Add the following code before the ControlLibControl class definition in the ControlLib namespace: public __gc __interface MyDummyInterface { }; </li>  To implement the MyDummyInterface interface in the ControlLibControl class, change the definition of the ControlLibControl class as follows: public __gc class ControlLibControl : public System::Windows::Forms::UserControl, public MyDummyInterface </li>  Add the following code to declare a TextBox control member in the ControlLibControl class: System::Windows::Forms::TextBox *tx; </li>  Replace the code in the ControlLibControl class constructor with the following code: InitializeComponent; tx = new System::Windows::Forms::TextBox; initControlLibControl; </li>  Add the following code in the InitializeComponent method: components = new System::ComponentModel::Container; this->Name = S&quot;ControlLibControl&quot;; </li>  Add the following code after the InitializeComponent method in the ControlLibControl class: private: void initControlLibControl {   System::Drawing::Size size(300, 50); Size = size; tx->Text = &quot;Click the TextBox to invoke 'ClickEvent'&quot;; tx->Size = this->Size; tx->Click += new System::EventHandler(this, ClickHandler); this->Controls->Add(tx); } private: void ClickHandler(System::Object * sender, System::EventArgs *e) {   if (ClickEvent != 0) {       ClickEvent(0, 0); } } </li> Press CTRL+SHIFT+B to build the control as a DLL.</li> <li> Create a script block in the HTML to hook the event, and then save the HTML file in the folder that contains the DLL as follows: <!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;> <META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=iso-8859-1' />

<HTML> <HEAD> <TITLE>Sink managed event in Internet Explorer</TITLE> </HEAD> <BODY> <OBJECT id=&quot;ctrl&quot; classid=&quot;ControlLib.dll#ControlLib.ControlLibControl&quot;> </OBJECT> <SCRIPT LANGUAGE=&quot;JScript&quot;> function ctrl::ClickEvent(a,b) {           alert(&quot;ControlLibControl_ClickEvent&quot;); }   </SCRIPT> </BODY> </HTML> </li> <li>On any client system, use the Microsoft .NET Framework Configuration tool (Mscorcfg.msc) to grant the assembly the individual permissions that are required. To do this, follow these steps: <ol style="list-style-type: lower-alpha;"> <li>Start the .NET Framework configuration tool, Mscorcfg.msc.</li> <li>Expand each element in the following path:

My Computer/Runtime Security Policy/Machine/Code Groups/All_Code/LocalIntranet_Zone

</li> <li>Right-click All_Code, and then click New.</li> <li>On the Identify the new Code Group page of the Create Code Group wizard, type Q816165 in the Name box, and then click Next.</li> <li>In the Choose the condition type for this code group list, click URL.</li> <li>Type the URL of the folder in the Web Server that contains the .dll file, and then click Next.</li> <li>Click Use existing permission set, and then click FullTrust.</li> <li>Click Next, and then click Finish.</li></ol> </li> <li>Browse the HTML file that you just created, and then click the Textbox control.

Note You must create a virtual directory in Internet Information Services (IIS) that points to the folder that contains the HTML file and the .dll file, and then look through the HTML file.</li></ol>

Back to the top

Complete code listing

 * 1) pragma once

using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Runtime::InteropServices;

namespace ControlLib {   [GuidAttribute(&quot;0422D916-C11A-474e-947D-45A107038D14&quot;) ] [InterfaceTypeAttribute(ComInterfaceType::InterfaceIsIDispatch)] //Source interface for events to be exposed. public __gc __interface ControlEvents {       //Add a DispIdAttribute to any members in the source //interface to specify the COM DispId. [DispIdAttribute(0x60020000)] void ClickEvent(int x, int y); };

//Define a reference type to encapsulate the interface method. public __delegate void ClickEventHandler(int x, int y); ///    /// Summary for ControlLibControl ///    ///    /// WARNING: If you change the name of this class, you must change the ///         'Resource File Name' property for the managed resource compiler tool ///         associated with all .resx files this class depends on. Otherwise, ///         the designers will not be able to interact correctly with localized ///         resources associated with this form. public __gc __interface MyDummyInterface {   };    //Add a ComSourceInterfaces attribute to the control to     //identify the list of interfaces that are exposed as COM event sources. [ClassInterface(ClassInterfaceType::None),ComSourceInterfaces(__typeof(ControlEvents))] public __gc class ControlLibControl : public System::Windows::Forms::UserControl, public MyDummyInterface {   public: ControlLibControl(void) {           InitializeComponent; tx = new System::Windows::Forms::TextBox; initControlLibControl; }   protected: void Dispose(Boolean disposing) {           if (disposing && components) {               components->Dispose; }           __super::Dispose(disposing); }   private: ///        /// Required designer variable. ///        System::ComponentModel::Container* components; System::Windows::Forms::TextBox *tx; // Declare a delegate type data member as event. __event ControlLib::ClickEventHandler *ClickEvent; ///        /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///        void InitializeComponent(void) {           components = new System::ComponentModel::Container; this->Name = S&quot;ControlLibControl&quot;; }       private: void initControlLibControl {           System::Drawing::Size size(300, 50); Size = size; tx->Text = &quot;Click the TextBox to invoke 'ClickEvent'&quot;; tx->Size = this->Size; tx->Click += new System::EventHandler(this, ClickHandler); this->Controls->Add(tx); }       private: void ClickHandler(System::Object * sender, System::EventArgs *e) {           if (ClickEvent != 0) {               ClickEvent(0, 0); }       }    }; } Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile this code sample. To do this, follow these steps:
 * 1) Click Project, and then click ProjectName Properties.

Note ProjectName represents 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 on the right pane, click Apply, and then click OK.

For more information about the common language runtime support compiler options, visit the following Microsoft Web site:

/clr (Common language runtime compilation)

http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

Back to the top

<div class="references_section">