COM组件开发实践(一)【转】

本文详细介绍如何使用VS2005创建一个简单的ActiveX控件,包括项目配置、控件设计、动画GIF支持及对话框添加等关键步骤。

 Preface

      因为项目需要,开始从事 ActiveX 方面的工作,看了一些资料,可惜都是些 COM 原理方面的,没有切合实际动手的东西,在 CodeProject 上读完 David Marcionek的 文章【1】后,收获良多,但也遇到一些恼人的小问题, 因此在其基础上就一些易错点做些小注解。本文版权归 David Marcionek 所有。

简介  

本文目的在于让你快速掌握 ActiveX 控件开发技术,将会展示开发 ActiveX 应该知道的基本概念,如方法,属性和事件,以及如何在一个 ActiveX 控件和一个 web 页面之间进行通信

在本文中,我们将创建一个 ActiveX 控件,当加载控件时,它会显示一个动画进度条,以便向用户表明控件正在加载。此控件会包含展示如何在控件和 web 页面间传递信息的功能。下面我们会使用 VS2005 一步步进行开发的。

创建一个 ActiveX 控件

为了创建一个 ActiveX 控件,如下所示:

1, 创建一个 "MFC ActiveX Control" 项目,取名 MyActiveX,

2 ,在 "MFC ActiveX Control Wizard" 对话框中,选中 "Control Settings"

3,"Create control based on" 中选择 "STATIC". 我们将使用静态控件,因为我们只是显示从控件中获取的输出信息,并不接受输入信息。

4 ,在 "Additional features" 中,确保 "Activates when visible""Flicker-free activation" 被选中, "Has an About box dialog" 不选中。

5 ,默认情况下, wizard 会创建一个项目,使其在一个共享 DLL 中使用 MFC. 我们必须更改这种情况,因为除非所需的 MFC DLL 都已经在系统中安装了,否则 ActiveX 控件 就不能运行。包含 ActiveX 控件的 Web 页面上出现红叉的一个原因就是此。在项目的属性中, "Configuration Properties"-->"General",“Use of MFC” 改为 “Use MFC in a Static Library”.

6 ,向导会创建如下几个类:

      1)CMyActiveXApp: 这是 ActiveX 应用程序类,从 COleControlModule 类继承下来的。它是 OLE 控件模块对象继承自的基类,包含了初始化 (InitInstance )和清理 (ExitInstance) 的代码

      2)CMyActiveXCtrl:COleControl 继承而来,这里是我们实现控件大部分功能的地方。

      3)CMyActiveXPropPage:COlePropertyPage 继承而来,用于管理控件的属性页对话框。向导已经为我们创建了一个默认的对话框来作为控件的属性页对话框。

增加动画 GIF 支持

      这里我们使用了一个 CPictureEx 类(具体代码见最后的 资源 部分), vs2005 增加一个动画 GIF 资源有一个 bug (其实在 vs2008 中也存在),我们可以使用下面这种技巧来回避它:

ProcessingProgressBar.gif 拷贝到项目文件夹下,然后更名为 ProcessingProgressBar.gaf 在资源视图中,右键资源文件 MyActiveX.rc, 选择 添加资源 。在 添加资源 对话框中,按下 导入 按钮,并选择 ProcessingProgressBar.gaf 文件。在 自定义资源类型 对话框中输入 “GIF” 作为资源类型。这就会将 GIF 图片文件导入项目中。然后将导入的图片 IDIDR_GIF1 改为 IDR_PROGRESSBAR .

现在开始着手恢复原状,首先,打开 MyActiveX.rc 的源文件,找到 IDR_PROGRESSBAR 的定义,将其文件名改为 ProcessingProgressBar.gif ”. 同样地,把项目文件夹下的图片文件名也改回为 “ProcessingProgressBar.gif”, 最后在 解决方案资源管理器 视图中,选中 ProcessingProgressBar.gaf ,在其 属性 中,修改 相对路径 ."ProcessingProgressBar.gif”.

增加对话框

      现在,我们为进度条图像增加一个对话框。

1,  资源 视图中,右键 对话框 ,选择 插入对话框 来创建一个默认的对话框。

