设为首页 加入收藏

TOP

使用Visual C++实现OLE剪贴板(1)
2013-10-06 23:42:28 来源: 作者: 【 】 浏览:60
Tags:使用 Visual 实现 OLE 剪贴板

一、概述 < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Windows操作系统中存在两种剪贴板机制:Windows标准剪贴板和OLE剪贴板机制。

 

标准的Windows剪贴板是一个被所有Windows应用程序共享的系统服务,因此它并没有自己的句柄或类。但你可以通过CWnd类的成员函数来管理剪贴板。

 

自从OLEObject Linking and Embedding,对象链接和嵌入)诞生之后,Windows操作系统中便出现了第二种剪贴板机制——OLE剪贴板机制。标准的Windows剪贴板APIApplication Programming Interface,应用程序编程(www.cppentry.com)接口)依然可用,但是他已经被OLE数据传输机制来实现了。OLE支持UDTUniform Data Transfer,统一数据传输),并可以通过拖放操作实现剪贴板的剪切、复制和粘贴等操作。OLE剪贴板除了拥有标准Windows剪贴板的性能外,还支持传输用户自定义的剪贴板格式,并能够在传输数据时绑定OLE格式(如字体、字号等)。OLE剪贴板机制将成为更为主要的数据传输机制。

 

本文将简要叙述标准Windows剪贴板的实现,并将重点放在讨论如何通过Visual C++(www.cppentry.com)实现OLE剪贴板上。

 

二、选择适当的剪贴板机制

 

在选择使用何种剪贴板机制时通常应遵循下面的原则:如果应用程序在将来又可能具有新的性能(比如现在只需要传输纯文本,但将来有可能需要另外传输字体等特性),那么使用OLE剪贴板。

如果你正在使用一个OLE应用程序,或者你希望使用任何OLE特性(如拖放等)那么你应当使用OLE剪贴板机制。

如果你提供了OLE格式(如字体、字号等),那么使用OLE剪贴板机制。

 

三、使用Windows标准剪贴板

 

大多数Windows下的应用程序支持剪切或复制数据到Windows剪贴板中以及从剪贴板粘贴数据至目的地。在这个过程中,剪贴板数据格式在多种应用程序之间发生了变化。系统构架仅仅通过实现一些有限的类来支持一些有限的剪贴板格式,下表列出了Windows标准剪贴板支持的格式(第一列将在下面的程序代码中使用)。

 

             含义

CF_BITMAP      一个对应于位图的句柄(HBITMAP)。

CF_DIB         一个包含BITMAPINFO结构并且

跟着位图数据的内存对象。

CF_DIF         数据交互格式

CF_DSPBITMAP   有一个私有格式的位图显示格式。

CF_DSPENHMETAFILE      有一个私有格式的增强的元文件的显示格式。

CF_DSPMETAFILEPICT     有一个私有格式的元图显示格式。

CF_DSPTEXT     有一个私有格式的文本显示格式。

CF_ENHMETAFILE 一个增强的元文件(HENHMETAFILE结构)的句柄。

CF_GDIOBJFIRST CF_GDIOBJLAST        应用软件定义

的一系列GDI对象的整型值。

CF_HDROP       一个HDROP类型的句柄,用来标识一列文件。

CF_METAFILEPICT 一个使用METAFILEPICT结构定义的元图文件的句柄。

CF_OEMTEXT     预定义的字符的文本格式,每一行都绑定

一个CR-LF字符,并且用一个空字符表示数据结尾。

CF_OWNERDISPLAY 剪贴板拥有者的显示格式,

剪贴板的拥有者必须显示并且更新剪贴板的观察器窗口,

并且接收WM_ASKCBFORMATNAMEWM_HSCROLLCLIPBOARD

WM_PAINTCLIPBOARDWM_SIZECLIPBOARD以及

WM_VSCROLLCLIPBOARD等消息,hMem参数必需为NULL

CF_PALETTE     调色板的句柄

CF_PRIVATEFIRSTCF_PRIVATELAST      私有的剪贴板格式的整型值。

CF_RIFF 能够提交比CF_WAVE标准波表文件格式更为复杂的音频数据

CF_SYLK 微软公司的SYLKSymbolic Link,符号链接)格式

CF_TEXT 文本格式

CF_WAVE 使用一种标准波表文件格式如11kHz22kHz

PCMPulse Code Modulation,脉冲编码调制器)提交音频数据。

CF_TIFF TIFF图形格式

CF_UNICODETEXT Unicode文本格式(

注意:仅适用于Windows NTWindows 2000操作系统)

 

1 常用的标准剪贴板格式

 

