用ATL和MFC来创建ActiveX控件
2010-07-25 20:46:35 来源:WEB开发网用ATL开发一个控件
有了基于MFC的控件,你就可以用ATL COM App Wizard得到一个开发基于ATL的控件的触发器。使用ATL来创建控件可以分为两步。虽然MFC的Control Wizard要求你预先确定你希望在DLL中包含多少个控件,ATL COM Wizard简单的创建DLL——你可以以后使用ATL对象选项从Insert菜单添加控件。当创建一个新的基于ATL的DLL时,你可以选择混用MFC支持。你还可以选择在控件的DLL中合并任何proxy/stub代码。这使得如果有人希望远程控制你的控件实现的代码,你只要发布一个文件。
一旦生成了基于ATL的DLL,你就可以开始添加COM类了。Insert New ATL Object菜单条使得这项工作变得十分容易。选择此菜单项显示一个用来创建任何一个COM类的对话框,包括无格式的COM对象,ActiveX控件以及Microsoft事务服务器组件(Windows NT Server的一部分)。
当添加基于ATL的控件到你的工程的时候,ATL Object Wizard比MFC Object Wizard提供了更大范围的选项。对于新手来说,ATL使得你可以选择使用任何现有的线性模型实现你的控件。你可以将你的类标记为或者单线程或者单元线程的。ATL Object Wizard限制你创建一个自由的或者混合线程的控件,因为控件通常是面向UI的。
如果你创建了一个单线程的控件,一个包容的控件的客户将总是将它加载到主、单线程的单元(STA)中。结果,只有在客户进程空间运行的单主线程才会接触到你的对象,这样就免除了你保护你的控件状态不受并发访问干扰的责任。另外,因为你的对象的所有实例将只会被一个线程接触,你将不必担心DLL中的全局数据。如果你的控件是单元线程的,你还免除了保护你的控件的内部状态的大部分负担。然而,你仍然不得不保护DLL中的全局数据。为什么呢?首先,设想你的控件是由客户的单线程创建的。现在假定客户试图创建该控件的另一份拷贝——但是是从一个云向在当前进程的多线程的单元中。通过将你的对象标记为单元线程的,COM被告知你希望你的控件保护免遭并发访问。COM在它加载时为你的控件创建一个新的STA。现在当线程调用到你的对象时,它们只能通过单元边界来访问它,远程层将同步对此对象的调用。然而,当某个控件的状态被保护不被并发访问,作为在一个STA中的副产品,由控件的实例所共享的数据(象在DLL中的全局数据一样)是脆弱的。这是因为你的全局DLL数据(同时为几个对象服务,分别运行在独立的线程中)会被那些多线程同时接触到。
虽然基于MFC的COM类总是可聚合的(内置了对它的支持),ATL ObjectWizard使得你可以指定你的控件支持聚合,只是可聚合的,或者是独立的对象。根据你选择的聚合选项,ATL ObjectWizard使用一个宏来执行聚合策略。例如,缺省的COM类的实现是可聚合的——对象将既运行在独立的模式,又作为一个聚合的一部分。如果你使你的COM对象不可聚合,ObjectWizard把DECLARE_NOT_ AGGREGATABLE宏加到你的类定义中。如果你选择了仅是可聚合的,ObjectWizard把DECLARE_ ONLY_AGGREGATABLE宏加入到类定义中。
这里是宏如何工作的。缺省的对象创建在一个名为_CreatorClass的类中发生。_CreatorClass当被加入到服务器范围的对象映射后(这是OBJECT_ENTRY宏所做的工作的一部分),就成为你的COM类的创建机制。_CreatorClass其实只是一个名为CComCreator2类的别名,此类将两个从CcomCreator类中定制的类作为参数。此宏根据选择的聚合模式来特制CcomCreator类,分别使用CComObject, CComAggObject, CComFailCreator, 或者CcomPolyObject:
#define DECLARE_NOT_AGGREGATABLE(x) public:
typedef CComCreator2< CComCreator< CComObject< x > >,
CComFailCreator<CLASS_E_NOAGGREGATION> > _CreatorClass;
#define DECLARE_AGGREGATABLE(x) public:
typedef CComCreator2< CComCreator< CComObject< x > >,
CComCreator< CComAggObject< x > > > _CreatorClass;
#define DECLARE_ONLY_AGGREGATABLE(x) public:
typedef CComCreator2< CComFailCreator<E_FAIL>,
CComCreator< CComAggObject< x > > > _CreatorClass;
#define DECLARE_POLY_AGGREGATABLE(x) public:
typedef CComCreator< CComPolyObject< x > > _CreatorClass;
ATL ObjectWizard Attributes页中最后三个检查框包括对COM例外处理的支持(例如,IsupportErrorInfo接口),连接点以及自由线程集(FTM)。你也可以添加IsupportErrorInfo到控件的继承列表中,提供ISupportErrorInfo::InterfaceSupportsErrorInfo的一个实现。打开连接点将添加IConnectionPointImpl 模板类到控件的继承列表中。
将你的控件聚合到FTM使得单元间(以及Windows 2000的上下文间)的调用更为频繁的发生,如果两个对象正好位于同一个进程中。然而,你在编写控件时不应该检查这一点,因为当你使用FTM的时候,你多少都违反了单元(以及Windows 2000的上下文)规则。关于FTM的更多细节,请参见Don Box的Effective COM (Addison-Wesley Longman, 1998)一书。
- ››创建SQL2005自动备份,定期删除的维护计划
- ››创建动态表单 javascript
- ››MFC中有多个slider时OnHScroll函数判断方法
- ››MFC自绘按钮
- ››创建基于PPTP的站点到站点VPN连接:ISA2006系列之...
- ››创建基于L2TP的站点到站点的VPN连接:ISA2006系列...
- ››创建一个Twisted Reactor TCP服务器
- ››创建Windows Mobile上兼容性好的UI 程序
- ››创建android的Service
- ››创建远古部落环境与原住民角色
- ››创建并扩展Apache Wicket Web应用
- ››创建不在任务条中显示窗口按钮的应用
更多精彩
赞助商链接