[activeX]使用ATL开发ActiveX控件[转]

本文描述了使用ATL开发一个ActiveX控件的完整过程。

一、创建项目

单击起始页中的“New Project…”,选择“ATL”分类下的“ATL Project”项目,项目名称为“Calculator”。在随后出现的项目向导中,使用默认配置即可。

二、添加控件

在解决方案管理器中的项目上右击,依次选择“Add”、“Class”,在添加类对话框中选择ATL分类下的ATL Control类型。单击“Add”按钮,将会出现添加ATL Control向导。

在向导的第二步中,将接口类型选择为“Dual”,为控件支持事件做为准备,在Support选项中,选中“Connection points”复选框。

随后出现选择控件要实现的接口的界面,除VS默认添加的实现外,再添加IObjectSafety接口,实现该接口可以避免控件在IE中使用时IE弹出运行的脚本不安全的提示。

三、为控件添加并实现方法

在Class View窗口中右击ICalc接口,依次选择“Add”、“Add Method…”,此处假定我们实现一个加法运算,将方法命名为“Add”,然后添加参数:

需要注意的是对返回值的处理。应将参数类型选定为DOUBLE*,并选中“retval”复选框。

向导结束后,VS自动在Calc.cpp中添加了该方法的空实现,略加修改后的方法代码为:

STDMETHODIMP CCalc::Add(DOUBLE a, DOUBLE b, DOUBLE* result)
{
	*result = a + b;

	return S_OK;
}

测试该方法:

由于只是调用该控件进行加法运算,并不需要该控件的界面展示,因此在测试控件之前,可以将VS自动生成的OnDraw方法中的其他代码删除,直接返回 S_OK 即可。

对VS自动生成的用于测试的htm略做修改来测试添加的方法。修改后的完整htm代码如下:

<HTML>
<HEAD>
<TITLE>ATL 8.0 test page for object Calc</TITLE>
</HEAD>
<BODY>

<OBJECT ID="Calc" CLASSID="CLSID:59443E6F-7B99-4F75-A7AF-6FEE5B8208CD"></OBJECT>

<input type="button" value="Add" onclick="add();" />

<script type="text/javascript">
    function add() {
        var calc = document.getElementById(‘Calc‘);
        var result = calc.Add(2, 3);
        alert(result);
    }
</script>

</BODY>
</HTML>

点击“Add”按钮后的运行效果:

四、为控件添加事件

假定控件进行的是一个非常复杂的运算,为了在调用运算时不阻塞调用者线程,可以使用异步方式完成运算。控件在完成运算时需要通知调用者,这时便需要事件。

首先按照步骤三中的方法,添加一个异步调用加法运算的方法AddAsync,然后为控件添加运算完成的事件AddCompleted。

在Class View窗口中右击_ICalcEvents接口,依次选择“Add”、“Add Method…”,根据添加方法向导添加AddCompleted方法,如下图所示:

然后在Class View窗口中右击CCalc类,依次选择“Add”、“Add Connection Point…”,在弹出的实现连接点窗口中实现_ICalcEvents接口。

完成向导后,VS会自动为我们生成基本框架,包括引发事件的方法Fire_AddCompleted。我们只需在AddAsync方法中添加运算并在运算结束时调用Fire_AddCompleted的代码:

STDMETHODIMP CCalc::AddAsync(DOUBLE a, DOUBLE b)
{
	double result;
	result = a + b;
	Fire_AddCompleted(&result);

	return S_OK;
}

在网页中添加异步计算的代码进行测试(添加的javascript代码如下),应该能够得到我们想要的效果。

<script type="text/javascript">
    function addAsync() {
        var calc = document.getElementById(‘Calc‘);
        calc.attachEvent("AddCompleted", OnAddCompleted);
        calc.AddAsync(3, 4);
    }

    function OnAddCompleted(result) {
        alert(result);
    }
</script>

五、ActiveX控件的事件与多线程

