要干什么?
创建一个控件,导出一个方法,提供一个事件,应用一个属性;方法提供两个输入参数,接收web的输入,事件提供一个参数,把方法输入的两个参数加上属性值传递给web。
开始!
第一步创建工程:(VS2005)
菜单“文件”--“新建”--“项目”,“项目类型”选择MFC,模版选择“MFC ActiveX 控件”,输入名称“MyActiveX“后确定,接下来弹出的向导中的设置全部采取默认。工程创建好了,为实现目标,我们只需要关心三个文件:MyActiveXCtrl.h 、MyActiveXCtrl.cpp 和MyActiveX.idl
第二步添加方法:
在”类视图“中找到“MyActiveXLib”节点并展开,选中“_DMyActiveX”节点,右键弹出菜单,选择“添加”--“添加方法”,“返回类型”选择“void”,“方法名”输入“Fun“,添加两个参数param1和param2类型为LONG。“IDL”属性采用默认,点击完成。看看上面的步骤做了写什么吧(看这个的好处是可以手动添加一个方法,而不采用向导)。
首先在MyActiveX.idl中,多了“[id(1), helpstring("方法Fun")] void Fun(LONG param1, LONG param2);”这样一句。
其次在MyActiveXCtrl.h中,添加了一个protected类型的void Fun(LONG param1, LONG param2),并添加了一个“dispidFun = 1L”枚举。
最后在MyActiveXCtrl.cpp中,
void CMyActiveXCtrl::Fun(LONG param1, LONG param2)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加调度处理程序代码
}
方法的实现体。
在调度映射中看到
DISP_FUNCTION_ID(CMyActiveXCtrl, "Fun", dispidFun, Fun, VT_EMPTY, VTS_I4 VTS_I4)
这样的映射。
第三步添加事件:
在“类视图”中选择“CMyActiveXCtrl”节点,右键弹出菜单,“添加”--“添加事件”,“事件名称”输入“DoEvent“,添加一个LONG型的参数param。
同样的看看做了些什么:
MyActiveX.idl中,[id(1)] void DoEvent(LONG param),与方法不同的是,在不同的接口中。
在MyActiveXCtrl.h中多了实现
void DoEvent(LONG param)
{
FireEvent(eventidDoEvent, EVENT_PARAM(VTS_I4), param);
}
并且又添加了一个枚举eventidDoEvent = 1L
MyActiveXCtrl.cpp中进行了事件映射
BEGIN_EVENT_MAP(CMyActiveXCtrl, COleControl)
EVENT_CUSTOM_ID("DoEvent", eventidDoEvent, DoEvent, VTS_I4)
END_EVENT_MAP()
第四步添加属性:
与第二步一样“添加”菜单之后是“添加属性”,“属性类型”是“VARIANT”,“属性名”是“Property”,“实现类型”选择“成员变量”,“IDL属性”采用默认点击完成。
做了什么:
MyActiveX.idl中,[id(2) , helpstring("属性 Property")] VARIANT Property;
MyActiveXCtrl.h中
void OnPropertyChanged(void);
VARIANT m_Property;
并且添加了一个枚举dispidProperty = 2
MyActiveXCtrl.cpp中,
void CMyActiveXCtrl::OnPropertyChanged(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加属性处理程序代码
SetModifiedFlag();
}
并且添加了调度映射DISP_PROPERTY_NOTIFY_ID(CMyActiveXCtrl, "Property", dispidProperty, m_Property, OnPropertyChanged, VT_VARIANT).
第五步:
上面四步把框架搭好了,接下来实现方法,在CMyActiveXCtrl::Fun(LONG param1, LONG param2)中添加代码,代码如下:
void CMyActiveXCtrl::Fun(LONG param1, LONG param2)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
LONG ret = param1 + param2;
m_Property.vt = VT_I4;
m_Property.lVal = ret;
DoEvent(ret);
}
第六步:
编译生成ocx文件。
第七步:
编写web代码测试这个控件,web代码如下:
<HTML>
<head>
<script language="javascript">
function Fun()
{
MyActiveX.Fun(10,10);
}
</script>
</head>
<BODY>
<OBJECT classid="clsid:2F1BCCED-818A-4510-A8CB-90272F88ADAD" id="MyActiveX">
</OBJECT>
<INPUT TYPE="button" NAME="Fun" VALUE="Fun" ONCLICK=Fun()>
</BODY>
<script for=MyActiveX event=DoEvent()>
{
window.document.write("DoEvent's param is " + arguments[0]+ " and MyActiveX's Property is " + MyActiveX.Property);
}
</script>
</HTML>
clsid:2F1BCCED-818A-4510-A8CB-90272F88ADAD是MyActiveX.idl中“CMyActiveXCtrl 的类信息”的uuid。