activex控件的功能,怎样允许activex控件

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: