当前位置:首页 > OPC服务器与客户程序开发指南
else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); return TRUE; // ok
}
最后的四个函数如下:
STDAPI DllCanUnloadNow(void) {
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
STDAPI DllRegisterServer(void) {
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}
STDAPI DllUnregisterServer(void) {
return _Module.UnregisterServer(TRUE); }
这些函数除非调用_Module对象的合适的函数,什么也不做。有关这四个函数的详细说
明请参考有关COM书籍和MSDN。 2.4 添加组件对象
通过上面的介绍,开始对ATL有了一定的认识,下面为上面的应用程序添加一个COM组件,本节的主要目的是熟悉如何通过ATL添加组件对象。
最简单的添加组件的方法是通过ATL Object Wizard。从Insert菜单下选择New ATL Object...,你将看到图2.4所示的对话框。
图2.4 ATL Object Wizard
这里选择Simple Object,单击Next,图2.5所示的属性页显示出来,在这个属性页可以输入组件的名称和组件的属性。在Short Name编辑框里输入“BeepCnt”,也可以输入其它名字。输入“BeepCnt”其它七个编辑框的内容会自动生成。
图2.5 ATL Object Wizard Properties
单击属性页上的Attributes,出现图2.6所示的属性框,在这个框中可以选择组件相应的属性,本例中选择默认。单击OK。
图2.6 ATL Object Wizard Properties
Apartment Threading Model的意思是指这个对象可以被一个或者多个线程所调用。实际上每个COM对象的实例都是单线程的,需要注意的是假设COM对象有多个线程在调用它,如果在程序的方法中引用了全局变量,必须保证程序多个线程访问的安全问题。不管如何,只要引用了全局变量,需要考虑程序多线程访问时的安全问题,或者在此选择Single Threading Model.
在这里,选择Dual Interface,双重接口的意思是指创建的组件支持自定义接口,也支持自动化接口。自动化接口是用来支持脚本语言访问的接口,考虑到客户程序自动化的实现比自定义的实现简单的多,所以选择了双接口的方式。
Aggregation,汉语意思为聚合。包容和聚合是COM的两种重要类型。聚合是指组件对象一种特殊的包容方法,在一个组件对象里面可以拥有另外的组件对象。一般而言,采用COM自己实现聚合的的方式是复杂的,而ATL可以帮助我们操作聚合的实现。如果组件支持聚合,那么组件将是更加灵活的,因此我们选择支持聚合。
ISupportErrorInfo,创建 ISupportErrorInfo 接口支持,以便对象可将错误信息返回到客户端。我们不选择它。
Connection Points,连接点用来支持事件,通过使对象的类从 IConnectionPointContainerImpl 导出来启用对象的连接点,连接点用来支持事件,所谓事件是指COM对象中当某个属性发生改变时,对象产生一个事件,通知到客户程序,客户程序可以处理这些事件。本例中,不选择连接点。
Free-Threaded Marshaller,自由线程封送拆收器,创建自由线程封送拆收器对象,以有效地在同一进程中的两个线程之间封送接口指针。对指定“两者”或“自由”作为线程模型的对象可用。用于多线程控制的特定类型。本例中,不选择它。
创建完成后的组件对象由于支持双接口(自动化接口,自定义接口),聚合,多线程访问,因此它是一个简单但是易于扩展的组件。
现在工程中又多了两个ATL对象向导创建的文件:beepcnt.cpp和beepcnt.h。beepcnt.cpp基本上是空的,因为没有为组件对象添加任何的属性。所有将来添加的对象方法和属性都将在这个文件中实现。
beepcnt.h包含了对象的类的定义。
class ATL_NO_VTABLE CBeepCnt :
public CComObjectRootEx &LIBID_BEEPCNTMODLib> { public: CBeepCnt() { } DECLARE_REGISTRY_RESOURCEID(IDR_BEEPCNT) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CBeepCnt) COM_INTERFACE_ENTRY(IBeepCnt) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() // IBeepCnt public: };
共分享92篇相关文档