Hosting Windows Forms Controls in COM Control Containers
by Chris Sells01/20/2003
As wonderful as the new Windows Forms control model is, if you still need to host controls in COM control containers, you are limited to exactly one control host that also supports the hosting of Windows Forms controls: Internet Explorer. However, if you're brave and can stand the heat from the kitchen, you may have some luck hosting Windows Forms controls in other COM control hosts, including VB6, Office, ATL, and MFC. Since a Windows Forms control implements COM control interfaces and behavior, this can be made to at least seem to work (although it is not supported by Microsoft, even a little bit).
The first step to enabling hosting of a Windows Forms control in a COM control host is to set Project->Properties->Configuration Properties->Build->Register for COM Interop to true on your VS.NET Windows Forms control project. When the project is built, this setting will cause most of the COM registration entries to be added, as shown in Figure 1.
![]() |
| Figure 1: Base COM interop settings |
In addition, the Register for COM Interop setting will cause a COM type library
to be created and registered. This is the equivalent of using the tlbexp.exe
and regasm.exe tools from the command line, but is automatically handled as part
of the build in VS.NET. These keys are enough to support CoCreateInstance from
C++ or New from VB6, but they're not enough to support COM control creation.
Enabling that requires four more keys, as is shown in Figure 2.
![]() |
| Figure 2: Minimum COM Control interop settings |
The Control sub-key marks the COM class as a COM control for MFC's Insert ActiveX Control dialog. The MiscStatus is a set of bits from the OLEMISC enumeration. A value of 131457 works well (see the References section for more information about these bits). The TypeLib key and Version keys point to the COM type library exported by the VS.NET build when Register for COM Interop is set to true.
Getting these keys into the Registry requires some additional work, as the Register for COM Interop setting in VS.NET won't do it for you. Instead of adding these keys by hand, or even writing a .reg file or an installer to do it, I recommend adding a ComRegister function to your Windows Forms control class:
using System.Runtime.InteropServices; // COM attributes
using Microsoft.Win32; // RegistryKey
namespace WindowsControlLibrary1 {
// Stops control from getting a new CLSID
// at each registration
[Guid("E73CD054-1247-4853-AF05-B7D26D993E85")]
public class UserControl1 : UserControl {
...
[ComRegisterFunction]
static void ComRegister(Type t) {
string keyName = @"CLSID\" + t.GUID.ToString("B");
using( RegistryKey key =
Registry.ClassesRoot.OpenSubKey(keyName, true) ) {
key.CreateSubKey("Control").Close();
using( RegistryKey subkey = key.CreateSubKey("MiscStatus") ) {
subkey.SetValue("", "131457");
}
using( RegistryKey subkey = key.CreateSubKey("TypeLib") ) {
Guid libid = Marshal.GetTypeLibGuidForAssembly(t.Assembly);
subkey.SetValue("", libid.ToString("B"));
}
using( RegistryKey subkey = key.CreateSubKey("Version") ) {
Version ver = t.Assembly.GetName().Version;
string version =
string.Format("{0}.{1}",
ver.Major,
ver.Minor);
if( version == "0.0" ) version = "1.0";
subkey.SetValue("", version);
}
}
}
[ComUnregisterFunction]
static void ComUnregister(Type t) {
// Delete entire CLSID\{clsid} subtree
string keyName = @"CLSID\" + t.GUID.ToString("B");
Registry.ClassesRoot.DeleteSubKeyTree(keyName);
}
}
}
A static function with the appropriate signature and marked with the ComRegisterFunction
attribute will be called as part of the COM registration process for a .NET
class. Likewise, a function marked ComUnregistrationFunction will be called
when the class is unregistered. This allows you to write the code that adds
the keys necessary to make the WinForm control act like a COM control. Once
this code is added and your Windows Forms control is built (and registered for COM
interop), you can use the Windows Forms control as a COM control. For example, to
host the Windows Forms control in an MFC application, right-click on a dialog in
design mode and choose Insert ActiveX Control, choosing your Windows Forms control
by namespace and class name, e.g. WindowsControlLibrary1.UserControl1.
Where Are We?
I cannot stress enough just how unsupported this technique is. My understanding is that the Windows Forms team spent all of their energy testing that Windows Forms controls work in supported ways for supported Windows Forms and COM Control hosts, and in no other ways in other hosts. The fact that these Registry tricks seem to work is probably just an illusion for the unwary. However, if you need to play with fire, at least I've helped you to learn how to properly light the match.
Chris Sells is an independent consultant specializing in .NET.
Return to ONDotnet.com
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 23 of 23.
-
How to use SAP COM Object In Dot.Net 2005 Development Studio
2007-09-19 05:29:00 Padamgonde [Reply | View]
-
Cannot update label.Text value in ActiveX Dot Net?
2006-08-02 21:21:36 HaDV [Reply | View]
I write an ActiveX containing a progressbar and a label by C#. But when ruuning it from IE; the progressbar is OK, but the label's Text cannot be updated. Following is the code:
for (int i=1; i <= totalFile; i++)
{
Thread.Sleep(this.SleepTime);
completedFile += 1;
lblProgress.Text = String.Format("{0} / {1}", completedFile, totalFile);
progressBar.PerformStep();
}
Plz explain this problem for me.
thanks,
HaDV
-
VS2005 has changed a little
2006-08-02 00:20:00 thinktwice [Reply | View]
i should set Make com-visible to true to achieve this.btw how to do it in VC2005 CONTROL LIBRARY PROJECT?
-
Ole Initialization failed
2006-03-27 05:07:18 uggla [Reply | View]
When I follow the example in the article, using VS 2005 and hence .Net 2.0, I run into trouble.
Anyone got this to work in VS 2005?
Regards /Dan
-
Expose Events
2006-02-09 18:12:36 EricDy [Reply | View]
How could I expose events to the VB Form container?
-
Anybody solved problem with textbox control?
2005-10-11 10:03:17 R_PR [Reply | View]
I tried to use textbox controls in a "form" in MS Word Task Pane, but I have a problem with textboxes - they did not allow keyboard input. I saw message with the same problem dated by 2003. Did someone solve it already?
Regards,
Roman
-
Running UserControl in separate process
2005-02-15 09:08:59 KennethF [Reply | View]
Has anyone tried to run a usercontrol in a com container as a separate process? Not in the com's process? Thanks for any info.
-
Arrow keys don't work when hosted in Usercontrol
2005-01-31 23:41:30 DavidSmith [Reply | View]
When the dotnet usercontrol is loaded on a VB6 form things seem to work, but when it is loaded inside a VB6 usercontrol arrow keys stop working. It seems like they are treated as tabs even if focus is on a textbox or listview.
-
Tried it in .NET 2003,(Framework 1.1) faced problems
2003-11-10 05:42:52 anonymous2 [Reply | View]
Hi,
I tried the ComRegister/UnRegister functions to use a C# user control as an ActiveX control in an ATL Com client.
It worked perfectly fine with .NET 2002/Framework 1.0.
I recently upgraded to 2003/ Framework 1.1.
When the user tries to close the application with the focus still on the ActiveX control, it hangs.
This occurs only when there are other control(s)(dialog controls) also on the ATL Dialog.
Can you help me out to resolve this????
Thanks.
-
Context Menu
2003-10-08 07:51:57 anonymous2 [Reply | View]
I've to host a windows forms control in Excel, and following the COMRegisterFunction and COMUNRegisterFunction I got it to work. The control inserts fine and also works ok including the context menu upon insert. But when I save and close the workbook and open it back the control draws correctly, but the context menu no longer works. I'm associated a ContextMenu to the .net usercontrol. Am I doing something wrong??
Thanks.
-
Implementing Input Interface
2003-09-08 15:48:26 anonymous2 [Reply | View]
I had no problem getting this to work and am able to get my custom control to display in a COM application (Word taskpane). However, I cannot edit the text in the textboxes, even though I can tab between them and click the buttons. Any ideas on how to get the textboxes to accept input?
thanks
-
For more information...
2003-06-23 05:30:17 anonymous2 [Reply | View]
If you are really interested in doing this, there's not quite enough information in this article to pull it off. I would recommend reading the following link from Codeproject.com: http://www.codeproject.com/cs/miscctrl/exposingdotnetcontrols.asp
If you use the techniques outlined in the CodeProject article with Chris Sell's ComRegisterFunction/ComUnregisterFunction code you should be off and running!
Some important things to remember are:
1) Use the ComRegister/Unregister stuff!
2) Make sure to generate your assembly with a strong name and add it to the global assembly cache (gacutil /i)
3) I find I need to add the [ClassInterface(ClassInterfaceType.AutoDual)] attribute to my control for it to work.
-
For more information...
2003-07-29 12:18:33 anonymous2 [Reply | View]
I got this approach to work, even loading the control in Excel. The problem is, it won't resize the way we expect ole objects to in office. I'm sure it requires some interface implementation or something only an ATL person would know, but I can't seem to find any info on it. Anyone have any ideas?
-
unsupported
2003-06-16 10:20:04 anonymous2 [Reply | View]
Ian, Have you tried it within an MS Office document?
Bill
-
Interesting But Gives Me Not A Clue
2003-06-01 09:08:55 anonymous2 [Reply | View]
as to how to reduce my content in D drive (system disk) ..I need to delete or transfer but have no idea how to do so after being attacked by hackers who wanted to ruin my computer because of my web page.
Well I'm back now..and I'm on the offensive.
So look out you hoodwinks..I'm on to you..I accept no spam from anyone, not even my friends.
Bill, How about an Icon for return to sender..PLEASE!!!
-
need help with the example!!!
2003-06-01 05:55:24 anonymous2 [Reply | View]
tried the example
1. register it from the IDE to support interop
2. added the code to the control and it did not work.
please make it more clear
thanks
Avi
-
install 1.1
2003-03-27 08:58:06 jtmi [Reply | View]
If you install the final beta 1.1 of the framework, you will not get those annoying "Out of memory" or "Device I/O error" when you try to run,compile or save a VB6 form using a .NET control. (Seems MS got a point with this side-by-side execution of the framework)
-
Try install .NET Framework v1.1
2003-03-27 08:54:07 anonymous2 [Reply | View]
If you install the final beta 1.1 of the framework, you will not get those annoying "Out of memory" or "Device I/O error" when you try to run,compile or save a VB6 form using a .NET control. (Seems MS got a point with this side-by-side execution of the framework)
-
help needed
2003-02-20 07:33:58 anonymous2 [Reply | View]
Tried the sample, it did not work!!!!!!!!!!
-
Example?
2003-02-06 02:43:21 quindennis [Reply | View]
I could use an example. I created a UserControl derived control and did nothing but change its background color. With the modifications suggested, it built and successfully registers as a COM ActiveX object. When I place it on a VB6 Form, it paints fine, but when I run the project, VB6 says "Out of Memory", then twice more when I close the project. When I place it on a UserForm in MSWord VBA, it says "Device I/O Error". This is so close, I must be missing something.
Any help greatly appreciated.
-
Example
2003-02-06 02:42:43 quindennis [Reply | View]
I could use an example. I created a UserControl derived control and did nothing but change its background color. With the modifications suggested, it built and successfully registers as a COM ActiveX object. When I place it on a VB6 Form, it paints fine, but when I run the project, VB6 says "Out of Memory", then twice more when I close the project. When I place it on a UserForm in MSWord VBA, it says "Device I/O Error". This is so close, I must be missing something.
Any help greatly appreciated.
-
Groove Workspace's new VS.Net support includes hosting WinForms
2003-01-27 13:17:03 anonymous2 [Reply | View]
I don't know of they use the above technique or something else (Groove Networks has a close relationship with Microsoft) but it allows VS.Net to be used to design Groove tools (for customers who have installed the .Net Framework/CKR on their client machines).
Michael.
-
unsupported
2003-01-22 17:59:58 anonymous2 [Reply | View]
Chris,
It is true that this approach is unsupported. However I have successfully used it with a number of different hosts includeing vb and c++ code and even visual studio via VSIP. Some of this is even production code. I think that the reason its unsupported is to avoid having the support burden not because the team thought that it wouldn't work.
Ian MacLean








So please send me the solutions for that