【MoreWindows工作笔记9】OleGetClipboard 访问剪切板的文本内容

原创 2013年12月31日 15:59:31

剪贴板系列目前有四篇,包括访问剪贴板上的文本数据,查看复制文件时剪贴板上的文件数据,枚举剪贴板上数据格式以及监视剪贴板。

目录如下:

1.《【MoreWindows工作笔记9OleGetClipboard 访问剪切板的文本内容》

http://blog.csdn.net/morewindows/article/details/17655053

2.《【MoreWindows工作笔记10OleGetClipboard 访问剪切板上的文件信息》

http://blog.csdn.net/morewindows/article/details/17655057

3.《【MoreWindows工作笔记11EnumClipboardFormats剪切板内容的数据格式》

http://blog.csdn.net/morewindows/article/details/17655299

4.《【MoreWindows工作笔记12WM_DRAWCLIPBOARD 监视剪切板》

http://blog.csdn.net/morewindows/article/details/17655429

 

剪贴板的参考文档推荐http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016(v=vs.85).aspx

这里很详细,也提供了丰富的示范代码,呵呵,现在微软的MSDN已经比之前改进不少了。不但实例更加丰富了,还能在下面给出评论了。


为了提高大家学习的兴趣,先看看程序运行的效果吧,先复制一些文本,然后运行程序,程序将输出剪贴板上的文本大小和文本内容。运行结果如下所示:

 

下面在来看下如何实现这个功能,先看看完整的源代码,然后在来讲解重点函数。

《【MoreWindows工作笔记9OleGetClipboard 访问剪切板的文本内容》的完整源代码如下所示:

// 【MoreWindows工作笔记9】OleGetClipboard 访问剪切板的文本内容
// http://blog.csdn.net/morewindows/article/details/17655053
// By MoreWindows( http://blog.csdn.net/MoreWindows )
#include <Windows.h>
#include <ObjBase.h>
#include <iostream>
using namespace std;

void DisplayDataObject(IDataObject *pDataObject)
{
  FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  STGMEDIUM stgmedium;
  if (pDataObject->GetData(&fmtetc, &stgmedium) == S_OK)
  {
    cout<<"  剪切板数据格式上为CF_TEXT, 文本内容如下:"<<endl;
    char* data = (char*)GlobalLock(stgmedium.hGlobal);
    cout<<data<<endl;
    GlobalUnlock(stgmedium.hGlobal);
    ReleaseStgMedium(&stgmedium);
  } else {
    cout<<"  剪切板数据格式不为CF_TEXT"<<endl;
  }
} 

int main()   
{
  printf("   【MoreWindows工作笔记9】OleGetClipboard 访问剪切板的文本内容\n");
  printf(" - http://blog.csdn.net/morewindows/article/details/17655053 -\n");
  printf(" -- By MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

  if (OleInitialize(NULL) != S_OK) return 0;
  IDataObject *pDataObject;
  // Retrieves a data object that you can use to access the contents of the clipboard.
  if (OleGetClipboard(&pDataObject) == S_OK) {
    DisplayDataObject(pDataObject);
    pDataObject->Release();
  }
  OleUninitialize();
  return 0;
}

访问剪贴板内容可以分为三步:


第一步 初始化

OleInitializeOleUninitialize这两个函数简单,就是初始化和反初始化OLE(Object Linking and Embedding)OLE是个复杂的大东西,有兴趣可以参考参考http://msdn.microsoft.com/en-us/library/df267wkc.aspx


第二步 获取剪贴板内容

通过OleGetClipboard()函数取的剪贴板内容。其函数原型如下:

HRESULT OleGetClipboard(
  _Out_  LPDATAOBJECT *ppDataObj
);


第三步 剪贴板内容解析

主要是通过2个结构体——FORMATETCSTGMEDIUM。下面先看看FORMATETCFORMATETC OLE数据交换的一个关键结构,对某种设备,数据,和相关媒体做了格式上的描述。其定义为:

typedef struct tagFORMATETC 
{ 
CLIPFORMAT cfFormat; // 剪贴板数据格式
DVTARGETDEVICE *ptd; // 设备有关的信息
DWORD dwAspect; // 图形数据的表现方式
LONG lindex; // dwAspect 成员的补充
DWORD tymed; // 数据的存储介质
} FORMATETC; 
一个典型的FORMATETC结构变量定义如下:
FORMATETC cFmt = {(CLIPFORMAT) CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};

剪贴板数据格式在winuser.h中定义,取值如下:

// winuser.h
#ifndef NOCLIPBOARD

/*
 * Predefined Clipboard Formats
 */
#define CF_TEXT             1
#define CF_BITMAP           2
#define CF_METAFILEPICT     3
#define CF_SYLK             4
#define CF_DIF              5
#define CF_TIFF             6
#define CF_OEMTEXT          7
#define CF_DIB              8
#define CF_PALETTE          9
#define CF_PENDATA          10
#define CF_RIFF             11
#define CF_WAVE             12
#define CF_UNICODETEXT      13
#define CF_ENHMETAFILE      14
#if(WINVER >= 0x0400)
#define CF_HDROP            15
#define CF_LOCALE           16
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define CF_DIBV5            17
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0500)
#define CF_MAX              18
#elif(WINVER >= 0x0400)
#define CF_MAX              17
#else
#define CF_MAX              15
#endif
#define CF_OWNERDISPLAY     0x0080
#define CF_DSPTEXT          0x0081
#define CF_DSPBITMAP        0x0082
#define CF_DSPMETAFILEPICT  0x0083
#define CF_DSPENHMETAFILE   0x008E
/*
 * "Private" formats don't get GlobalFree()'d
 */
