如何使用 MFC 为 ActiveX 控件添加任何可重用接口?

Posted

技术标签:

【中文标题】如何使用 MFC 为 ActiveX 控件添加任何可重用接口?【英文标题】:How to add any reusable interface for an ActiveX control using MFC? 【发布时间】:2015-04-09 20:36:12 【问题描述】:

我有一个 ActiveX 控件容器,它只接受一组预定义的接口(属性)。我需要设计相当多的 MFC ActiveX 控件来公开这些属性,所以我最初的尝试是创建一个接口类,其中包含作为纯虚拟成员的所有必需属性,并且我的所有 ActiveX 控件都继承自该接口类。现在我的 ActiveX 控件继承了所有接口,但是如何将它们公开给容器呢?如果我使用类向导添加这些属性,我知道我可以公开它们。但重点是避免为每个 ActiveX 控件一一添加它们。如果我不使用类向导,这将意味着我必须手动修改 BEGIN_DISPATCH_MAP() & END_DISPATCH_MAP() 部分以及对应的 .ODL 文件,我认为这不是一件好事。

所以我的问题是,使用 MFC,我如何继承一个抽象类(接口类)来实现 ActiveX 控件的所有预定义属性(接口)并将它们公开给用户?

示例: 假设我的基类 A 有一个属性定义为:long newProperty。而我的ActiveX控件B继承自A,所以B也有newProperty。我的问题是如何在 B 中公开 newProperty?我怎样才能获得和设置这个新属性的功能,比如使用类向导?我是否必须手动修改 BEGIN_DISPATCH_MAP() & END_DISPATCH_MAP() 部分和相应的 .ODL 文件?

【问题讨论】:

【参考方案1】:

如果我理解正确,您想以编程方式访问 ActiveX 控件,而不是使用类向导生成的包装器?嗯,这有点麻烦。例如,这会调用一个成员函数 MyMemberFunction,其参数为 long 123456789:

AtlAxWinInit();
pMyActiveXWnd = new CAxWindow();
pMyActiveXWnd ->Create(...)
LPUNKNOWN pUnk;
pMyActiveXWnd ->QueryControl(&pUnk);    
IDispatch *spDispatch; 
HRESULT hRes = pUnk->QueryInterface(__uuidof(spDispatch), (void **) &spDispatch);   
DISPID dispid;
DISPPARAMS dispparams =  NULL, NULL, 0, 0 ;
VARIANT vRet;
COleVariant vParam((long)123456789,VT_I4);
EXCEPINFO excepinfo;
UINT nArgErr;
dispparams.rgvarg = (LPVARIANT)vParam;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 0;
hRes = spDispatch->GetIDsOfNames(IID_NULL, _T("MyMemberFunction"), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
hRes = spDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, &vRet, &excepinfo, &nArgErr);

【讨论】:

不,我想公开我的 ActiveX 控件的属性(接口),同时让所有这些公开的属性继承自基类。假设我的基类 A 有一个属性定义为:long newProperty。而我的ActiveX控件B继承自A,所以B也有newProperty。我的问题是如何在 B 中公开 newProperty? 虚拟成员的概念来自 C++ 世界,所以我假设您使用某种自行创建的包装器。 C++ 缺乏动态类型。如果需要,您必须提供某种解释器来访问 ActiveX 控件中的继承成员以“模拟”动态类型,即通过查询我上面描述的 com 接口来使用 OLE 变体。 再次感谢您的回复。我的问题是我不知道如何在没有类向导的情况下向用户公开继承的成员。但你的回答是告诉我如何访问这些成员。如果我什至不知道如何公开它们,我也无法访问它们。 对不起,我想我并没有真正理解你在做什么。我只能猜测。但是,如果我是对的,您想以某种方式在编译时生成接口。这将需要复杂的脚本,我真的不推荐。也许您应该将 .NET 用于您的二级控件,因为 .NET 包含反射和嵌入式编译功能,因此您可以根据需要动态生成接口。您可以通过 com 互操作性使用这些。但我什至无法想象这种努力落在肥沃土地上的情况,我怀疑您应该考虑进行全面的重新设计。 恐怕这不是我的选择。我们正在处理遗留代码,我们负担不起重新设计或迁移到 .NET 的费用。

以上是关于如何使用 MFC 为 ActiveX 控件添加任何可重用接口?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 MFC 以编程方式更改 ActiveX 控件的属性?

如何访问 MFC 中的 activex 控件?

在 MFC 中构建 ActiveX 组件时为属性创建新的类别部分

如何在 MFC 对话框中替换/更新 ActiveX 控件

MFC设计器中的“无法访问ActiveX控件类型库”错误

我可以编辑具有 x64 ActiveX 控件的 MFC 对话框吗?