Hosting Windows Forms Controls in ActiveX Control Containers

team lib

Windows Forms controls are the .NET equivalent of ActiveX controls: self- contained components , normally with a user interface, that implement the right architecture for plugging into a suitable container. In the case of Windows Forms controls, the container is a Windows Forms form; in the case of an ActiveX control, the container will be an ActiveX container. Given that the two types of components are performing the same logical task, you might want to use them interchangeably. Interoperation is possible but only to a limited extent, as explained below.

Windows Forms controls can be used as ActiveX controls, but they might not work in all ActiveX containers. Being an ActiveX container is not a binary either-or matter, and some containers might not implement all the functionality that it is possible to provide. For this reason, the wrapper that lets Windows Forms controls work as ActiveX controls is designed to work with Internet Explorer. Internet Explorer is not yet a .NET application, but it needs to be able to host Windows Forms controls seamlessly; hence, the built-in support. This means that if you export a .NET control, youll be able to use it on a Web page in Internet Explorer, but it might not work in other ActiveX containers, such as Visual Basic 6. It might work correctly, but Microsoft gives no guarantees .

Registry Entries

To export a Windows Forms control to work in a container other than Internet Explorer, youll need to add extra registry entries, as explained in the following paragraphs.

Identifying a Control

ActiveX controls are identified in the registry in two ways. The older way, which dates from the days when a COM component was either an ActiveX control or a plain component, is to add a Control subkey to the CLSID for the Windows Forms control. As the capabilities of COM components got more complex, the Implemented Categories key was introduced to list the categories to which a component belonged. Implemented Categories is a subkey of the controls CLSID, and it has subkeys that identify the capabilities of the component. For ActiveX controls, the subkey you need to add has the name {40FC6ED4-2438-11CF-A3DB-080036F12502} . This GUID is known as CATID_Control , and unfortunately you have to use the GUID itself rather than its name. You might need to identify a control using both of these methods , although older containers will need only the first entry.

Type Library Entries

The type library for the exported control needs to be registered, and the TypeLib subkey of CLSID must be set to refer to the library GUID. A Version subkey needs to be added to the controls CLSID entry, and its value should be set to the version number of the exported type library.

Miscellaneous Entries

The control CLSID key should have a subkey called MiscStatus , which holds the OLE Miscellaneous Status Bits . These bits comprise a collection of flags that detail the capabilities of embeddable COM components, and you OR members of the Windows OLEMISC structure together to obtain the value you want. The members of the structure are shown in the following listing:


Many of the possible values are inapplicable to Windows Forms controls, so it wouldnt be useful to explain the entire structure here. A sensible set of values to OR together comprises OLEMISC_INSIDEOUT , OLEMISC_RECOMPOSEONRESIZE , OLEMISC_ACTIVATEWHENVISIBLE , and OLEMISC_SETCLIENTSITEFIRST , which gives a value of 131457.

Example: Hosting a Windows Forms Control in Internet Explorer

This section shows you how a simple Windows Forms control can be used in Internet Explorer. The control is called TimeBox, a simple compound control that combines a text box with a button. The user is supposed to enter a time into the control in the format hh:mm:ss. Pressing the button to the right of the control will insert the current time. Listing 4-4 contains the Visual C# code. You can find this sample in the Chapter04\TimeBox folder in the books companion content.

Listing 4-4: TimeBox.cs
start example
 usingSystem; usingSystem.Collections; usingSystem.ComponentModel; usingSystem.Drawing; usingSystem.Data; usingSystem.Windows.Forms; namespaceTimeBox { publicclassTimeBox:System.Windows.Forms.UserControl { privateSystem.Windows.Forms.TextBoxtextBox1; privateSystem.Windows.Forms.Buttonbutton1; ///<summary> ///Requireddesignervariable. ///</summary> privateSystem.ComponentModel.Containercomponents=null; publicUserControl1() { //ThiscallisrequiredbytheWindows.FormsFormDesigner. InitializeComponent(); //TODO:AddanyinitializationaftertheInitComponentcall } ///<summary> ///Cleanupanyresourcesbeingused. ///</summary> protectedoverridevoidDispose(booldisposing) { if(disposing) { if(components!=null) components.Dispose(); } base.Dispose(disposing); } #regionComponentDesignergeneratedcode ///<summary> ///RequiredmethodforDesignersupport-donotmodify ///thecontentsofthismethodwiththecodeeditor. ///</summary> privatevoidInitializeComponent() { this.textBox1=newSystem.Windows.Forms.TextBox(); this.button1=newSystem.Windows.Forms.Button(); this.SuspendLayout(); // //textBox1 // this.textBox1.Location=newSystem.Drawing.Point(8,8); this.textBox1.Name= "textBox1"; this.textBox1.Size=newSystem.Drawing.Size(176,20); this.textBox1.TabIndex=0; this.textBox1.Text= ""; // //button1 // this.button1.Location=newSystem.Drawing.Point(192,8); this.button1.Name= "button1"; this.button1.Size=newSystem.Drawing.Size(24,23); this.button1.TabIndex=1; this.button1.Text= "..."; this.button1.Click+=newSystem.EventHandler(this.button1_Click); // //UserControl1 // this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.Name= "UserControl1"; this.Size=newSystem.Drawing.Size(224,40); this.ResumeLayout(false); } #endregion //Propertytoreturnthetimeasastring publicstringTime{ get{ returntextBox1.Text; } } privatevoidbutton1_Click(objectsender,System.EventArgse){ //putsthetimeintothetextbox DateTimedt=DateTime.Now; textBox1.Text=dt.Hour.ToString()+ ":"  +dt.Minute.ToString()+ ":"  +dt.Second.ToString(); } } } 
end example

No special processing is needed to use a Windows Forms control with Internet Explorer. When using .NET components with other programs, youve seen how you need to create a type library to represent the component as a COM object. The aim is to let Windows Forms controls be used in Internet Explorer just as easily as ActiveX controls, so Internet Explorer itself will create an appropriate CCW when it loads the HTML page.

To use this control with Internet Explorer, place an < object > tag within the HTML.

 <objectid="TimeBox1" classid="http:TimeBox.dll#TimeBox.TimeBox"height="300" width="500" VIEWASTEXT> </object> 

Note the form of the classid attribute specified for the control. This isnt the traditional COM CLSID you usually provide for an ActiveX control. Since Internet Explorer knows about .NET assemblies and how to generate wrappers, the Uniform Resource Identifier (URI) specifies the name of the assembly DLL, a pound sign, and the fully qualified name of the control class. Internet Explorer will use this URI to locate the assembly and automatically generate a CCW for the TimeBox class.


The < object > tag provides a way to embed ActiveX controls and Java applets in HTML pages. For ActiveX controls, the classid parameter provides the CLSID (class ID) for the ActiveX control; if this control is registered on the machine where Microsoft Internet Explorer is being run, an instance will be created using the installed DLL. If the control is not installed, the DLL will be downloaded from the server, and temporarily installed on the client machine.

team lib

COM Programming with Microsoft .NET
COM Programming with Microsoft .NET
ISBN: 0735618755
EAN: 2147483647
Year: 2006
Pages: 140

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: