我在我的应用程序中增加了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;
}

解决方案 »

  1.   

    See the link below, FYI :http://www.codeproject.com/clipboard/#Drag and Drop
      

  2.   

    我去看了,但是我不知道我的程序错在什么地方了,麻烦各位高手再帮看看,如果想要整个工程可以给我发Email,[email protected]
      

  3.   

    慢慢调试MSDN的例子程序吧,小弟没有7.0,运行都不行啊。
      

  4.   

    这是6.0的工程。已经调到第四天了,还是一点进展没有。你如果想要看看错误的话,可以用MSDN的 HIERSVR 例子,再把我上面的代码替换掉它的ServerItem类的实现代码就行了。(因为我这就是在那上面做的)。