OLE剪贴板学习心得

来源:互联网 发布:全国淘宝卖家数据采集 编辑:程序博客网 时间:2024/06/03 15:45

 

MFC对OLE剪贴板的支持主要集中在两个类上,分别是
COleDataSource,COleDataObject。
其中,COleDataSource作为操作者,而COleDataObject作为消费者,换句话说,用户需要使用COleDataSource把数据放到OLE剪贴板上,而使用COleDataObject把它取回。


将保存在全局内存中的项目放置在OLE剪贴板上,需要进行如下步骤:
1.在堆上(而不是在堆栈上)创建COleDataSource对象。
2.调用COleDataSource::CacheGlobalData将HGLOBAL递交给COleDataSource对象。
3.调用COleDataSource::SetClipboard将对象放置在
   OLE剪贴板上。

下列使用COleDataSource在OLE剪贴板上提供了ANSI文本字符串.

char szText[]="Hello,world";
HANDLE hData=::GlobalAlloc(CMEM_MOVEABLB,::lstrlen(szText)+1);
::lstrcpy(pData,szText);
::GlobalUnlock(hData);

COleDataSource * pods=new COleDataSource;
pods->CacheGlobalData(CF_TEXT,hData);
pods->SetClipboard();


MFC的COleDataObject提供了从OLE剪贴板获取项目的机制。
1.创建COleDataObject对象。
2.调用COleDataObject::AttachClipboard将   COleDataObject连接到OLE剪贴板。
3.使用COleDataObject::GetGlobalData获取项目。
4.释放由GetGlobalData返回的全局内存块。

以下为例:
   char szTect[];
   COleDataObject pdo;
   pdo.AttachClipboard();
   HANDLE hData=pdo.GetGlobalData(CF_TEXT);
  
   if(hData!=NULL)
      LPCSTR pData=(LPCSTR)::Globallock(hData);
      if(::lstrlen(pData<BUFLEN))
         ::lstrcpy(szText,pData);
      ::GlobalUnlock(hData);
      ::GlobalFree(hData);

注意,我们以上讨论的OLE剪贴板储存媒介都是内存,下面我们将要讨论储存媒介为非内存的情况。


COleDataSource::CacheGlobalData和COleDataObject::GetGlobalData与全局内存密不可分。但是您可以使用更一般的COleDataSource::CacheData和COleDataObject::GetData函数在其他数据类型的媒介中传送数据。

下面例子说明如何使用文件作为传送媒体,通过前贴板来传送文本字符串。字符串首先复制到临时文件中。然后用描述文件的信息和文件包含的数据初始化FORMATETC和STGMEDIUM结构。最后信息被传送给COleDataSource::CacheData,并用COleDataSource::SetClipboar将数据对象放置在剪贴板上。

char szText[]="Hello,world"
TCHAR szPath[Max_path],szFileName[Max_path];
::GetTempPath(sizeof(szPath)/sizeof(TCHAR),szPath);
::GetTempFileName(szPath,_T("tmp"),0,szFileName);//分配临时文件名称。

CFile file;
if(file.Open(szFileName,CFile::modeCreate|CFile::modeWrite))
{
     file.Write(szText,::lstrlen(szText)+1);
     file.Close();

     LPWSTR pwszFileName=(LPWSTR)::CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
     #ifdef UNICODE
           ::lstrcpy(pwszFileName,szFileName);
     #else
           ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szFileName,-1,pwszFileName,MAX_PATE);
     #endif
     FORMATETC fe={CF_TEXT,NULL,DVASPECT_CONTENT,-1,TYMED_FILE};

     STGMEDIUM stgm;
     stgm.tymed=TYMED_FILE;
     stgm.lpszFileName=pwszFileName;
     stgm.pUnkForRelease=NULL;
   
     COleDataSource * pods=new COleDataSource;
     pods->CacheData(CF_TEXT,&stgm,&fe);
     pods->setClipboard();
}


在消费者端,您可以使用COleDataObject::GetData从剪贴板获取字符串
char szText[BUFLEN];
STGMEDIUM stgm;
FORMATETC fe={CF_TEXT,NULL,DVASPECT_CONTENT,-1,TYMED_FILE;}
COleDataObject pdo;
pdo.AttachClipboard();
if(pdo.GetData(CF_TEXT,&stgm,&fe)&&stgm.tymed==TYMED_FILE)
{TCHAR szFileName|Max_Path;}

#ifdef UNICODE
     ::lstrcpy(szFileName,stgm,lpszFileName);
#else
     ::WideCharToMultiByte(CP_ACP,0,stgm,lpszf|leName,_T,szFileName,sizeof(szFileName)/sizeof(TCHAR),NULL,NULL);
#endif
     CFile file;
     if(file.Open(szFileName,CFile::modeRead))|DWORD dwSize=file.GetLength();
     if(dwSize<BUFLEN)
           file.Read(szText,(UNIT)dwSize);
     file.Close();
   }
   ::ReleaseStgMedium(&stgm);
}

 

在读取OLE剪贴板内容是,用户可以直接使用COleDataObject::GetFileData取代GetData函数。

原创粉丝点击