上的一个帖子,我好像没有遇到问题,楼主的代码我也没有仔细调
我在我的应用程序中增加了copy/paste和DragDrop功能,我把原来的window_Format matefile改成了enhanced-format metafile,这时我的程序可以和安全的向word中进行copy/paste,但不能dragdrop(拖放),在拖源方一切正常,当我在word是松开拖放键时,系统会提示我“内存不足”警告。我不明白为什么. 下面是我ServerItem类的部分代码。 //当对象调用CopyToClipboard和DoDragDrop时,OnGetClipboard被自动调用。 COleDataSource* CSrvrItem::OnGetClipboardData(BOOL bIncludeLink, LPPOINT pptOffset, LPSIZE pSize) { ASSERT_VALID(this); COleDataSource* pDataSource = new COleDataSource; TRY { GetNativeClipboardData(pDataSource); GetEnhMetaFileToClip(pDataSource);//增加增强图元到数据对象。 GetClipboardData(pDataSource, bIncludeLink, pptOffset, pSize); //把即将复制到剪贴板中的所有数据(如果调用CopyToClipboard)填充指定的COleDataSource对象中 } CATCH_ALL(e) { delete pDataSource; THROW_LAST(); } END_CATCH_ALL ASSERT_VALID(pDataSource); return pDataSource; } //被OnGetClipboardData所调用。 void CSrvrItem::GetNativeClipboardData(COleDataSource *pDataSource) { ASSERT_VALID(this); ASSERT(CCvtGraphDoc::m_cfFirst != NULL); // Create a shared file and associate a CArchive with it CSharedFile file; CArchive ar(&file,CArchive::store); // Serialize selected objects to the archive dview.m_selection.Serialize(ar); ar.Close(); // put on local format instead of or in addation to COleDataSource pDataSource->CacheGlobalData(CCvtGraphDoc::m_cfFirst,file.Detach()); } //重载函数。 BOOL CSrvrItem::OnRenderData( LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium ) { ASSERT_VALID(this); ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE)); ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM))); // default implementation does not support extended layout if (lpFormatEtc->lindex != -1) return FALSE; // default implementation supports both types of metafiles //去掉原先的Window_format metafile支持。 //if (lpFormatEtc->cfFormat == CF_METAFILEPICT) // return GetMetafileData(lpFormatEtc, lpStgMedium); return FALSE; // cfFormat not supported } void CSrvrItem::GetEnhMetaFileToClip(COleDataSource* pDataSource) { // Obtain a handle to a reference DC. HDC hdcRef = GetDC(gpView->m_hWnd); // Determine the picture frame dimensions. // iWidthMM is the display width in millimeters. // iHeightMM is the display height in millimeters. // iWidthPels is the display width in pixels. // iHeightPels is the display height in pixels. int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE); int iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE); int iWidthPels = GetDeviceCaps(hdcRef, HORZRES); int iHeightPels = GetDeviceCaps(hdcRef, VERTRES); // Use iWidthMM, iWidthPels, iHeightMM, and iHeightPels to determine the number of .01-millimeter units per pixel in the x and y directions. int iMMPerPelX = (iWidthMM * 100)/iWidthPels; int iMMPerPelY = (iHeightMM * 100)/iHeightPels; CClientDC dc(gpView); CRect rcSelBox; gpView->OnPrepareDC(&dc); dview.CalcSelectedItemRect(&dc,rcSelBox); //convert from the word coordinates to the client coordinates; dview.DocToClient(rcSelBox,gpView); CPoint ptTopLeft = rcSelBox.TopLeft(); CSize rSize = rcSelBox.Size(); AdjustSize(rSize);//适当调整包围盒大小。 // Convert client coordinates to .01-mm units. rSize.cx = rSize.cx * iMMPerPelX; rSize.cy = rSize.cy * iMMPerPelY; ptTopLeft = CPoint (0,0); CRect rcNew(ptTopLeft,rSize); CClientDC cdc(gpView); CMetaFileDC * pMetaDC = new CMetaFileDC(); BOOL bRet = pMetaDC->CreateEnhanced(&cdc,NULL,rcNew,"whatever"); if(bRet == FALSE) { TRACE("Create Enhanced metafile failed!/n"); return; } // create attribute DC according to lpFormatEtc->ptd HDC hAttribDC = ::GetDC(gpView->GetSafeHwnd()); if (hAttribDC == NULL) { TRACE("Create attribute DC failed!/n"); return; } pMetaDC->SetAttribDC(hAttribDC); CSize size; this->OnDraw(pMetaDC); //在增加图元中画。 pMetaDC->HIMETRICtoLP(&rSize); pMetaDC->SetAttribDC(NULL); ::DeleteDC(hAttribDC); //close meta file dc and prepare for clipboard; HENHMETAFILE hMF = pMetaDC->CloseEnhanced(); tagSTGMEDIUM * data = new tagSTGMEDIUM; data->tymed = TYMED_ENHMF; data->hEnhMetaFile = hMF; data->pUnkForRelease = NULL; tagFORMATETC* fec = new tagFORMATETC; fec->cfFormat = CF_ENHMETAFILE; fec->dwAspect = DVASPECT_CONTENT; fec->ptd = NULL; fec->tymed = TYMED_ENHMF; fec->lindex = -1; pDataSource->CacheData(CF_ENHMETAFILE, data,fec); delete pMetaDC; }