2,  删除默认产生的 确定 取消 按钮,调整对话框大小为 230*40

3, 更改对话框 IDIDD_MAINDIALOG ,并修改对话框属性: Border—none, Style – Child, System Menu – False, Visible – True.

4, 在对话框中加入一个图片控件,调整其大小为 200*20 ,更改控件 ID IDC_PROGRESSBAR ,颜色为 “white”

5, 为对话框创建一个类,名为 CMainDialog,

 现在我们为类增加成员变量:

1, CMyActiveXCtrl 类增加一个变量 m_MainDialog ,类型为 CMainDialog

2,  CMainDialog 类增加一个变量 m_ProgressBar ,类型为 CPictureEx ,这里注意确保 控件变量 选中,并且对于的控件是 ”IDC_PROGRESSBAR”.

增加支持代码

好了,现在加入一些代码来绘制主对话框和进度条控件吧。

1 ,为 CMyActiveXCtrl 处理 WM_CREATE 事件的代码,在其中加入:

m_MainDialog.Create(IDD_MAINDIALOG,  this );

并在 OnDraw 函数中加入:

m_MainDialog.MoveWindow(rcBounds, TRUE);
CBrush brBackGnd(TranslateColor(AmbientBackColor()));
pdc
-> FillRect(rcBounds,  & brBackGnd);

     2. CMainDialog 类中,加入处理 WM_CREATE 事件的代码,在其中加入:

if (m_ProgressBar.Load(MAKEINTRESOURCE(IDR_PROGRESSBAR),_T( " GIF " )))
m_ProgressBar.Draw();

Ok, 一个简单的 ActiveX 控件已经开发完毕,设置编译模式为 “Release” 模式,并构建整个应用程序。

创建一个 Web 页面作为 ActiveX 控件容器

      可以使用微软的 ActiveX Control Pad 。要利用它在 Web 页面中插入一个 ActiveX 控件,在 <BODY> 标记中右键,选择 “Insert ActiveX Control”, 选择你需要的就可以了。

 直接打开 Web 页面或者放到 IIS 服务器上进行访问,一切顺利的话就可以看到下面的图像:  

注1:前面要求设置编译模式为“ Release” ,其实是为了避免运行时因为触及 Assert 出错而做的,否则会报错如下:

 跟踪调试后会发现:  

  可以看出是图片扩展控件加载时的顺序有些问题,但在浏览器中并不需要考虑如此多,因此这里忽略此 Assert 条件。

 2 :作 者在这里没有对 MyActiveX.idl 文件进行讲解,我认为是一个不小的失误,也正是因为如此,才会导致一个很容易犯错的地方,当我们按照他的教程,仿照他的代码一步步进行完后,却发现在 ActiveX 测试容器中是可以运行通过的,但到了浏览器中却死活都是红叉叉。。。,就是因为作者忽略了其对 MyActiveX.idl 接口定义文件的修改进行解释。

注3:VS2008中没有ActiveX控件测试容器了,VS05以上的数字签名工具也改变了,因此使用VS2005可能更好

     我按照教程一步步模仿着做的时候,在上面这两点上纠缠了3个多小时才发现问题的原因。

     在下一篇文章中,将介绍如何对 ActiveX 控件进行数字签名并使其自注册和销毁来确保其安全性,此外还会介绍如何在 ActiveX 控件和 Web 页面间进行数据通信。

参考资源

1A Complete ActiveX Web Control Tutorial By David Marcionek

2. Add GIF-animation to your MFC and ATL projects with the help of CPictureEx and CPictureExWnd by Oleg Bykov, CodeProject.

 

作者:洞庭散人

出处:http://phinecos.cnblogs.com/     

本博客遵从 Creative Commons Attribution 3.0 License ,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

