用C#创建ActiveX问题
这里只对我遇到的问题进行说明及解答,其它请参见MSDN的COM交互:
一、 最好使用自定义的接口。否则很容易导出一些不必要的东西,在编译时还会有一大堆的警告(当从.Net自身的类继承时会出现这种情况,其它情况我没有试。)。
二、 接口中的方法或属性要有DispID属性(否则可能会报“找不到成员”错误,当接口中含有成员时,如果不使用DispID,则该成员有可能不会导出!)。
三、 接口不能将继承的的接口进行公布。如果要公布的接口继承自另一接口,不知为什么其父接口中的内容不会被导出。如果有知道的朋友不妨告知一下。
四、 我曾经想将.Net中的强类型化数据集作为参数或返回值,试验是行不通的。因为只面涉及到了只有.Net才能用的东西如ComponentModel等。
五、 可视化控件整体不显示的问题的解决方法:请指定分别含有下面两个属性的两个方法。
[ComRegisterFunction()]
[ComUnregisterFunction()]
并在注册表中创建或删除“Control”键及设置或删除“Codebase”项的值。如下:
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
k.DeleteSubKey("CodeBase", false);
k.Close();
}
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(@"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
k.DeleteSubKey("CodeBase", false);
k.Close();
}
六、 可视化控件内某些子控件无法显示的问题的解决方法有三种
为控件设置非缺省背景色。
在接口中指定背景色属性(请将alpha值设置为255)。
将窗体设置为支持透明(但在放在Delphi上面时并不透明,只是能够显示完整而已。)
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;