Проблемы с ActiveX control написанного на C#
От: vladislav.tsyryuk Россия  
Дата: 02.03.06 10:31
Оценка:
Привет всем!
Написал на 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

  }
}
Проблемы с ActiveX control написанного на C#
От: Аноним  
Дата: 02.03.06 11:09
Оценка:
> Написал на C# ActiveX control. Мне нужно чтобы этот ActiveX генерил событие наружу в определенной ситуации, например по таймеру.

см. http://www.gotdotnet.ru/Forums/Web/127278.aspx


---
см.: TaskRunner, PopupWindow, Html2XmlConverter, Win32ResourceManager, MenuBuilder, Lens .


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Проблемы с ActiveX control написанного на C#
От: vladislav.tsyryuk Россия  
Дата: 02.03.06 13:53
Оценка:
Это то я читал, только дело в том, что это для эксплорера работает и только, а вот для VB6 уже нет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.