#define CF_PRIVATEFIRST     0x0200
#define CF_PRIVATELAST      0x02FF
/*
 * "GDIOBJ" formats do get DeleteObject()'d
 */
#define CF_GDIOBJFIRST      0x0300
#define CF_GDIOBJLAST       0x03FF

#endif /* !NOCLIPBOARD */

看完了FORMATETC结构体,再来看看STGMEDIUM结构体:
typedef struct tagSTGMEDIUM {
  DWORD    tymed;
  union {
    HBITMAP       hBitmap;
    HMETAFILEPICT hMetaFilePict;
    HENHMETAFILE  hEnhMetaFile;
    HGLOBAL       hGlobal;
    LPOLESTR      lpszFileName;
    IStream       *pstm;
    IStorage      *pstg;
  };
  IUnknown *pUnkForRelease;
} STGMEDIUM, *LPSTGMEDIUM;

这里很巧妙的使用了union来存储不同类型的句柄指针。


使用IDataObject类的GetData()函数可以根据FORMATETC的值取出相应的STGMEDIUM数据,注意最后要调用ReleaseStgMedium()来释放STGMEDIUM数据


下一篇《MoreWindows工作笔记10OleGetClipboard访问剪切板上的文件信息

》(http://blog.csdn.net/morewindows/article/details/17655057)将介绍在复制粘贴文件时,剪贴板会存储什么格式的数据,如何使用这些数据,欢迎继续浏览。





本文地址:http://blog.csdn.net/morewindows/article/details/17655053  转载请标明出处,谢谢。

欢迎关注微博:http://weibo.com/MoreWindows 





版权声明:本文为博主原创文章,未经博主允许不得转载。

【MoreWindows工作笔记10】OleGetClipboard 访问剪切板上的文件信息

【MoreWindows工作笔记10】OleGetClipboard 访问剪切板上的文件信息 当我们复制文件时,会将文件的信息存储在剪贴板中,这个文件信息并不是文件路径的字符串。而是HDROP类型,本...

在java中使用Jawin组件访问Windows下的COM组件 java调用ole

环境:windows XP Home版;Office2000;j2se 1.6.0(JRE也是1.6.0);Jawin 2.0-alpha1。 原由:使用Jacob访问windows下的COM组...

VC 粘贴 CF_METAFILEPICT 格式 MetaFile

BOOL CALLBACK MyProc (EmfPlusRecordType recordType,UINT flags,UINT dataSize,const BYTE* data,VOID *c...

winuser.h

#ifndef _WINUSER_H #define _WINUSER_H #if __GNUC__ >= 3 #pragma GCC system_header #endif #ifdef __c...
  • Acheld
  • Acheld
  • 2016年11月28日 23:36
  • 1509

使用Visual C++实现OLE剪贴板

---- 一、概述---- 在Windows操作系统中存在两种剪贴板机制:Windows标准剪贴板和OLE剪贴板机制。---- 标准的Windows剪贴板是一个被所有Windows应用程序共享的系统服...

多人共同使用一个github的仓库,实现版本管理,多人开发一个项目

以前那使用 github + IntelliJ IDEA  + git(就是在git的基础上实现的)实现了代码的版本管理,有了版本控制之后,那么就可以随心所欲的写测试代码,而不用担心其他问题。 但是...

Java 多线程 并发 锁 Java线程面试题 Top 50

多线程 并发 锁 同步 原子

【MoreWindows工作笔记11】EnumClipboardFormats 剪切板内容的数据格式

【MoreWindows工作笔记11】EnumClipboardFormats 剪切板内容的数据格式 本文将输出剪贴板上的数据地址,数据大小,对文本类型的数据如何直接输出。...

【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板

【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板 很多程序会监视剪贴板,比如迅雷,这样当你复制一个迅雷下载链接时,迅雷就可以自动启动并创建一个新的下载任务。下面我们就...

向剪切板复制文本的js库——clipboard.js

首先,加载clipboard.js文件(我上网找的一个cdn):其次,html代码:
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【MoreWindows工作笔记9】OleGetClipboard 访问剪切板的文本内容
举报原因:
原因补充:

(最多只允许输入30个字)