Привет всем!
Написал на C# ActiveX control. Мне нужно чтобы этот ActiveX генерил событие наружу в определенной ситуации, например по таймеру. Необходимый код был мной добавлен, однако использование ActiveX показало что, к примеру в VB6, при добавлении на форму моего активХ и реализации метода-обработчика события механизм event-ов не работает, а именно обратчик не регистрируется в активХ. Ниже приведен код моего активХ, + Важное замечание в тест контейнере данный механизм работает. В чем проблема, что нужно переписать не могу понять, подскажите кто знает!
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();
}
Далее идет часть кода которая относится к регистрации активХ и к тому что генерит Component Designer
Контрол представляет собой юзер контрол с текст боксом. + таймер раз в три секунды срабатывающий, и в его обработчике генерится евент.
Такое ощущение, что проблемы в инициализации контрола, когда ВБ6 хостит его, как подругому он инициализируется, к сожалению механизма не знаю.
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
}
}
Это то я читал, только дело в том, что это для эксплорера работает и только, а вот для VB6 уже нет.