ImageVerifierCode 换一换
你正在下载:

COM培训.ppt

[预览]
格式:PPT , 页数:65 ,大小:405.50KB ,
资源ID:456004      下载积分:12 文钱
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,省得不是一点点
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenke99.com/d-456004.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(COM培训.ppt)为本站会员(ga****84)主动上传,文客久久仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文客久久(发送邮件至hr@wenke99.com或直接QQ联系客服),我们立即给予删除!

COM培训.ppt

1、COM:可连接对象 & 结构化存储,潘爱民http:/ *p;p-,聚合模型的关键,可连接对象(connectable object),内容:可连接对象结构模型实现可连接对象(源对象)客户-源对象-接收器的协作过程可连接对象的程序实现,双向通信机制 客户与可连接对象的关系,两个概念,入接口(incoming interface)组件对象实现入接口,客户通过入接口调用对象提供的功能客户和组件都需要知道接口的类型信息出接口(outgoing interface)客户端提供的COM对象实现出接口组件端的对象通过出接口调用客户提供的功能组件提供接口类型信息,客户实现该接口类似于回调(callback)

2、,但是要复杂和灵活得多,出接口,类型信息由组件一方提供客户提供出接口的实现,实现出接口的COM对象被称为接收器对象(sink)sink没有CLSID,也不需要类厂也是一个COM接口,有IID每个成员函数代表了:事件event通知notification请求request,源对象 or 可连接对象,Connectable object,source普通的COM对象,支持一个或者多个出接口提供出接口的类型信息通过IProvideClassInfo2接口通过typelib,客户与可连接对象之间的两种结构,可连接对象的基本结构,可连接对象,如何管理多个出接口每个出接口对应一个连接点对象通过连接点枚举器

