十五 统一数据传输 数据格式 数据对象和IDataObject接口 通报连接机制 通过剪贴板传输数据 MFC对数据对象的支持

Slides:



Advertisements
Similar presentations
7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
Advertisements

NAT与ICMP交互.
第三章 数据类型和数据操作 对海量数据进行有效的处理、存储和管理 3.1 数据类型 数据源 数据量 数据结构
Oracle数据库 Oracle 子程序.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
第九章 字符串.
Hadoop I/O By ShiChaojie.
八. COM跨进程特性 进程外组件 列集 标准列集过程 总体结构 存根 代理 接口列集器 ORPC通道 标准列集的实现 自定义列集
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
十四. 名字对象 概念 IMoniker接口 名字对象的创建 根据显示名创建名字对象 类名字对象的创建 其他名字对象的创建
6.4 Notification 通知栏.
存储系统.
管理信息结构SMI.
辅导课程六.
网络游戏开发语言基础 ——Windows程序设计
五 COM对象 接口及其接口方法的实现 注册表 类厂 COM组件与客户程序的交互过程 类厂的由来 类厂的定义与实现 类厂的创建
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
文件读写实践 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
第十章 IDL访问数据库 10.1 数据库与数据库访问 1、数据库 数据库中数据的组织由低到高分为四级:字段、记录、表、数据库四种。
十二. 可连接对象 概念与模型 轮询 通知 出接口 连接点机制 IConnectionPointContainer接口
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
逆向工程-汇编语言
如何生成设备节点 广州创龙电子科技有限公司
泛型委托 泛型接口、方法和委托.
COM:moniker、UDT、control
Windows 7 的系统设置.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
潘爱民 COM:可连接对象 & 结构化存储 潘爱民
DevDays ’99 The aim of this mission is knowledge..
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第一章 函数与极限.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
VisComposer 2019/4/17.
第二章 Java基本语法 讲师:复凡.
VB与Access数据库的连接.
分裂对象模型 C++ otcl.
实验七 安全FTP服务器实验 2019/4/28.
Select模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
_08文件的基本操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
本节内容 内存复制指令 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
3.16 枚举算法及其程序实现 ——数组的作用.
《手把手教你学STM32-STemWin》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
_13简单的GDI绘图操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
数据报分片.
Chapter 18 使用GRASP的对象设计示例.
第4课时 绝对值.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
Visual Basic程序设计 第13章 访问数据库
#include <iostream.h>
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
WSAAsyncSelect 模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang
1.4WIN32中的宽字符.
阻塞式模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
本节内容 this指针 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
《手把手教你学STM32-STemWin》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
DSP技术与应用 电子与信息技术系.
多个Activity的使用 本讲大纲: 1、使用Bundle在Activity之间交换数据 2、调用另一个Activity并返回结果
学习目标 1、什么是列类型 2、列类型之数值类型.
Presentation transcript:

十五 统一数据传输 数据格式 数据对象和IDataObject接口 通报连接机制 通过剪贴板传输数据 MFC对数据对象的支持 十五 统一数据传输 数据格式 数据对象和IDataObject接口 通报连接机制 数据变化通报机制. 数据变化通知的实现方式 通过剪贴板传输数据 MFC对数据对象的支持

1 数据格式 COM提供了UDT(Uniform Data Transfer)作为应用系统之间的数据交换方案。 1 数据格式 COM提供了UDT(Uniform Data Transfer)作为应用系统之间的数据交换方案。 COM之前的数据传输:剪贴板, DDE 局限性: 1。数据格式限制。只能使用预定义的几种格式 2。被传输的数据只能位于全局内存中。 3。没有双向通讯机制。 4。数据格式与传输协议相关。 COM使用数据对象作为数据实体,数据对象通过IDataObject接口暴露其内部信息。数据的传递变成了数据对象的创建和接口指针的传递。 (永久对象,数据对象,都是COM对象,都有状态.) UDT 定义了两个数据结构FORMATETC 和STGMEDIUM分别描述数据格式和存储介质以适应广泛的数据类型和存储介质。且提供了双向通讯机制。 数据对象可以称为应用之间交换信息的标准。数据对象的IDataObject接口指针。统一的方式访问、操作。 数据对象的操作过程频繁地使用了如下的两个数据结构:

