Problem with ActiveX control event mechanism

V

vtsyryuk

Hi, all!
I wrote an ActiveX UserControl in C# language. My problem is write a
Managed Server as the event source and for example write a COM Client
as the event sink. The managed server declares "SampleEvents" as an
event
sink interface and connects the interface to the "SampleControl" class.

The unmanaged client creates an instance of the "SampleControl" class
and
implements the event sink interface ( VB.6 client for example). I have
no problem if I wrote simple class library in c# ( ActiveX ) like in
http://msdn.microsoft.com/library/d...e/html/cpconRaisingEventsHandledByCOMSink.asp
msdn article, but when I made a UserControl from this class library the

unmanaged client can't see event interface ( handle of event can't
register ), in VB6 I have 459 error, that means "This component doesn't

support the set of events"
http://msdn.microsoft.com/library/d...benlr98/html/vamsgobjdoesnotsupportevents.asp).

My client is simple: In VB6 I create a standart exe project with form
on wich I place my .NET ActiveX control with event interface. After
that I wrote a simple handle of control event that generated for
example by timer ( even second ).
Below are my server code (C#) that is simple control with TextBox and
two methods: GetText and SetText.

Managed server (event source)
[C#]
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace ActiveX
{
[Guid("C5365803-25EE-4ebc-883B-DB20A4072400"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)]
public interface ISampleEvents
{
[DispIdAttribute(1)]
void SomeEvent();
};

[Guid("D4F3706D-A238-4216-BA45-1C11255A7F44"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)]
public interface ISampleControl
{
[DispId(1)]
void SetText( string s );
[DispId(2)]
String GetText();
[DispId(3)]
void OnSomeEvent();
};
[Guid("000C9F0F-48C1-4642-879A-28C7B1ABDDBD"),
ClassInterface(ClassInterfaceType.None),
ProgId("ActiveX.SampleControl"),
ComSourceInterfaces(typeof(ISampleEvents)), ]

public class SampleControl : UserControl, ISampleControl
{
public delegate void SomeEventDelegate();
public event SomeEventDelegate SomeEvent = null;
public void OnSomeEvent()
{
try
{
if( SomeEvent != null )
{
SomeEvent();
textBox1.Text += " SomeEvent called. Method name is " +
SomeEvent.Method.Name;
}
else
{
textBox1.Text += " SomeEvent == null";
}
}
catch( Exception e )
{
MessageBox.Show( "My exception:" + e.Message );
}
}

private void timer1_Tick(object sender, System.EventArgs e)
{
this.OnSomeEvent();
}
<!-------- below are standart design component code and [un]register
ActiveX functions ---->

private TextBox textBox1;
private Timer timer1;
private IContainer components = null;

public SampleControl()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

#region Component Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.textBox1 = new System.Windows.Forms.TextBox();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// textBox1
//
this.textBox1.AutoSize = false;
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(208, 208);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 3000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// SampleControl
//
this.Controls.Add(this.textBox1);
this.Name = "SampleControl";
this.Size = new System.Drawing.Size(208, 208);
this.ResumeLayout(false);

}
#endregion

#region [Un]Register Class for COM Interop
[ComRegisterFunction()]
public static void AxRegisterClass( 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 rk =
Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// Next create the CodeBase entry - needed if not string named
and GACced.
RegistryKey inprocServer32 = rk.OpenSubKey("InprocServer32",
true);
inprocServer32.SetValue("",
"C:\\WINDOWS\\system32\\mscoree.dll");
inprocServer32.Close() ;

// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
rk.CreateSubKey("Control");
rk.CreateSubKey("Insertable");
rk.CreateSubKey("Programmable");
rk.CreateSubKey("TypeLib").SetValue("",
"{09CC5676-60CB-41bf-B405-09F205845EC4}");
rk.CreateSubKey("Version").SetValue("", "1.0");

// Finally close the main key
rk.Close();
}
[ComUnregisterFunction()]
public static void AxUnregisterClass( 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 rk =
Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// Delete the 'Control' key, but don't throw an exception if it
does not exist
rk.DeleteSubKey("Control", false);
rk.DeleteSubKeyTree("InprocServer32");
rk.DeleteSubKey("Insertable");
rk.DeleteSubKey("Programmable", false);
rk.DeleteSubKey("TypeLib", false);
rk.DeleteSubKey("Version", false);

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

#region ISampleControl Members
public void SetText( string s )
{
textBox1.Text = s;
}

public String GetText()
{
return textBox1.Text;
}

#endregion

}
}
}


Also I tested my ActiveX control with TestContainer and it is intrested

that event "SomeEvent" happened by timer, may be anyone knows what's
problem?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top