3、管理对于每个出接口,如何管理多个客户连接通过连接枚举器管理多个连接,实现可连接对象(源对象)(一),枚举器内部对象,不需要类厂和CLSID其含义就如同指针智能指针枚举器接口模板class IEnum : public IUnknownvirtual HRESULT Next( ULONG celt, ELT_T *rgelt, ULONG *pceltFetched ) = 0;virtual HRESULT Skip( ULONG celt ) = 0;virtual HRESULT Reset( void ) = 0;virtual HRESULT Clone( IEnum*ppenum

4、) = 0;,枚举器的用法,class IStringManager : public IUnknown virtual IEnumString* EnumStrings(void) = 0;void SomeFunc(IStringManager * pStringMan) String psz; IEnumString * penum; penum=pStringMan-EnumStrings(); while (S_OK = penum-Next(1, ,实现可连接对象(源对象)(二),IConnectionPointContainer接口class IConnectionPointCo

5、ntainer : public IUnknown virtual HRESULT EnumConnectionPoints(IEnumConnectionPoints *) = 0; virtual HRESULT FindConnectionPoint(const IID *, IConnectionPoint *) = 0;IEnumConnectionPoints接口class IEnumConnectionPoints : public IUnknownvirtual HRESULT Next( ULONG cConnections, IConnectionPoint *rgpcn,

6、 ULONG *pcFetched) = 0; virtual HRESULT Skip( ULONG cConnections) = 0;virtual HRESULT Reset(void) = 0;virtual HRESULT Clone( IEnumConnectionPoints *ppEnum) = 0;,实现可连接对象(源对象)(三),连接点和IConnectionPoint接口class IConnectionPoint : public IUnknown virtual HRESULT GetConnectionInterface( IID *pIID) = 0; virt

7、ual HRESULT GetConnectionPointContainer( IConnectionPointContainer *ppCPC) = 0; virtual HRESULT Advise( IUnknown *pUnk, DWORD *pdwCookie) = 0; virtual HRESULT Unadvise( DWORD dwCookie) = 0; virtual HRESULT EnumConnections(IEnumConnections*ppEnum) = 0; ;连接枚举器 实现IEnumConnections接口允许多个客户连接每个连接用struct C

8、ONNECTDATA来描述,回顾:可连接对象的基本结构,客户与源对象建立连接过程,客户请求IConnectionPointContainer接口客户调用IConnectionPointContainer:FindConnectionPoint找到连接点对象客户调用IConnectionPoint:Advise建立与接收器的连接最后,客户调用IConnectionPoint:Unadvise取消连接,并释放连接点对象,客户方基本结构,客户方实现接收器对象(sink)支持多个与可连接对象之间的连接一般只实现专用的出接口(IUnknown除外)不需要类厂、CLSID与客户代码紧密连接起来建立连接1

9、通过IConnectionPointContainer接口找到连接点对象2 通过连接点对象建立连接连接点相当于连接管理器,接收器的实现,class CSomeEventSet : public ISomeEventSet private: ULONG m_cRef; / Reference count . / other private data members public: DWORD m_dwCookie; / Connection key public: CSomeEventSet (); CSomeEventSet(void); /IUnknown members STDMETHOD

10、IMP QueryInterface(REFIID, PPVOID); STDMETHODIMP_(DWORD) AddRef(void); STDMETHODIMP_(DWORD) Release(void); STDMETHODIMP SomeEventFunction ( . ); .;,接收器的用法,ISomeEventSet *gpSomeEventSet;./ InitializeCSomeEventSet *pSink = new CSomeEventSet;pSink-QueryInterface(IID_ISomeEventSet, pSomeEventSet ); / Re

11、ference count is 1./ connections the sink object to the connectable object we havehr=pConnectionPoint-Advise(pSomeEventSet , / Reference count is 0,事件的激发和处理,BOOL CSourceObject:FireSomeEvent(IConnctionPoint *pConnectionPoint) IEnumConnections *pEnum; CONNECTDATA connectionData; if (FAILED(pConnection

12、Point-EnumConnections(,与出接口有关的类型信息,客户如何知道出接口?运行时刻?编译时刻?动态构造接收器对象?动态构造vtable?支持部分成员?类型信息的协商通过IProvideClassInfo2能否用标准的接口作为出接口?,用IDispatch接口作为出接口(一),IDispatch接口class IDispatch : public IUnknown public: virtual HRESULT GetTypeInfoCount( UINT *pctinfo) = 0; virtual HRESULT GetTypeInfo( UINT iTInfo, LCID

13、lcid, ITypeInfo *ppTInfo) = 0; virtual HRESULT GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) = 0; virtual HRESULT Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *p

14、uArgErr) = 0;,用IDispatch接口作为出接口(二),IDispatch出接口的事件激发函数,void CMySourceObj:FireMyMethod (short nInt)COleDispatchDriver driver;POSITION pos = m_xMyEventSet.GetStartPosition();LPDISPATCH pDispatch;while (pos != NULL) pDispatch = (LPDISPATCH) m_xMyEventSet.GetNextConnection(pos);ASSERT(pDispatch != NULL)

15、;driver.AttachDispatch(pDispatch, FALSE);TRYdriver.InvokeHelper(eventidMyMethod, DISPATCH_METHOD, VT_EMPTY, NULL,(BYTE *) (VTS_I2), nInt);END_TRYdriver.DetachDispatch();,用连接点机制实现回调的讨论,比传统的回调函数功能强大,灵活可以跨进程、跨机器Tightly coupled vs loosely coupled (COM+)要求客户与组件同步没有第三方的参与,所以双方必须保持共识,MFC对连接和事件的支持,用MFC实现源对象

16、,创建工程支持COM定义出接口编辑.odl文件利用MFC宏加入连接点声明以及连接点对象的定义在对象构造函数中调用EnableConnections();在接口映射表中加入接口IConnectionPointContainer的表项,再加入连接映射表定义连接点类的虚函数(至少为GetIID)加入事件激发函数,用MFC在客户程序中实现接收器,初始化 AfxOleInit定义出接口成员类实现出接口成员类创建源对象建立连接和取消连接完成可触发事件的动作,用MFC实现的例子,ATL实现可连接对象,在IDL中定义一个用作出接口的automation接口在coclass中加入出接口,含source属性增加I

17、ConnectionPointContainer接口在基类列表中增加IConnectionPointConntainerImpl在COM MAP中加入COM_INTERFACE_ENTRY(IConnectionPointConntainer),模板类IConnectionPointImpl,CMyClass继承IConnectionPointImpl一次或多次IConnectionPointImpl实现了独立的引用计数用法:在基类列表中增加IConnectionPointImpl加入connection point map,如下BEGIN_CONNECTION_POINT_MAP(CMyCl

18、ass)CONNECTION_POINT_ENTRY(DIID_IEventSet)END_CONNECTION_POINT_MAP(),激发事件辅助函数,手工激发事件IConnectionPointImpl包含一个m_vec成员,内含所有已经建立的接收器连接遍历m_vec数组,逐一调用Invoke函数利用VC IDE提供的源码产生工具ATL连接点代理生成器,启动对话框Implement Connection Point产生名为CProxy_的模板类例如CProxy_IEventSet,它从IConnectionPointImpl派生对于每一个事件或者请求,都有一个对应的Fire_Xxx成员函

19、数用模板类代替IConnectionPointImpl基类,Implement Connection Point对话框,创建对象时选择Connection PointClassView中,在对象类上右键点击选择此项功能,ATL实现连接点:最后的工作,在需要激发事件的地方调用CProxy_提供的辅助函数增加对IProvideClassInfo2接口的支持需要typelib的支持加入基类IProvideClassInfo2Impl在COM MAP中加入:COM_INTERFACE_ENTRY(IProvideClassInfo2)COM_INTERFACE_ENTRY(IProvideClassI

20、nfo),ATL实现接收器sink,IDispEventSimpleImpl轻量,不需要typelib的支持IDispEventImpl需要typelib的支持Event Sink MapBEGIN_SINK_MAP(CMyCLass)SINK_ENTRY_EX(.)/ 适合用于non-UI objectSINK_ENTRY(.) / 适合用于UI objectEND_SINK_MAP,ATL:建立sink和source之间的连接,IDispEventSimpleImpl成员DispEventAdviseDispEventUnadviseAtlAdviseSinkMap建立sink与sourc

21、e缺省源接口的连接,VB中使用出接口,使用浏览器控件的事件函数使两个窗口同步,结构化存储(structured storage),内容:结构化存储模型复合文档永久对象,问题的由来,文件系统的诞生多个应用程序共享同一个存储设备文件服务功能的抽象进展到结构化存储多个组件共享同一个文件组件软件存储功能的基本要求OLE的需求组件共享句柄方案,如何定位?避免冲突?,文件系统结构,结构化存储,多个组件程序共享一个复合文件,复合文件,文件内部的文件系统只有两种对象:存储对象和流对象实现了部分访问和增量访问的功能,流对象,COM库提供实现,实现了IStream接口class IStream : public

22、IUnknownpublic :virtual HRESULT Read (void *pv, unsigned long cb, unsigned long *pcbRead) = 0;virtual HRESULT Write (void *pv, unsigned long cb, unsigned long *pcbWritten) = 0;virtual HRESULT Seek (LARGE_INTEGER dlibMove, unsigned long dwOrigin,ULARGE_INTEGER *plibNewPosition) = 0;virtual HRESULT Se

23、tSize (ULARGE_INTEGER libNewSize) = 0;virtual HRESULT CopyTo (LPSTREAM pStm, ULARGE_INTEGER cb,ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) = 0;virtual HRESULT Commit (unsigned long dwCommitFlags) = 0;virtual HRESULT Revert ()= 0;virtual HRESULT LockRegion (ULARGE_INTEGER libOffset, ULARGE_I

24、NTEGER cb,unsigned long dwLockType) = 0;virtual HRESULT UnlockRegion (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,unsigned long dwLockType) = 0;virtual HRESULT Stat (STATSTG *pStatStg, unsigned long grfStatFlag) = 0;virtual HRESULT Clone(LPSTREAM * ppStm) = 0;,存储对象,COM库提供实现,实现了IStorage接口class IStora

25、ge : public IUnknownvirtual HRESULT CreateStream (const WCHAR * , unsigned long , LPSTREAM * ) = 0;virtual HRESULT OpenStream (const WCHAR * , unsigned long , LPSTREAM * ) = 0;virtual HRESULT CreateStorage (const WCHAR * , unsigned long ,LPSTORAGE * ) = 0; virtual HRESULT OpenStorage (const WCHAR* ,

26、 LPSTORAGE *, unsigned long , SNB , unsigned long , LPSTORAGE * ) = 0;virtual HRESULT CopyTo(unsigned long , IID const *, SNB snbExclude, LPSTORAGE * pStgDest) = 0;virtual HRESULT MoveElementTo(const WCHAR * , LPSTORAGE *,char const * , unsigned long ) = 0;virtual HRESULT Commit (unsigned long ) = 0

27、;virtual HRESULT Revert ()= 0;virtual HRESULT EnumElements (unsigned long , void *,unsigned long , LPENUMSTATSTG * ) = 0;virtual HRESULT DestroyElement (const WCHAR * pwcsName) = 0;virtual HRESULT RenameElement (const WCHAR * pwcsOldName, const WCHAR * pwcsNewName) = 0;virtual HRESULT SetElementTime

28、s(const WCHAR *,FILETIME const *,FILETIME const*,FILETIME const *) = 0;virtual HRESULT SetClass (REFCLSID rclsid) = 0;virtual HRESULT SetStateBits (unsigned long grfStateBits, unsigned long grfMask) = 0;virtual HRESULT Stat (STATSTG *pStatStg, unsigned long grfStatFlag) = 0;,客户如何获取存储对象和流对象,如何得到指向根存储

29、对象的接口指针?CreateStorage和OpenStorage成员函数得到一个子存储对象,是唯一的途径CreateStream和OpenStream成员函数得到一个流对象,也是唯一的途径,用结构化存储设计应用(一),用普通文件组织的文档结构,用结构化存储设计应用(二),复合文件格式的文档结构,结构化存储特性访问模式,STGM_CREATESTGM_CONVERTSTGM_FAILIFTHERESTGM_DELETEONRELEASESTGM_DIRECTSTGM_TRANSACTEDSTGM_PRIORITYSTGM_READSTGM_WRITESTGM_READWRITESTGM_SHA

30、RE_DENY_READSTGM_SHARE_DENY_WRITESTGM_SHARE_EXCLUSIVESTGM_SHARE_DENY_NONE,结构化存储特性事务机制,数据一致性和完整性操作:Commit、Revert事务嵌套:以STGM_TRANSACTED标志为基础事务机制需要消耗较多系统资源Commit参数:STGC_DEFAULTSTGC_OVERWRITESTGC_ONLYIFCURRENTSTGC_DANGEROUSLYCOMMITMERELYTODISKCACHE,结构化存储特性命名规则,根存储对象的名字遵守文件系统的命名约定长度不超过32个字符首字符使用大于32的字符,小于

31、32的字符作为首字符有特殊意义不能使用字符“”、“/”、“:”和“!”名字“.”和“.”被保留名字保留大小写,但比较操作大小写无关,结构化存储特性增量访问,减少保存和打开文件的时间降低了应用程序对系统资源的要求问题:通过根存储逐层找到目标对象空间回收,复合文档,结构化存储的具体实现底层机制:LockBytes对象把存储介质描述成一般化的字节序列复合文档API函数零内存保存特性,复合文档模型,root,LockBytes对象,ILockBytes接口class ILockBytes : public IUnknownpublic :virtual HRESULT ReadAt (ULARGE_I

32、NTEGER , VOID *pv, unsigned long ,unsigned long *) = 0;virtual HRESULT WriteAt (ULARGE_INTEGER , VOID *pv, unsigned long ,unsigned long *) = 0; virtual HRESULT Flush ()= 0;virtual HRESULT SetSize (ULARGE_INTEGER cb) = 0;virtual HRESULT LockRegion (ULARGE_INTEGER , ULARGE_INTEGER ,unsigned long ) = 0

33、;virtual HRESULT UnlockRegion (ULARGE_INTEGER , ULARGE_INTEGER ,unsigned long ) = 0;virtual HRESULT Stat (STATSTG *, unsigned long ) = 0;,复合文档API函数,创建复合文档的API函数StgCreateDocfile、StgCreateDocfileOnILockBytes打开复合文档的API函数StgOpenStorage、StgOpenStorageOnILockBytes与内存句柄有关的一组操作函数CreateILockBytesOnHGlobal、Ge

34、tHGlobalFromILockBytesCreateStreamOnHGlobal、GetHGlobalFromStream其他,零内存保存特性,意义:资源耗尽之后,保留修改信息资源预留,对于所有的流对象和存储对象“Save”操作,只要调用Commit函数即可“Save As”操作,利用根存储对象上的IRootStorage接口,调用SwitchToFile成员函数,再调用Commit函数即可。,与CLSID的联系,IStorage:SetClass函数把存储对象与CLSID联系起来GetClassFile函数,从文件到CLSID:复合文件,直接得到根存储的CLSID非复合文件:(1) 文

35、件扩展名-ProgID-CLSID(2) HKEY_CLASSES_ROOTFileType键提供了匹配规则:HKEY_CLASSES_ROOT FileType = , = ,复合文档与COM的关系,复合文档技术以COM为基础应用程序在处理复合文档时把storage或stream直接交给COM组件来处理COM组件接受storage或stream作为数据存储多个组件协同处理同一个文件-永久对象,永久对象,永久对象实现了IPersistXXX接口的COM对象永久接口:class IPersist : public IUnknownclass IPersistStream : public IPersistclass IPersistStreamInit : public IPersistclass IPersistFile : public IPersistclass IPersistStorage : public Ipersist永久接口的成员函数:GetClassID、IsDirty、Load和Save,.永久对象可以实现多个永久接口,但使用时要保持一致性,永久对象用法,永久对象与结构化存储模型结合永久对象例子用MFC实现的COM对象功能:永久状态为一段文本,使用永久接口对文本维护实现了IPersistStream和一个自动化接口,复合文档例子,复合文档查看工具,

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。