activeX 开发

转自 (http://www.cnblogs.com/chinadhf/archive/2010/09/03/1817336.html),并且在开发过程中遇到的问题进行了补充说明,让新手少走弯路

本文描述了使用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><OBJECTID="Calc"CLASSID="CLSID:59443E6F-7B99-4F75-A7AF-6FEE5B8208CD"></OBJECT><inputtype="button"value="Add"onclick="add();"/><scripttype="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方法,如下图所示:

-----------------------------------------------------------------------
在2013中添加事件时,可能会出错,请在源文件->.ldl 中添加
dispinterface _IwebAXFingerEvents
	{
		properties:
		methods:
			[id(1)] void xxxx(char xxx);
//事件

	};
然后点右键编译该文件

然后在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;

  //...
}

----------------------------------------------------------------------
pThis->SendMessage(WM_ADDCOMPLETED);
WM_ADDCOMPLETED是用户自定义的消息
static const UINT WM_ADDCOMPLETED = WM_APP + 101;//定义WM_ADDCOMPLETED消息
MESSAGE_HANDLER(WM_ADDCOMPLETED, OnAddCompleted)//绑定事件,在发送消息是触发
------------------------------------------------------------------------------
char 转bstr
                        char temp1[1024];
			hex2visiblec(_finerstr, temp1, 497);
			char temp2[30];
			hex2visiblec(_deviceid, temp2, 10);
			BSTR xxx= _com_util::ConvertStringToBSTR(temp1);
			BSTR xxx1 = _com_util::ConvertStringToBSTR(temp2);

注意应该调用dll,应该放在windwos/system32/

时间: 2024-10-07 19:47:54

activeX 开发的相关文章

.Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇

一.前言 经过上几篇的学习,现在我们已经掌握了ActiveX的整个开发过程,但要发挥ActiveX的真正威力,必须依靠JS.下面一起来学习吧! 二.JS调用ActiveX方法 只需在UserControl子类中(即自定义的ActiveX控件中),编写公共方法即可. C# [Guid("0203DABD-51B8-4E8E-A1EB-156950EE1668")] public partial class Uploader : UserControl, IObjectSafety { p

ActiveX开发

转自(http://blog.csdn.net/mingojiang/article/details/8159263) 一.ActiveX基础 1.1什么是ActiveX ActiveX是COM规范的一种实现,前身是OLE(Object Linking and Embedding).一般读成:ActiveX Ctronl,译成:ActiveX控制,ActiveX控件.即可用于桌面也可用于网络,是封装.跨平台(兼容)与重用技术的延伸.封装与重用技术大概经历了以下几个历史阶段: 明码复用:就是写的代

.Net魔法堂:史上最全的ActiveX开发教程——部署篇

一.前言 接<.Net魔法堂:史上最全的ActiveX开发教程——发布篇>,后我们继续来部署吧! 二. 挽起衣袖来部署   ActiveX的部署其实就是客户端安装ActiveX组件,对未签名和已签名的ActiveX,分别有对应的部署方式. 1. 部署未签名的ActiveX 未签名的ActiveX控件不受浏览器端信任,默认是不被允许安装的 1. 将网站加入 **可信站点** 2. 在“可信站点”和“Internet”下的 **自定义级别** 中确认“对未标记为可安全执行脚本的ActiveX控件初

基于MFC的ActiveX控件开发教程------------浏览器插件之ActiveX开发

一般的Web应用对于浏览器插件能不使用的建议尽量不使用,因为其涉及到安全问题以及影响用户安装(或自动下载注册安装)体验问题.在有特殊需求(如涉及数据安全的金融业务数据交互.需插件才能实现的与本地设备的交互等)的情况下可以酌情慎用. 浏览器插件总体可以划分为两大阵营,即IE支持的插件以及非IE支持的插件.本来在Netscape时代,对于浏览器插件是有公用的规范的(NPAPI),一开始所有浏览器都支持该规范,包括IE.后来出于商业原因,微软的IE不再支持NPAPI,改而自己开发了一套基于COM的Ac

activex开发、部署、更新

开发篇 一.前言 在设计某移动内部自动化运维平台时,经综合考虑终端机性能和功能需求等因素后,决定采用B/S模式,并且浏览器通过ActiveX组件实现与服务器Agent作P2P的通讯.好处,整个平台以网页形式存在,界面渲染性能高于桌面应用(终端机性能其低):通过ActiveX组件与各服务器Agent进行P2P通讯,不对Web服务器造成压力.风险,当用ActiveX传输上百兆的文件时,会对浏览器造成哪些影响:团队中没有类似解决方案的经验供借鉴.解决方法:前期对主要功能进行快速原型设计.开发.验证和总

C# Activex开发、打包、签名、发布

一.前言      最近有这样一个需求,需要在网页上面启动客户端的软件,软件之间的通信.调用,单单依靠HTML是无法实现了,因此必须借用Activex来实现.由于本人主要擅长C#,自然本文给出了用C#实现的范例,本文的预期效果是有一定Winform基础的人可都轻松读懂本文. 文章主要介绍了以下几个部分: 1.用C#制作Activex控件,并发布为msi安装文件 2.将exe打包为cab,达到浏览器自动安装的效果 3.给cab数字签名(可选) 4.将Activex应用到网页上 二.用C#制作Act

C# ActiveX开发及安装部署

最近项目中,因为需要在WEB页面上操作串口,包括串口查询.打开.发送指令.接收数据.关闭串口等功能.如下所示: 考虑使用ActiveX来实现.因为以前没有这方面的经验,开发过程中也是遇到各种问题.废话不多说,下面进入正题: 1:打开VS2008,新建项目,以下是具体代码: 1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 using System.IO.Ports; 5 usin

Delphi XE7 开发ActiveX 及在IntraWeb下调试

最近学习DelphiXE7下Intraweb开发,Intraweb完全服务器端运行使得FastReport报表系统无法在客户端运行,当然网上也有一大堆解决方案,例如导出到PDF后,给出连接,让客户点击下载等,个人感觉不完美.由于我做的B/S系统主要运行在windows平台,所以还是考虑ActiveX插件,来的直观.一.DelphiXE7下 ActiveX开发 1.new-other-打开窗口,选择ActiveX Library,点击OK按钮 2.出现这样一个界面,此时Delphi建立一个无窗口的

开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件

ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇: 基本教程:http://www.cnblogs.com/guenli/articles/1629915.html 注意事项:http://jon-lt.iteye.com/blog/1676272 属性.方法开发:http://blog.csdn.net/waxgourd0/article/details/7652478 但是由于我的目的是开发一个身份证识别仪的ActiveX控件,因此我就要先仿照识别仪ActiveX开发一个Ac