//以下是一个用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; }