how to make it COM visible?

694 views
Skip to first unread message

LEo

unread,
Sep 13, 2007, 12:25:42 PM9/13/07
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
I'm trying to create an ActiveX Control on C#.NET. I just followed the
instructions on:
http://www.codeproject.com/cs/miscctrl/exposingdotnetcontrols.asp
It did work... I could compile and use the ActiveX on a web page...
but... I cannot use it on another Visual Studio Project nor on another
development application I've got here... Well, when I compile the
project I got several warnings like the one bellow:

C:\WINDOWS\Microsoft.NET\Framework
\v2.0.50727\Microsoft.Common.targets : warning : Type library exporter
warning processing 'Ottimah.myActiveXControl.get_Anchor(#0),
myActiveXControl'. Warning: Non COM visible value type
'System.Windows.Forms.AnchorStyles' is being referenced either from
the type currently being exported or from one of its base types.

I guess the control I created should follow OLE Control and Control
Container Guidelines, but it does not (at least not all of them). I
guess I've got to make some properties and methods of my class
ComVisible in order to avoid those warnings. Since my class is in fact
an inherited class from UserControl, what should I do?
If I were creating my own methods I guess I should do as bellow:

[ComVisible(true)]
public int MyMethod(string param)
{
return 0;
}

[ComVisible(true)]
public int MyProperty
{
get
{
return MyProperty;
}
}

But they are already created on the Parent Class... Is there a way to
set them as ComVisible? Will it solve my problem?

[]'s
LEo

Andrew Badera

unread,
Sep 13, 2007, 12:44:49 PM9/13/07
to DotNetDe...@googlegroups.com
Leo-

I'm pretty certain either an entire class, or entire assembly, needs to be set COMVisible(true) ... I don't think you can dial it down to methods or properties ... but I could be wrong. Also, don't forget you'll need a GUID generated for visibility ...

--Andrew Badera

LEo

unread,
Sep 13, 2007, 1:05:30 PM9/13/07
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
Well, I tried it...
I've made the class declaration this way:
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public partial class myActiveXControl : UserControl
But it didn't work... :(

[]'s
LEo

Andrew Badera

unread,
Sep 14, 2007, 7:36:08 AM9/14/07
to DotNetDe...@googlegroups.com
And you've generated and attributed a GUID for COM as well?

LEo

unread,
Sep 14, 2007, 8:33:38 AM9/14/07
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
yes...
in AssemblyInfo.cs I've got the line for GUID, like this
[assembly: Guid("a7259dde-3525-4617-b7c7-5911dee03483")]

LEo

unread,
Sep 21, 2007, 8:46:28 AM9/21/07
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
As I haven's solved the problem, here are what I've done...
Let's see if someone can make it work properly...

1. I've created a Windows Control Library project in .NET
2. In the project properties, it is important to set it (under the
build tag) to register for COM interop.
3. in the end follows the code for my file UserControl1.cs (note: I've
excluded the designer.cs file)
4. I've built the solution... and there were no errors... but there
are a few warnings like:
Warning 1 Type library exporter warning processing
'mySimpleActiveXControl.UserControl1.get_Anchor(#0),
mySimpleActiveXControl'. Warning: Non COM visible value type


'System.Windows.Forms.AnchorStyles' is being referenced either from
the type currently being exported or from one of its base types.

mySimpleActiveXControl
5. I run Microsoft ActiveX Control Pad and add the control I've just
created.
6. Save the html file and open it on IE. It's gonna work fine
7. Then I try to use it in .NET... I've tried to add a reference to
the COM control I've created and I get the error message:
A reference to 'mySimpleActiveXControl' could not be added.
The ActiveX type library 'D:\mySimpleActiveXControl\bin\Debug
\mySimpleActiveXControl.tlb' was exported from a .NET assembly and
cannot be added as a reference.
Add a reference to the .NET assembly instead.

What should I do to use this ActiveX both on html page and Windows
Form Applications?

[]'s
LEo
here goes the code
>>>>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
// required for COM interoperability features
using System.Runtime.InteropServices;

using System.Reflection;
using Microsoft.Win32;

// exposes events to the outside world through COM
[assembly: ClassInterface(ClassInterfaceType.AutoDual)]
namespace mySimpleActiveXControl
{
[ProgId("mySimpleActiveXControl.UserControl1")]
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}

#region (Un)Register Function
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I
don't need it
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");

// Open the CLSID\{guid} key for write access
RegistryKey k =
Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

// And create the 'Control' key - this allows it to show
up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();

// Next create the CodeBase entry - needed if not string
named and GACced.
RegistryKey inprocServer32 =
k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase",
Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();

// Finally close the main key
k.Close();
}

[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");

// Open HKCR\CLSID\{guid} for write access
RegistryKey k =
Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

// Delete the 'Control' key, but don't throw an exception
if it does not exist
k.DeleteSubKey("Control", false);

// Next open up InprocServer32
RegistryKey inprocServer32 =
k.OpenSubKey("InprocServer32", true);

// And delete the CodeBase key, again not throwing if
missing
k.DeleteSubKey("CodeBase", false);

// Finally close the main key
k.Close();
}
#endregion


#region Design Code


/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should
be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Component Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(23, 51);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(99, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "Hello World!";
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.textBox1);
this.Name = "UserControl1";
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.TextBox textBox1;

#endregion

Reply all
Reply to author
Forward
0 new messages