WEB开发网
开发学院软件开发VC 用ATL和MFC来创建ActiveX控件 阅读

用ATL和MFC来创建ActiveX控件

 2010-07-25 20:46:35 来源:WEB开发网   
核心提示:用ATL开发一个控件有了基于MFC的控件,你就可以用ATL COM App Wizard得到一个开发基于ATL的控件的触发器,用ATL和MFC来创建ActiveX控件(4),使用ATL来创建控件可以分为两步,虽然MFC的Control Wizard要求你预先确定你希望在DLL中包含多少个控件,你多少都违反了单元(以及W

用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)一书。

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:ATL MFC 创建

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接