组件基础 1 软件开发的阶段 1.1 结构化编程 采用自顶向下的编程方式,划分模块 和功能的种编程方式。 1.2 面向对象编程 采用对象的方式,将程序抽象成类, 模拟现实世界,采用继承、多态的方式 设计软件的种编程方式。 1.3 面向组件编程 将功能和数据封装成二进制代码,采用 搭积木的方式实现软件的种编程方式。 2 组件和优点 2.1 组件 - 实际是些可以执行的二进 制程序,它可以给其他的应用程序、操 作系统或其他组件提供功能 2.2 优点 2.2.1 可以方便的提供软件定制机制 2.2.2 可以很灵活的提供功能 2.2.3 可以很方便的实现程序的分布式 开发。 3 组件的标准 - COMComponent Object Model ) 3.1 COM种编程规范,不论任何开发语言 要实现组件都必须按照这种规范来实现。 组件开发语言无关。 这些编程规范定义了组件的操作、接口的 访问等等。 3.2 COM接口 COM接口是组件的核心,从定程度上 讲"COM接口是组件切". COM接口给用户提供了访问组件的方式. 通过COM接口提供的函数,可以使用组件 的功能. 4 COM组件 4.1 COM组件-就是在Windows平台下, 封装在动态库(DLL)或者可执行文件(EXE) 中的段代码,这些代码是按照COM的 规范实现. 4.2 COM组件的特点 4.2.1 动态链接 4.2.2 与编程语言无关 4.2.3 以二进制方式发布 二 COM接口 1 接口的理解 DLL的接口 - DLL导出的函数 类的接口 - 类的成员函数 COM接口 - 是个包含了组函数指针 的数据结构,这些函数是由组件实现的 2 C++的接口实现 2.1 C++实现接口的方式,使用抽象类 定义接口. 2.2 基于抽象类,派生出子类并实现 功能. 2.3 使用 interface 定义接口 interface ClassA { }; 目前VC中,interface其实就是struct 3 接口的动态导出 3.1 DLL的实现 3.1.1 接口的的定义 3.1.2 接口的实现 3.1.3 创建接口的函数 3.2 DLL的使用 3.2.1 加载DLL和获取创建接口的函数 3.2.2 创建接口 3.2.3 使用接口的函数 4 接口的生命期 4.1 问题 在DLL中使用new创建接口后,在用户 程序使用完该接口后,如果使用delete 直接删除,会出现内存异常. 每个模块有自己的内存堆(crtheap) EXE - crtheap DLL - crtheap new/delete/malloc/free默认情况 下都是从自己所在模块内存堆(crtheap) 中分配和施放内存.而各个模块的 这个内存堆是各自独立.所以在DLL中 使用new分配内存,不能在EXE中delete. 4.2 引用计数和AddRef/Release函数 引用计数 - 就是个整数,作用是 表示接口的使用次数 AddRef - 增加引用计数 +1 Release - 减少引用计数 -1, 如果 当引用计数为0,接口被删除 4.3 使用 4.3.1 创建接口 4.3.2 调用AddRef,增加引用计数 4.3.3 使用接口 4.3.4 调用Release,减少引用计数 4.4 注意 4.4.1 在调用Release之后,接口指针 不能再使用 4.4.2 多线程情况下,接口引用计数 要使用原子锁的方式进行加减 5 接口的查询 5.1 每个接口都具有唯标识 GUID 5.2 实现接口查询函数 QueryInterface 6 IUnknown 接口 6.1 IUnknown是微软定义的标准接口 我们实现所有接口就是继承这个接口 6.2 IUnknown定义了三个函数 QueryInterface 接口查询函数 AddRef 增加引用计数 Release 减少引用计数 7 接口定义语言 - IDL(Interface Definition Language ) 7.1 IDL和MIDL IDL - 定义接口的种语言,与开发 语言无关. MIDL.EXE - 可以将IDL语言定义接口, 编译成C++语言的接口定义 7.2 IDL的基础 import "XXXX.idl" [ attribute ] interface A : interface_base { } 7.2.1 Import 导入,相当于C++的 #include 7.2.2 使用"[]"定义区域,属性描述 关键字 1) object - 后续是对象 2) uuid - 定义对象GUID 3) helpstring - 帮助信息 4) version - 版本 5) point_default - 后续对象 中指针的默认使用方式 比如: uniqune - 表示指针可以 为空,但是不能修改 7.2.3 对象定义 1) 父接口是IUnknown接口 2) 在对象内添加函数,函数定义必须 是返回 HRESULT. HRESULT是32位整数,返回函数是否 执行成功,需要使用 SUCCESSED和 FAILED宏来判断返回值.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值