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函數。