细心的读者一定会发现步骤四中所谓的“异步”是假的:虽然在运算结束后使用事件对调用者进行通知,但由于运算是在主线程上进行的,所以调用过程仍是同步的。步骤四其实只是展示了一下事件的简单用法,如果真正实现异步,则需要在控件中使用多线程。

在ActiveX控件中使用多线程时需要注意的是:引发事件(即调用Fire_XXXX)必须在窗口线程中进行,否则会导致事件不能被ActiveX控件的容器处理。如果事件发生时执行代码的线程不是窗口线程。那么应该使用PostMessage或SendMessage来通知窗口线程,并在消息处理函数中执行Fire_XXXX。为了使用控件的消息机制,还应该在CCalc的构造函数中将m_bWindowOnly字段设置为TRUE。

以下是改为多线程后的部分示例代码:

STDMETHODIMP CCalc::AddAsync(DOUBLE a, DOUBLE b)
{
	m_a = a;
	m_b = b;

	_beginthreadex(NULL, NULL, AddMethod, this, NULL, NULL);

	return S_OK;
}

unsigned __stdcall CCalc::AddMethod(LPVOID arg)
{
	CCalc* pThis = (CCalc*)arg;
	pThis->m_result = pThis->m_a + pThis->m_b;

	pThis->SendMessage(WM_ADDCOMPLETED);

	return 0;
}

LRESULT CCalc::OnAddCompleted(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	Fire_AddCompleted(&m_result);

	return 0;
}

至此,一个简单的ActiveX控件就开发完成了。关于ActiveX控件的打包部署等问题,可以参考以下内容:

1、Web发布cab文件打包的ActiveX控件总结

2、ActiveX控件打包成Cab置于网页中自动下载安装

3、VS2005下MFC开发的ActiveX控件的部分总结

本文示例所使用的开发环境为Visual Studio 2010。

附:使用VC6开发时的注意事项

在今天看来,VC6显得有些古老,但由于目前能见到的大多数版本的Windows操作系统已经内置了运行VC6开发的应用程序所需要的库,因此从方便发布的角度看,使用VC6来开发ActiveX控件不失为一个好的选择。

使用VC6开发ActiveX控件与上文所述步骤大同小异,但是需要注意微软给开发者留下的两道试题--使用VC6向导生成的代码中包含两处错误:

第一处错误位于连接点映射,DIID__IXXXXEvents中的第一个字符‘D’需手动添加。

示例代码:

BEGIN_CONNECTION_POINT_MAP(CCalc)
	CONNECTION_POINT_ENTRY(DIID__ICalcEvents)	// 修改 IID_XXXX 为 DIID_XXXX
END_CONNECTION_POINT_MAP()

该错误会造成生成失败,比较容易发现。

第二处错误位于Fire_XXXX方法内,不会造成生成失败但会造成运行结果莫名其妙,因此该错误更隐蔽一些。

示例代码:

if (pConnection)
{
  CComVariant avarParams[1];
  avarParams[0].byref = result;    //此处自动生成的代码有错误,应去掉原代码中的取址运算
  avarParams[0].vt = VT_R8|VT_BYREF;
  CComVariant varResult;

  //...
}
时间: 2024-10-06 17:02:32

[activeX]使用ATL开发ActiveX控件[转]的相关文章

使用VC2008中ATL开发浏览器控件

http://blog.csdn.net/cnjet/article/details/6218355 使用VC2008中ATL开发浏览器控件 2011.03.02 [email protected] 介绍 本文将介绍使用VC2008中的ATL开发一个用于网络部署的cab控件包的过程. 建立ATL项目 打开VS2008,建立一个ATL项目,如下图: 考虑到简介性,选择了"Allow merging of proxy/stub code" 添加ATL控件 (建议先编译一下真个project

IOS学习资源收集--开发UI控件相关

收集的一些本人了解过的iOS开发UI控件相关的代码资源(本文持续补充更新) 内容大纲: 1.本人在github上也上传了我分装好的一些可重复利用的UI控件 2.计时相关的自定义UILabel控件 正文: 1.本人在github上也上传了我分装好的一些可重复利用的UI控件 示例: 网址:https://github.com/HeYang123456789/UIView 2.计时相关的自定义UILabel控件 网址:https://github.com/mineschan/MZTimerLabel

