//以下是一个用COleDataSource和ColeDataObject通过剪贴板传输一个对象Bitmap的方法,,数据格式为CF_DIB(系统已定义的)//若使用自定义的数据格式,请看下数据格式结构体CLIPFORMAT,然后还得使用RUINT RegisterClipboardFormat(LPCTSTR lpszFormat),具体用法,请查资料吧//m_dib是CEx25aDoc一个CDib对象公共成员,
void CEx25aView::OnEditCopy()
{
// TODO: Add your command handler code here
COleDataSource* pSource = SaveDib();//此处我们得到了一个new分配出来的COleDataSource对象,如何删除看下面
if(pSource){
pSource->SetClipboard(); //此处COleDataSource对象中的数据被系统传输到剪贴板,,然后系统自动把GloableAlloc分配的内存释放,并且把new分配的CO//leDateSource释放
}
}
COleDataSource* CEx25aView::SaveDib(void)
{
CDib& dib = GetDocument()->m_dib;
if(dib.GetSizeImage() > 0){
COleDataSource* pSource = new COleDataSource(); //此处使用堆分配
int nHeaderSize = dib.GetSizeHeader();//此处为计算出Bitmap文件的头大小
int nImageSize = dib.GetSizeImage();//此处为Bitmap文件的数据部分大小
HGLOBAL hHeader = ::GlobalAlloc(GMEM_MOVEABLE,nHeaderSize + nImageSize);//分配大小,MSDN上说此函数中GMEM_MOVEABLE参数表示,得到的HGLOBAL内.存句柄得使用GlobalLock得到分配空间的指针,用完后,还得使用GlobalUnlock解除
LPVOID pHeader = ::GlobalLock(hHeader);
ASSERT(pHeader != NULL);
LPVOID pImage = (LPBYTE)pHeader+nHeaderSize;
memcpy(pHeader,dib.m_lpBMIH,nHeaderSize);//
memcpy(pImage,dib.m_lpImage,nImageSize);//拷贝数据,Receiver is supposed to free the global memory
::GlobalUnlock(hHeader); //使用GlobalUnlock解除
pSource->CacheGlobalData(CF_DIB,hHeader); //将分配的全局内存数据插入到数据对象缓冲区中
return pSource;
}
return NULL;
}
void CEx25aView::OnEditPaste()
{
// TODO: Add your command handler code here
CEx25aDoc* pDoc = GetDocument();
COleDataObject dataObject; //接收剪贴板信息时,使用的是局部变量COleDataObject
VERIFY( dataObject.AttachClipboard());
DoPasteDib(&dataObject);
CClientDC dc(this);
pDoc->m_dib.UsePalette(&dc);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews(NULL);
}
BOOL CEx25aView::DoPasteDib(COleDataObject* pDataObject)
{
//update command user interface should keep us out of here if not CF_DIB
if(!pDataObject->IsDataAvailable(CF_DIB)){
TRACE("CF_DIB format is unavailable \n");
return FALSE;
}
CEx25aDoc* pDoc = GetDocument();
//seems to be MOVEABLE memory ,so we must use GlobalLock!
//(hDib != lpDib) GetGlobalData copies the memory ,so we can hang onto it until we delete the CDib
HGLOBAL hDib = pDataObject->GetGlobalData(CF_DIB); //此处使用GetGlobalData从剪贴板获得数据时,会申请内存从剪贴板中拷贝一份!
//若用BOOL COleDataObject::GetData(CLIPFORMAT cfFormat,LPSTGMEDIUM lpStgMedium,LPFORMATETC lpFormatEtc)的话,会将数据传输到lpStgMedium指向的结构体
ASSERT(hDib != NULL);
LPVOID lpDib = ::GlobalLock(hDib);
ASSERT(lpDib != NULL);
pDoc->m_dib.AttachMemory(lpDib,true,hDib);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews(NULL);
return TRUE;
}
没用这个发过代码,弄的好悲剧