activex控件的功能,怎样允许activex控件
首先,创建一个项目
在起始页中点击“新建项目…”并选择“ATL”类别下的“ATL项目”项目。项目名称为“计算器”。在随后的项目指南中,只需使用默认配置。
第二,添加控件
在解决方案管理器中右击该项目,选择“添加”,然后选择“类”,并在“添加类”对话框中的“ATL分类”下选择ATL控件类型。单击“添加”按钮,将出现添加ATL控件向导。
在向导的第二步中,选择“Dual”作为接口类型,为控件支持事件做准备。在支持选项中,选择“连接点”复选框。
然后出现选择控件要实现的接口的界面。除了VS默认添加的实现,还添加了IObjectSafety接口。该接口的实现可以避免在IE中使用控件时IE弹出脚本的不安全提示。
第三,添加并实现控件的方法。
在“类视图”窗口中右击ICalc接口,依次选择“添加”和“添加方法…”。这里,假设我们实现了一个加法运算,将方法命名为“Add”,然后添加参数:
需要注意的是返回值的处理。参数类型应该是DOUBLE*并且应该选中“retval”复选框。
向导完成后,VS自动在Calc.cpp中添加了这个方法的一个空实现。稍微修改的方法代码是:
STDMETHODIMP CCalc:Add(DOUBLE a,DOUBLE b,DOUBLE* result)
*结果=a b;
返回S _ OK
}测试方法:
因为调用控件只是为了加法运算,不需要控件的界面显示,所以在测试控件之前,可以删除VS自动生成的OnDraw方法中的其他代码,直接返回S_OK。
稍微修改一下测试用VS自动生成的htm来测试添加的方法。修改后的完整htm代码如下:
超文本标记语言
头
对象计算/标题的标题ATL 8.0测试页
/头
身体
OBJECT ID= Calc CLASSID= CLSID:59443 e6f-7b 99-4f 75-A7AF-6 fee 5b 8208 CD /OBJECT
input type= button value= Add onclick= Add();/
脚本类型=文本/javascript
函数add() {
var Calc=document . getelementbyid( Calc );
var结果=calc。添加(2,3);
警报(结果);
/脚本
/BODY
/html点击“添加”按钮后的操作效果:
第四,为控件添加事件
假设控件执行非常复杂的操作,为了在调用操作时不阻塞调用方的线程,可以异步完成。当控件完成操作后需要通知调用方时,事件是必需的。
首先按照步骤3中的方法,添加一个异步调用加法操作的方法AddAsync,然后为控件添加事件AddCompleted。
在“类视图”窗口中右击_ ICalcEvents接口,依次选择“添加”和“添加方法……”,根据添加方法向导添加AddCompleted方法,如下图所示:
然后在类视图窗口中右键单击CCalc类,依次选择“添加”和“添加连接点.”,在实现连接点的弹出窗口中实现_ ICalcEvents接口。
完成向导后,VS会自动为我们生成基本框架,包括引发事件的方法Fire_AddCompleted。我们只需要在AddAsync方法中添加操作,并在操作结束时调用Fire_AddCompleted的代码:
STDMETHODIMP CCalc:AddAsync(双a,双b)
双重结果;
结果=a b;
Fire_AddCompleted(结果);
返回S _ OK
}将异步计算的代码添加到网页中进行测试(添加的javascript代码如下),应该可以得到想要的效果。
脚本类型=文本/javascript
函数addAsync() {
var Calc=document . getelementbyid( Calc );
calc.attachEvent(AddCompleted ,OnAddCompleted);
计算。AddAsync(3,4);
函数OnAddCompleted(结果){
警报(结果);
/script v . ActiveX控件的事件和多线程
细心的读者一定会发现,第四步所谓的“异步”是假的:虽然操作完成后调用方得到了事件的通知,但调用过程仍然是同步的,因为操作是在主线程上执行的。步骤4实际上只是展示了事件的简单用法。如果真的实现了异步,就需要在控件中使用多线程。
在ActiveX控件中使用多线程时,需要注意的是,引发事件(即调用Fire_XXXX)必须在窗口线程中完成,否则ActiveX控件的容器无法处理事件。如果事件发生时执行代码的线程不是窗口线程。那么你应该使用PostMessage或者SendMessage通知窗口线程,在消息处理函数中执行Fire_XXXX。若要使用控件的消息机制,还应该在CCalc的构造函数中将m _ bwindownonly字段设置为TRUE。
以下是多线程处理后的一些示例代码:
STDMETHODIMP CCalc:AddAsync(双a,双b)
m _ a=a
m _ b=b
_beginthreadex(NULL,NULL,AddMethod,this,NULL,NULL);
返回S _ OK
无符号_ _ stdcall CCalc:add method(LPVOID arg)
CCalc * pThis=(CCalc *)arg;
pThis- m_result=pThis- m_a pThis-
pThis-SendMessage(WM _ add completed);
返回0;
LRESULT CCalc:on add completed(UINT/* uMsg */,WPARAM /*wParam*/,LPARAM /*lParam*/,BOOL /*bHandled*/)
fire _ add completed(m _ result);
返回0;
}至此,已经开发了一个简单的ActiveX控件。关于ActiveX控件的打包和部署,请参考以下内容:
1.Web发布cab文件打包的ActiveX控件摘要
2.ActiveX控件被打包成Cab并放在网页中,以便自动下载和安装。
3.VS2005下MFC开发ActiveX控件部分摘要
本文使用的开发环境是Visual Studio 2
附:用VC6开发时的注意事项
在今天看来,VC6似乎有点老了,但由于目前能看到的Windows操作系统的大部分版本都已经内置了运行VC6开发的应用程序所需的库,所以从方便发布的角度来看,使用VC6开发ActiveX控件是一个不错的选择。
使用VC6开发ActiveX控件与上述步骤类似,但你要注意微软留给开发者的两道测试题——使用VC6向导生成的代码包含两个错误:
第一个错误是在连接点映射中,DIID _ _ ixxxxxxevents中的第一个字符 d 需要手动添加。
示例代码:
开始_连接_点_地图
connection _ point _ entry(diid _ _ icalevents)//将XXXX IID修改为XXXX DIID
END_CONNECTION_POINT_MAP()这个错误会导致构建失败,很容易发现。
第二个错误在Fire_XXXX方法中,不会导致生成失败但会导致运行结果莫名其妙,所以这个错误比较微妙。
示例代码:
if(p连接)
CComVariant avar params[1];
avarParams[0]。byref=结果;//这里自动生成的代码有错误,要去掉原代码中的寻址操作。
avarParams[0]。VT=VT _ R8 VT _ BYREF;
CComVariant varResult
//.
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。