typedef struct tagFORMATETC { CLIPFORMAT cfFormat; DVTARGETDEVICE *ptd; DWORD dwAspect; LONG lindex; DWORD tymed; }FORMATETC 1。CLIPFORMAT cfFormat; 数据格式。预定义的数据格式. UINT RegisterClipboardFormat( LPCTSTR lpszFormat // name of new format ); 可以创建新的数据格式。 2。ptd指向DVTARGETDEVICE数据结构 typedef struct tagDVTARGETDEVICE { DWORD tdSize; //结构长度 WORD tdDriverNameOffset; // 设备驱动名 WORD tdDeviceNameOffset;// 设备名 WORD tdPortNameOffset; // 端口名 WORD tdExtDevmodeOffset; // DEVMODE结构 BYTE tdData[ 1 ]; } DVTARGETDEVICE;

3。dwAspect 是一个枚举,指定图形数据的显示方式 enum tagDVASPECT { DVASPECT_CONTENT = 1, DVASPECT_THUMBNAIL = 2, DVASPECT_ICON = 4, DVASPECT_DOCPRINT = 8 } DVASPECT; 4。lindex为dwAspect的补充。 5。tymed指定存储介质。可以指定全局内存、磁盘文件、或者存储对象等。 另一个常用的结构如下: typedef struct tagSTGMEDIUM { DWORD tymed; union { HBITMAP hBitmap; HMETAFILEPICT hMetaFilePict; HENHMETAFILE hEnhMetaFile; HGLOBAL hGlobal; LPOLESTR lpszFileName; IStream *pstm; IStorage *pstg; } u; IUnknown *pUnkForRelease; }STGMEDIUM;

1。其中tymed指明介质的类型。 typedef enum tagTYMED { TYMED_HGLOBAL = 1, TYMED_FILE = 2, TYMED_ISTREAM = 4, TYMED_ISTORAGE = 8, TYMED_GDI = 16, TYMED_MFPICT = 32, TYMED_ENHMF = 64, TYMED_NULL = 0 } TYMED; 2。联合成员u指明数据的真正位置,根据tymed的值使用相应的联合成员。 3。pUnkownForRelease用来控制数据的释放过程。 应用程序可以选择合适的存储介质来传输数据。 这两个数据结构用于数据对象的各种操作之中.

2 数据对象和IDataObject接口 数据对象是一个COM对象,它实现了IDataObject接口。一旦应用程序创建了一个数据对象,此对象可以通过任一种传输协议传递到另一个应用。通过协议传送的实际上是IDataObject接口指针。(此传输协议使用了接口的列集,散集过程) .发送、接受双方都使用IDataObject接口来操作数据。 接口的定义如下: class IDataObject : public IUnknown { public: virtual HRESULT GetData( FORMATETC *pformatetcIn, [in] STGMEDIUM *pmedium [out] ) = 0; /*接受程序通过传输协议得到数据对象的接口指针后,在 pFormatetc中指定提取数据所使用的格式,并把数据放在pmedium 指针中。如果数据对象有我们所指定的格式,GetData会填充pmedium,否则出错返回。*/ virtual HRESULT GetDataHere( FORMATETC *pformatetc, [in] STGMEDIUM *pmedium [in, out] ) = 0; /*同GetData,但是,接受方也要负责预先分配存储空间pmedium*/

virtual HRESULT QueryGetData( FORMATETC *pformatetc [in]) = 0; /*询问数据对象是否支持pFormatetc数据格式,如果支持的话,再调用GetData会更好。*/ virtual HRESULT GetCanonicalFormatEtc( FORMATETC *pformatectIn, [in] FORMATETC *pformatetcOut [out]) = 0; /*提供一个标准的等价的FORMATETC结构。据此判断不同的FORMATETC结构能否得到同样的数据,以免重复调用GetData。*/ virtual HRESULT SetData( FORMATETC *pformatetc, [in] STGMEDIUM *pmedium, [in] BOOL fRelease [in]) = 0; /*接收方客户程序为数据对象提供数据。 */ virtual HRESULT EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC * *ppenumFormatEtc) = 0; /*返回一个数据格式枚举器,可以枚举该数据对象所支持的数据格式。*/

virtual HRESULT DAdvise( FORMATETC. pformatetc,DWORD advf,IAdviseSink virtual HRESULT DAdvise( FORMATETC *pformatetc,DWORD advf,IAdviseSink *pAdvSink, [in] DWORD *pdwConnection [out]) = 0; /*在客户的通报接收器(advisory sink)和数据对象之间建立一个通报连接(advisory connection),当数据对象中的数据发生变化时,它可以通知客户程序的通报连接器。 pdwConnection保留连接标志,以便客户解除连接使用。*/ virtual HRESULT DUnadvise( DWORD dwConnection [in] ) = 0; /*利用DAdvise函数返回的连接标志解除连接。*/ virtual HRESULT EnumDAdvise( IEnumSTATDATA **ppenumAdvise) = 0; /*返回一个STATDATA结构的枚举器。 STATDATA结构正好与DAdvise函数的参数一一对应*/ };

3 通报连接机制 3.1 数据变化通报机制. 客户得到IDataObject指针,可以读取数据,然而客户希望在数据改变的时候能及时得到通知,而不是一遍遍地轮询。要求数据对象在数据变化时能主动通知客户,客户应提供一个接收器以接受这些通知。 COM提供了连接点机制以实现双向通讯。 在UDT中,客户程序只需实现IAdviseSink接口: class IAdviseSink :public IUnkown { pulbic: virtual void OnDataChange(FORMATETC*pformatetc,STGMEDIUM *pmedium)=0; ......} 而数据对象作为源对象并没有实现IConnectionPointContainer接口,而是直接使用IDataObject的后三个成员函数 代替IConnectionPoint接口的Advise,UAdvise,和EnumConnections。 之所以可以这样简化,是因为在数据对象和客户的交互过程中,出接口以及其成员函数可以事先定下来,而且功能也很清楚。比较 IConnectionPoint的Advise的连接函数:

virtual HRESULT Advise( IUnknown *pUnkSink, DWORD *pdwCookie) = 0; 处理通用的连接。 IDataObject的DAdvise函数除了直接指定IAdviseSink接口以外(而不是含糊的IUnkown接口),同时指定了客户方感兴趣的数据格式pformtec,以及通报的方式advf。(见p284)。 使用方式: 数据对象方:可以使用诸如MFC的实现,见后. 接收方:客户程序实现IAdviseSink接口,当然指定OnDataChanged等函数, 然后在得到数据对象指针后,通过IDataObject调用DAdvise函数,将刚才的IAdviseSink接口传入,以响应数据变化通知. 客户 数据对象 通报连接接收器 客户把接收器的 接口指针传给对象 数据改变时,数据对象调用 OnDataChange成员 IDataObject IAdviseSink

3.2 数据变化通知的实现方式: 数据对象对连接的实现方式可以按照连接点机制中类似的方法来进行. COM提供了“数据通报控制器” (data advise holder)这个内部对象(没有类厂,没有CLSID)以简化这个工作. WINOLEAPI CreateDataAdviseHolder( IDataAdviseHolder **ppDAHolder ); 其中IDataAdviseHolder接口的定义 class IDataAdviseHolder : public IUnknown { public: virtual HRESULT Advise( IDataObject *pDataObject,FORMATETC *pFetc, DWORD advf,IAdviseSink *pAdvise, DWORD *pdwConnection) = 0; virtual HRESULT Unadvise(DWORD dwConnection) = 0; virtual HRESULT EnumAdvise( EnumSTATDATA * *ppenumAdvise) = 0; virtual HRESULT SendOnDataChange( IDataObject *pDataObject, DWORD dwReserved,DWORD advf) = 0; };

数据对象利用CreateDataAdviseHolder创建一个数据通报控制器对象,并返回一个IDataAdviseHolder 接口。 HRESULT MyDataObject::DAdvise(FORMATETC *pformatetc,DWORD advf,IAdviseSink *pAdvSink,DWORD *pdwConnection) { return pDAHolder->Advise((IDataObject*)this, FORMATETC *pformatetc,DWORD advf,IAdviseSink *pAdvSink,DWORD *pdwConnection ); } 其他两个函数的参数都一一对应。 当数据对象要调用它所连接的接收器sink的OnDataChange函数时,就把自己的IDataObject接口指针和通知方式标志advf一起传给IDataAdviseHolde::SendOnDataChange函数。在数据通报控制器内部,记录了所有通过Advise函数建立的sink的接口指针。数据通报控制器接收到调用后,检查连接标志,找到相应的advise sink,然后调用IAdviseSink::OnDataChange函数。

4 通过剪贴板传输数据 我们需要能传输数据对象接口指针的传输机制。 4 通过剪贴板传输数据 我们需要能传输数据对象接口指针的传输机制。 剪贴板机制是Windows上一种IPC机制。它是全局共享的资源。WIN32有一组API进行剪贴板操作。 p287列出了常用的几个。 OLE对剪贴板进行了扩充,称为“OLE剪贴板”,使之可以作为数据对象的传输通道。 WINOLEAPI OleSetClipboard(IDataObject * pDataObj ); 数据提供方向ole剪贴板上放数据对象 WINOLEAPI OleGetClipboard(IDataObject ** ppDataObj ); 数据接收方从ole剪贴板上得到数据对象接口指针 WINOLEAPI OleFlushClipboard( ); 清理剪贴板 WINOLEAPI OleIsCurrentClipboard(IDataObject * pDataObject ); 判断某数据对象是否在剪贴板上。 其他的数据传输机制也可以传输数据对象.

5 MFC对数据对象的支持 MFC提供了两个类COleDataSource (使用于数据提供方)和COleDataObject(使用于数据接收方) 实现了IDataObject接口。 COleDataSource 常用的成员函数 P290 CacheData 在数据对象的缓冲区中插入数据 SetCLipboard 调用OleSetCLipboard函数把数据对象放到剪贴板上。 DoDragDrop 对拖放的支持。 COleDataObject常用的成员函数。 AttachClipboard 把当前剪贴板上的数据对象与COleDataObject的数据成员m_lpDataObject联系起来。 Detach 解除联系 GetData 指定FORMATETC格式,准备STGMEDIUM指针后调用IDataObject::GetData,取回的数据存放在STGMEDIUM指针中。

源程序 客户程序 剪贴板 IDataObject 格式1 格式2 MFC应用处理剪贴板 原始数据 目标数据 COleDataSource 对象 格式1 格式2 客户程序 目标数据 m_lpDataObject IDataObject 剪贴板 复制 SetClipboard 粘贴 AttachClipboard 调用CacheGlobalData 或CacheData 调用GetGlobalData 或GetData MFC应用处理剪贴板

例子: 发送方: COleDataSource* pSource = new COleDataSource();//创建数据对象 ... HGLOBAL hHeader = ::GlobalAlloc(GMEM_SHARE, nHeaderSize + nImageSize); pSource->CacheGlobalData(CF_DIB, hHeader); //缓冲数据 pSource->SetClipboard(); //数据对象放到剪贴板上 接收方: ...... COleDataObject dataObject; //创建数据对象 dataObject.AttachClipboard();//数据对象与剪贴板相连 HGLOBAl hDib=dataObject.GetGlobalData(CF_DIB); //读取数据