可视化webpart基础开发——TreeView控件读取文档库中的所有文件夹和文件(递归方法读取)

可视化webpart基础开发——TreeView控件读取文档库中的所有文件夹和文件(递归方法读取) 分类: SharePoint2011-12-23 14:44 1584人阅读 评论(0) 收藏 举报 文档sharepointurl测试stringforms 可视化webpart基础开发——TreeView控件读取文档库中的所有文件夹和文件(递归方法读取) 1.在部署的sharepoint网站中新建一个名为“测试文档库”的文档库,并添加各级的子文件夹和子文件,用于测试 2.在VS2010中新建空

Web 开发工具控件ASPxperience Suite

ASPxperience Suite 是我们下一代的 Web 开发工具控件,可以为客户带来更多优秀体验,包括导航.数据布局管理以及嵌在 Web 应用程序中的浮动控件的应用.它从底层编写,然后使用支持 ASP.NET 2.0 Framework ,并且完全支持 out-of-the-box AJAX .此产品包含在产品集合 DXperience Universal Subscription 中. 具体功能: 包含在 ASPxperience Suite 中的控件只产生少量的 HTML 代码 可以根

IOS开发 UIView控件

1.万物皆对象 2.LBS:基于位置的服务(热门) 3.在启动XCODE创建项目的时候最好勾选 git 4.在SB界面中更改UILabel 之类的控件里面的内容,控件的frame会随着内容的大小而改变,但是在右侧的属性栏里面更改则不会影响frame 5.IBAction:SB界面原来叫Interface Builder 缩写为IB, 6.M_PI_4  代表45°  以此类推 // OC语法规定:不允许直接修改 某个对象中结构体属性的成员 ? 1 2 3 4 5 6 7 8 // 1.先取出fr

一些基于jQuery开发的控件

基于jQuery开发,非常简单的水平方向折叠控件.主页:http://letmehaveblog.blogspot.com/2007/10/haccordion-simple-horizontal-accordion.html (无法找到)下载:http://letmehaveblog.blogspot.com/2007/10/haccordion-simple-horizontal-accordion.html 示例:http://letmehaveblog.blogspot.com/2007

CAD控件,CAD插件使用教程:Android开发使用控件--开发环境的搭建

Android开发使用控件入门--环境搭建 2014-12-24 09:57     14人阅读     评论(0)     收藏         编辑     删除 CAD控件.CAD三维控件,手机控件 Android开发控件 软件名称(,梦,,想.CAD  ,控件) 1. 环境搭建: 3 1.1. 安装Eclipse 3 1.2. 下载JDK 3 1.3. 下载Android SDK 5 1.4. 给Eclipse 安装ADT插件  8 1.5. 运行Eclipse设置Android ADT

用swift开发仪表盘控件(一)

苹果swift刚刚推出不久,接触到这个语言是一个偶然的机会,无聊之余随便看了下它的语法: 瞬间就被感动了,switch 中居然大胆淘汰了break,完全是反人类的做法,其他语言没这么大胆和聪明,基本上switch, 都要搭配一大堆break(没有开发者考虑过繁琐性).因为99%的时候要使用break,所以苹果干脆就省略了.当然如果你要穿越的话可以用fallthrough.swift的优点还非常多此处省略1000字...... 可以在下面的地址下载控件(毫无保留,随便使用) http://down

CAD控件:QT开发使用控件入门

1. 环境搭建: 3 1.1. 安装Qt 3 1.2. 安装Microsoft Windows SDK的调试包 6 2. QT中使用MxDraw控件 7 1.3. 引入控件 7 3. 打开DWG文件 11 1.4. 增加打开文件按钮 11 1.5. 在VS中使用QT 13 环境搭建: 1.1. 安装Qt 官网地址:http://qt-project.org/,进入官网,点击  [Download]  到下载页面 如下: 再点击[Download],不使用它的在线安装,太慢,再点击[View Al