4

我正在尝试将 winform 用户控件注册为 COM 服务器,以便我的 MFC 应用程序可以使用它们。winform 控件是用 C++/CLI 编写的,并使用非托管本机 dll。我想利用 .net 出色的互操作服务将此用户控件注册为 COM 服务器。

[ProgId("MyAx.MyAxControl")]    
[ClassInterface(ClassInterfaceType::AutoDual)]
[Guid("612EAF58-ADCC-4e87-BC9E-FA208B037414")]
public ref class MyAxControl: public System::Windows::Forms::UserControl

MSDN说我可以使用regasm来实现我正在做的事情,所以我继续注册它

regasm MyAx.dll /tlb:MyAx.tlb

我什至生成了一个注册表项

regasm MyAx.dll /regfile:MyAx.reg

并将其与我的注册表合并

在这一点上,我预计当我为工具箱选择项目时,此控件将显示在我的 COM 组件中。然而它并没有出现在那里。这是预期的行为吗?如果是,我将如何在我的 MFC 应用程序中使用此控件,因为任何使用 Activex 控件的语言(比如 Java)。

4

1 回答 1

1

您缺少的是告诉系统您的 COM 对象是一个控件。缺少的信息是注册表中的“已实施类别”条目。要在向 COM 注册期间提供此信息,因此您需要创建自定义 COM(取消)注册功能。

private const string ControlsCategoryId = "{40FC6ED4-2438-11CF-A3DB-080036F12502}";

[ComRegisterFunction]
internal static void ComRegister(string key)
{
    key = key.Replace("HKEY_CLASSES_ROOT\\", "");
    RegistryKey reg = Registry.ClassesRoot.CreateSubKey(key);
    reg.SetValue("", "Your.ProgId.Here");
    reg = reg.CreateSubKey("Implemented Categories");
    reg.CreateSubKey(ControlsCategoryId);
}

[ComUnregisterFunction]
internal static void ComUnregisterFunction(string key)
{
    key = key.Replace("HKEY_CLASSES_ROOT\\", "");
    RegistryKey reg = Registry.ClassesRoot.OpenSubKey(key, true);
    reg = reg.OpenSubKey("Implemented Categories", true);
    reg.DeleteSubKey(ControlsCategoryId);
}

Com (un)registration 例程必须是静态的、返回 void、接受单个字符串或 Type 参数,并具有适当的属性。MSDN 现在声称只接受 Type 参数,但出于兼容性原因,字符串版本(从 1.1 版开始)也可以使用。传递给此函数的字符串是注册表项 HKCR\CLSID{YOUR-CLASS_GUID}。

希望有帮助。

于 2009-11-03T22:50:28.810 回答