01
首先,使用ocx意味着,网站只支持windows!!
MFC ActiveX
和ATL
C++ ocx
开发,有ATL
和MFC ActiveX
两套框架。二者的比较,简单说,MFC封装程度高,故MFC使得你很快完成你的工程并更快的运行起来,但是牺牲了灵活性;ATL更接近COM核心,轻量级。
如果ocx
需要界面的话,如监控控件需要显示视频流。建议使用MFC ActiveX
,可以像MFC Dialog
项目那样写界面,尽管说MFC
过时了,但C++写简单实用的界面,还有其他更好的选择?
如果很在意ocx
控件大小的话,只能用ATL
,因为MFC ActiveX
是MFC
项目——打入MFC
库,不够轻量。
02
MFC ActiveX
开发ocx
注意事项Active Test Control
工具(tstcon32.exe
)这是一个很实用的ocx
测试工具,从VS2010
起不再提供这一个工具(据说是由于微软内部评测不理想);但可以从网站下到,可正常使用,最少我目前为止没发现有问题。
CLSID
如何查看[ uuid(B24A098C-DBEE-482F-914D-7C951CEDAC36), helpstring("GridCapture Control"), control ]
coclass GridCapture
{
[default] dispinterface _DGridCapture;
[default, source] dispinterface _DGridCaptureEvents;
};
在ProgramName.idl
文件,如上位置,索搜关键字coclass
快速查找。
一般使用LONG
(整型)BSTR
(字符串)类型就够了。
遇到棘手的情况,使用VARIANT
类型——union
定义的“万能类型”,当年在VB、VC、C#等扩平台调用时出现过问题,使用复杂,现在具体已经记不清了。
建议不要使用bool
类型,用long
代替:当年在客户那出bug了,最后的原因是true!=true
,VB
的true
值是1,VC
是8位全1——255,1!=255。如若使用ocx
的bool
,推荐判false
——都是0。
cab
打包编写inf
文件如下
[version]
signature="$CHICAGO$"AdvancedINF=1.0[Add.Code]
MFCActiveXControl1.ocx=MFCActiveXControl1.ocx
mfc110.dll=mfc110.dll
msvcp110.dll=msvcp110.dll
msvcr110.dll=msvcr110.dll[MFCActiveXControl1.ocx]
file-win32-x86=thiscab
clsid={CC62BF54-D650-4123-B626-F356FD28C2A5}
RegisterServer=yes
DestDir=11[mfc110.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=11.00.50727.1[msvcp110.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=11.00.50727.1[msvcr110.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=11.00.50727.1[DestinationDirs]
InstallFilesSection=11
打包指令
cabarc -s 6144 n myocx.cab mfc110.dll mfc110.dll msvcp110.dll msvcr110.dll MFCActiveXControl1.ocx myocx.inf
<object id="ocx" classid="CLSID:054B8AF8-42D2-4F3A-A631-CDECC66E0290" codebase="myocx.cab">
<param name="name" value="Tom">
<param name="age" value="99">
<embed classid="CLSID:054B8AF8-42D2-4F3A-A631-CDECC66E0290" codebase="myocx.cab"></embed>
</object>
object id
属性很重要
ocx.name
操作ocx
接口的name
属性
ocx.start()
调用ocx
接口的start
方法
param
标签初始化ocx
属性值不成功?!因为在DoPropExchange
函数中没有设置
void CGridCaptureCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX); if (pPX->GetVersion() == (DWORD)MAKELONG(_wVerMinor, _wVerMajor))
{
PX_String(pPX,_T("name"),m_name);
PX_Long(pPX, _T("age"), m_age);
}
}
js
与ocx
借助ocx event
进行通讯通过MFC
向导添加event
,会自定生成如下:(以名为TestEvent
的自定义消息为例)
在idl
文件XXXEvents
中添加事件的接口定义
dispinterface _DMFCActiveXControl1Events {
dispinterface _DMFCActiveXControl1Events {
properties:
// 事件接口没有任何属性
methods:
[id(2)] void TestEvent(BSTR name, LONG age);
};
2.在XXXCtrol
类中实现TestEvent
方法
void TestEvent(LPCTSTR name, LONG age)
{
FireEvent(eventidTestEvent, EVENT_PARAM(VTS_BSTR VTS_I4), name, age);
}
3.添加事件映射,通常在XXXCtrol.c
BEGIN_EVENT_MAP(CMFCActiveXControl1Ctrl, COleControl)
EVENT_CUSTOM_ID("TestEvent", eventidTestEvent, TestEvent, VTS_BSTR VTS_I4)
END_EVENT_MAP()
附:通过MFC向导添加ocx属性、方法与之雷同,三步操作:在idl文件中添加ocx接口定义,在XXXCtrol类中添加方法实现,在XXCtrol.c中添加映射。
开始测试
1.ocx
端发送事件 在start
方法接口里发送TestEvent
消息
void CMFCActiveXControl1Ctrl::start(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加调度处理程序代码
TestEvent(L"Tom", 30);
}
2.html
端
<script type="text/javascript" event="TestEvent(name, age)" for="ocx">
alert("My name is " + name + ", my age is " + age + ".");
</script>
本文分享自 FreeSWITCH中文社区 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!