要编写一个实现剪切和复制命令的函数,就要在你的应用程序中实现选定操作;要编写一个实现粘贴命令的函数,就需要请求剪贴板来检测它是否包含你的应用程序能够支持的数据。下面的代码实现了复制命令,其它实现可仿照进行,在此不再赘言。

 

程序示例:

void CMyView::OnEditCopy()

{

if ( !OpenClipboard() )

{

AfxMessageBox( "无法打开剪贴板" );

return;

}

// 删除目前剪贴板的内容

        if( !EmptyClipboard() )

        {

AfxMessageBox( "无法清除剪贴板" );

return;

}

// 获取选定的数据

// 检查是否为剪贴板支持的格式

if ( ::SetClipboardData( CF_ , hData ) == NULL )

// CF_ 指定了剪贴板中数据的格式,

//1列出了标准的剪贴板格式

{

AfxMessageBox( "无法将数据复制到剪贴板当中" );

CloseClipboard();

return;

}

// ...

CloseClipboard();

}

 

四、使用OLE剪贴板机制

 

首先举个例子给你一些关于OLE剪贴板的感性认识,同时说明你需要为OLE剪贴板做哪些事情:Microsoft Excel为工作表注册了一个自定义的格式,这个格式能够比其它标准格式(如位图或纯文本等)提供更多的信息。当此数据被粘贴到一个支持工作表的程序(比如Lotus < xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1-2-3)时,所有的原工作表中的公式和数值将被保留,并且还可能会根据需要被更新。Excel同样将数据以OLE格式存放在剪贴板中,这样它就可以作为一个OLE对象被嵌入。任何OLE文档包容器(Container)(比如Microsoft Word)能够将该数据作为嵌入对象粘贴进文档(比如通过选择性粘贴,可以在Word中粘贴进Excel工作表对象)。这个嵌入对象能够通过激活Microsoft Excel来进行修改(在Word中可以通过双击对象实现)。该工作表甚至可以被粘贴到一个绘图程序(比如的画笔)。当然,这时你无论如何都没有办法将其中的数据像在工作表中一样修改,因为它已经是图片了。

 

从上例总结一下,我们应当作的事情大致有:注册自定义的格式、传输格式到剪贴板上以及实现复制、剪切和粘贴。

 

注册自定义格式

 

OLE剪贴板中的数据存在于多种格式。当一个用户选择从剪贴板粘贴数据时,应用程序应当能够选择使用何种格式粘贴数据。应用程序应当提供大部分格式的信息,除非用户指定使用某一种特定格式粘贴(比如只粘贴文字或只粘贴图片等)。

 

Windows定义了很多能够通过剪贴板传输的标准格式(见表1),OLE也定义了很多特殊的格式。应用程序可以通过获取更加详细的信息来注册他们自己的剪贴板格式。这可以通过使用Win32 API函数RegisterClipboardFormat来实现:

RegisterClipboardFormat ( lpszFormat );

 说明 lpzxFormat是指向一个字符串的指针,用以命名自定义的格式。该函数返回无符号整数,该数即为格式的ID

 在注册了自定义的格式之后,便可以使用RegisterClipboardFormat函数的返回值来标识并使用该格式。

将格式传输到剪贴板上

 要增加更多的格式到剪贴板上,你必须从COleClientItemCOleServerItem继承一个类,并且在该类中重载OnGetClipboardData函数。在这个函数中,你应当做按照下列步骤完成。

 将更多的格式放置在剪贴板上

1. 建立一个COleDataSource对象。

 2. 传递该数据源到一个函数,用该函数通过访问COleDataSource::CacheGlobalData函数来将你的数据格式添加到支持的格式列表。

3. 通过访问COleDataSource::CacheGlobalData,为每一个你向支持的格式添加标准格式。

 

程序示例:

COleDataSource* CMyItem::OnGetClipboardData(

BOOL bIncludeLink,LPPOINT pptOffset, LPSIZE pSize)

{

        ASSERT_VALID(this);

 

        if (m_pServerNode == NULL)

               return NULL;

 

        COleDataSource* pDataSource =

        new COleDataSource;

        TRY

        {

               GetNativeClipboardData(pDataSource);

               GetClipboardData(pDataSource, bIncludeLink,

         pptOffset, pSize);

        }

        CATCH_ALL(e)

        {

               delete pDataSource;

               THROW_LAST();

        }

        END_CATCH_ALL

 

        ASSERT_VALID(pDataSource);

        return pDataSource;

}

 

 

内容导航

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇在C++中的ODBC API数据库编程 下一篇Visual C++.NET 2005中的STL简介

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: