void CHexEdit::OnEditCopy() { COleDataSource* pSource = new COleDataSource(); EmptyClipboard(); int dwLen = GetSelLength(); HGLOBAL hMemb = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, dwLen); HGLOBAL hMema = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, (dwLen) * 3); if (!hMemb || !hMema) return; LPBYTE p = (BYTE*)::GlobalLock(hMemb); // copy binary memcpy(p, m_pData+m_selStart, dwLen); ::GlobalUnlock(hMemb); p = (BYTE*)::GlobalLock(hMema); // copy ascii memcpy(p, m_pData+m_selStart, dwLen); ::GlobalUnlock(hMema); for(int i = 0; i < dwLen;i++) { if(m_currentMode != EDIT_ASCII) { TOHEX(m_pData[m_selStart+i], p); *p++ = ' '; } else if(!isprint(*p)) *p++ = '.'; } pSource->CacheGlobalData(RegisterClipboardFormat("BinaryData"), hMemb); pSource->CacheGlobalData(CF_TEXT, hMema); pSource->SetClipboard(); }
void CExplorerTestView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here int nItem = -1; CObList fileList; LIST_VIEW* pListView; CListCtrl& listCtrl = GetListCtrl(); CSharedFile sharedFile; COleDataSource* dataSource = new COleDataSource; while((nItem = listCtrl.GetNextItem(nItem, LVNI_SELECTED)) != -1) { pListView = (LIST_VIEW*)listCtrl.GetItemData(nItem); fileList.AddTail((CObject*)pListView); } CArchive ar(&sharedFile, CArchive::store); CExplorerTestDoc* pDoc = (CExplorerTestDoc*)GetDocument(); pDoc->SetCopyFileList(&fileList); pDoc->SerializeCopyFiles(ar); ar.Close(); dataSource->CacheGlobalData(m_cbFormat, sharedFile.Detach()); dataSource->DoDragDrop(); delete dataSource; *pResult = 0; }
void CUIDesignerView::OnEditCopy() { ASSERT(m_cfUI != NULL); TiXmlDocument xmlDoc; TiXmlDeclaration Declaration("1.0","utf-8","yes"); xmlDoc.InsertEndChild(Declaration); TiXmlElement* pCopyElm = new TiXmlElement("UICopy"); CopyUI(pCopyElm); xmlDoc.InsertEndChild(*pCopyElm); TiXmlPrinter printer; xmlDoc.Accept(&printer); delete pCopyElm; CSharedFile file(GMEM_MOVEABLE, printer.Size() + 1); file.Write(printer.CStr(), printer.Size()); file.Write("\0", 1); COleDataSource* pDataSource = NULL; TRY { pDataSource = new COleDataSource; pDataSource->CacheGlobalData(m_cfUI, file.Detach()); pDataSource->SetClipboard(); } CATCH_ALL(e) { delete pDataSource; THROW_LAST(); } END_CATCH_ALL }
HRESULT __stdcall CXMiLFilesControl::OnItemClick(DWORD item) { #if 0 HGLOBAL hData = BuildSelectedFilesClipboard(); if (hData) { CMyDropSource* dropSource = new CMyDropSource; CMyDataObject* dataObject = new CMyDataObject; STGMEDIUM stg = {0}; stg.tymed = TYMED_HGLOBAL; stg.hGlobal = hData; stg.pUnkForRelease = NULL; FORMATETC etc = {0}; etc.cfFormat = CF_HDROP;//CF_UNICODETEXT;//49285;//RegisterClipboardFormat(CFSTR_SHELLURL);//CF_TEXT; etc.tymed = TYMED_HGLOBAL; etc.ptd = NULL; etc.dwAspect = DVASPECT_CONTENT; etc.lindex = -1; dataObject->SetData(&etc, &stg, TRUE); DWORD dropEffect = 0; HRESULT hr = ::DoDragDrop(dataObject, dropSource, DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &dropEffect); if (hr == DRAGDROP_S_DROP) { if (dropEffect/* & DROPEFFECT_MOVE*/) { } } GlobalFree(hData); // delete dataObject; // delete dropSource; #if 0 COleDataSource source; source.CacheGlobalData(CF_HDROP, hData, NULL); if (source.DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE, NULL, NULL) == DROPEFFECT_COPY) { } source.Empty(); #endif GlobalFree(hData); } #endif return S_OK; }
COleDataSource* CArxdrawView::generateDataSource(int objType, const CRect& rect) { COleDataSource* pSource = new COleDataSource(); char buf[50]; sprintf(buf,"%d %d %d %d %d", objType, rect.left, rect.top, rect.right, rect.bottom); HGLOBAL temp = GlobalAlloc(GHND, strlen(buf)+1); char *data = (char*) GlobalLock(temp); strcpy(data, buf); GlobalUnlock(temp); pSource->CacheGlobalData(CF_TEXT, temp); return pSource; }
// helper function used for clipboard and drag-drop COleDataSource* CEx27bView::SaveObject() { TRACE("Entering CEx27bView::SaveObject\n"); CEx27bDoc* pDoc = GetDocument(); if (pDoc->m_lpOleObj != NULL) { COleDataSource* pSource = new COleDataSource(); // CODE FOR OBJECT DATA FORMATETC fmte; SETFORMATETC(fmte, m_cfEmbedded, DVASPECT_CONTENT, NULL, TYMED_ISTORAGE, -1); STGMEDIUM stgm; stgm.tymed = TYMED_ISTORAGE; stgm.pstg = pDoc->m_pTempStgSub; stgm.pUnkForRelease = NULL; pDoc->m_pTempStgSub->AddRef(); // must do both! pDoc->m_pTempStgRoot->AddRef(); pSource->CacheData(m_cfEmbedded, &stgm, &fmte); // metafile needed too MakeMetafilePict(pSource); // CODE FOR OBJECT DESCRIPTION DATA HGLOBAL hObjDesc = ::GlobalAlloc(GMEM_SHARE, sizeof(OBJECTDESCRIPTOR)); LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR) ::GlobalLock(hObjDesc); pObjDesc->cbSize = sizeof(OBJECTDESCRIPTOR); pObjDesc->clsid = CLSID_NULL; pObjDesc->dwDrawAspect = 0; pObjDesc->dwStatus = 0; pObjDesc->dwFullUserTypeName = 0; pObjDesc->dwSrcOfCopy = 0; pObjDesc->sizel.cx = 0; pObjDesc->sizel.cy = 0; pObjDesc->pointl.x = 0; pObjDesc->pointl.y = 0; ::GlobalUnlock(hObjDesc); pSource->CacheGlobalData(m_cfObjDesc, hObjDesc); return pSource; } return NULL; }
void CAboutDlg::OnCopyToClipboard() { CStringW info = m_appname; info += _T("\n----------------------------------\n\n"); info += _T("Build information:\n"); info += _T(" Version: ") + m_strBuildNumber + _T("\n"); info += _T(" Compiler: ") + m_MPCCompiler + _T("\n"); info += _T(" Build date: ") + m_buildDate + _T("\n\n"); #ifndef MPCHC_LITE info += _T("LAV Filters:\n"); info += _T(" LAV Splitter: ") + CFGFilterLAV::GetVersion(CFGFilterLAV::SPLITTER) + _T("\n"); info += _T(" LAV Video: ") + CFGFilterLAV::GetVersion(CFGFilterLAV::VIDEO_DECODER) + _T("\n"); info += _T(" LAV Audio: ") + CFGFilterLAV::GetVersion(CFGFilterLAV::AUDIO_DECODER) + _T("\n"); info += _T(" FFmpeg compiler: ") + CString(g_Gcc_Compiler) + _T("\n\n"); #endif info += _T("Operating system:\n"); info += _T(" Name: ") + m_OSName + _T("\n"); info += _T(" Version: ") + m_OSVersion + _T("\n"); COleDataSource* pData = DEBUG_NEW COleDataSource(); int len = info.GetLength() + 1; HGLOBAL hGlob = GlobalAlloc(GMEM_FIXED, len * sizeof(WCHAR)); if (pData && hGlob) { wcscpy_s((WCHAR*)hGlob, len, (LPCWSTR)info); pData->CacheGlobalData(CF_UNICODETEXT, hGlob); // The system will take care of removing the allocated memory pData->SetClipboard(); } else if (pData) { delete pData; } else if (hGlob) { GlobalFree(hGlob); } }
void CGumpListView::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); *pResult = 0; COleDataSource srcItem; CString sType = _T(""); HGLOBAL hTextData = 0; CSharedFile clipb (GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); dynDropSource.nControlType = DYN_PICTURE; CString strText; strText.Format("%d",0); sType = strText; clipb.Write(sType, sType.GetLength()*sizeof(TCHAR)); hTextData = clipb.Detach(); srcItem.CacheGlobalData(m_nIDClipFormat, hTextData); srcItem.DoDragDrop(DROPEFFECT_COPY,NULL,&dynDropSource); }
LRESULT CSQLTableWnd::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT point; point.x = (short)LOWORD(lParam); point.y = (short)HIWORD(lParam); if (!(wParam & MK_SHIFT)) { for (int i = 0; i < m_columns.GetSize(); i++) { m_columns[i]->m_bSelected = false; } } long index = point.y/16; if (index >= 0 && index < m_table->Columns->Count) { m_columns[index]->m_bSelected = true; Invalidate(); UpdateWindow(); CComQIPtr<ILDOMDocument> document; document.CoCreateInstance(CLSID_LDOMDocument); VARIANT_BOOL success; document->loadXML(L"<columns/>", &success); CComQIPtr<ILDOMElement> documentElement; document->get_documentElement(&documentElement); documentElement->setAttribute(L"fromtable", m_table->Name); for (long i = 0; i < m_columns.GetSize(); i++) { if (m_columns[i]->m_bSelected) { CComQIPtr<ILDOMElement> element; document->createElement(L"column", &element); element->setAttribute(L"name", m_table->Columns->Item[_variant_t(index)]->Name); documentElement->appendChild(element, NULL); } } BSTR text; document->saveXML(NULL, &text); int len = SysStringLen(text); HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (len+1)*2); if (hData) { WCHAR* p = (WCHAR*)GlobalLock(hData); CopyMemory(p, text, (len+1)*2); GlobalUnlock(hData); CMyDropSource* dropSource = new CMyDropSource; CMyDataObject* dataObject = new CMyDataObject; STGMEDIUM stg = {0}; stg.tymed = TYMED_HGLOBAL; stg.hGlobal = hData; stg.pUnkForRelease = NULL; FORMATETC etc = {0}; etc.cfFormat = CF_UNICODETEXT;//CF_UNICODETEXT;//49285;//RegisterClipboardFormat(CFSTR_SHELLURL);//CF_TEXT; etc.tymed = TYMED_HGLOBAL; etc.ptd = NULL; etc.dwAspect = DVASPECT_CONTENT; etc.lindex = -1; dataObject->SetData(&etc, &stg, TRUE); DWORD dropEffect = 0; HRESULT hr = ::DoDragDrop(dataObject, dropSource, DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &dropEffect); if (hr == DRAGDROP_S_DROP) { if (dropEffect/* & DROPEFFECT_MOVE*/) { } } GlobalFree(hData); // delete dataObject; // delete dropSource; #if 0 COleDataSource source; source.CacheGlobalData(CF_HDROP, hData, NULL); if (source.DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE, NULL, NULL) == DROPEFFECT_COPY) { } source.Empty(); #endif } SysFreeString(text); } else { Invalidate(); } return 0; }
void CMusikSourcesCtrl::DoDrag( CMusikPropTreeItem* pItem ) { if ( !pItem ) return; COleDataSource datasrc; HGLOBAL hgDrop; DROPFILES* pDrop; CStringList lsDraggedFiles; POSITION pos; CString sFile; UINT uBuffSize = 0; TCHAR* pszBuff; FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; // get a list of filenames with the currently // selected items... CStdStringArray files; int nMode = pItem->GetPlaylistType(); // standard playlist dragged if ( nMode == MUSIK_PLAYLIST_TYPE_STANDARD ) m_Library->GetStdPlaylistFns( pItem->GetPlaylistID(), files, false ); // now playing dragged.. else if ( nMode == MUSIK_SOURCES_TYPE_NOWPLAYING ) { if ( m_Player->GetPlaylist() ) { m_Library->BeginTransaction(); for ( size_t i = 0; i < m_Player->GetPlaylist()->GetCount(); i++ ) files.push_back( m_Player->GetPlaylist()->GetField( i, MUSIK_LIBRARY_TYPE_FILENAME ) ); m_Library->EndTransaction(); } } // library playlist dragged else if ( nMode == MUSIK_SOURCES_TYPE_LIBRARY ) { CMainFrame* pMain = (CMainFrame*)m_Parent; if ( pMain->m_LibPlaylist ) { m_Library->BeginTransaction(); for ( size_t i = 0; i < pMain->m_LibPlaylist->GetCount(); i++ ) files.push_back( pMain->m_LibPlaylist->GetField( i, MUSIK_LIBRARY_TYPE_FILENAME ) ); m_Library->EndTransaction(); } } else if ( nMode == MUSIK_PLAYLIST_TYPE_DYNAMIC ) MessageBox( "This operation is not supported yet.", "Musik", MB_ICONINFORMATION | MB_OK ); if ( !files.size() ) return; // CStringList containing files for ( size_t i = 0; i < files.size(); i++ ) { lsDraggedFiles.AddTail( files.at( i ) ); uBuffSize += files.at( i ).GetLength() + 1; } files.clear(); // Add 1 extra for the final null char, and the size of the DROPFILES struct. uBuffSize = sizeof(DROPFILES) + sizeof(TCHAR) * (uBuffSize + 1); // Allocate memory from the heap for the DROPFILES struct. hgDrop = GlobalAlloc ( GHND | GMEM_SHARE, uBuffSize ); if ( !hgDrop ) return; pDrop = (DROPFILES*) GlobalLock ( hgDrop ); if ( !pDrop ) { GlobalFree ( hgDrop ); return; } // Fill in the DROPFILES struct. pDrop->pFiles = sizeof(DROPFILES); // If we're compiling for Unicode, set the Unicode flag in the struct to // indicate it contains Unicode strings. #ifdef _UNICODE pDrop->fWide = TRUE; #endif; // Copy all the filenames into memory after the end of the DROPFILES struct. pos = lsDraggedFiles.GetHeadPosition(); pszBuff = (TCHAR*) (LPBYTE(pDrop) + sizeof(DROPFILES)); while ( pos ) { lstrcpy ( pszBuff, (LPCTSTR) lsDraggedFiles.GetNext ( pos ) ); pszBuff = 1 + _tcschr ( pszBuff, '\0' ); } GlobalUnlock ( hgDrop ); // Put the data in the data source. datasrc.CacheGlobalData ( CF_HDROP, hgDrop, &etc ); // Add in our own custom data, so we know that the drag originated from our // window. CMyDropTarget::DragEnter() checks for this custom format, and // doesn't allow the drop if it's present. This is how we prevent the user // from dragging and then dropping in our own window. // The data will just be a dummy bool. HGLOBAL hgBool; hgBool = GlobalAlloc ( GHND | GMEM_SHARE, sizeof(bool) ); if ( NULL == hgBool ) { GlobalFree ( hgDrop ); return; } // Put the data in the data source. etc.cfFormat = m_DropID; datasrc.CacheGlobalData ( m_DropID, hgBool, &etc ); // Start the drag 'n' drop! DROPEFFECT dwEffect = datasrc.DoDragDrop ( DROPEFFECT_COPY | DROPEFFECT_MOVE ); // If the DnD completed OK, we remove all of the dragged items from our // list. switch ( dwEffect ) { case DROPEFFECT_COPY: case DROPEFFECT_MOVE: { // the copy completed successfully // do whatever we need to do here TRACE0( "DND from playlist completed successfully. The data has a new owner.\n" ); } break; case DROPEFFECT_NONE: { // This needs special handling, because on NT, DROPEFFECT_NONE // is returned for move operations, instead of DROPEFFECT_MOVE. // See Q182219 for the details. // So if we're on NT, we check each selected item, and if the // file no longer exists, it was moved successfully and we can // remove it from the list. if ( m_IsWinNT ) { // the copy completed successfully // on a windows nt machine. // do whatever we need to do here bool bDeletedAnything = false; if ( ! bDeletedAnything ) { // The DnD operation wasn't accepted, or was canceled, so we // should call GlobalFree() to clean up. GlobalFree ( hgDrop ); GlobalFree ( hgBool ); TRACE0( "DND had a problem. We had to manually free the data.\n" ); } } // not windows NT else { // We're on 9x, and a return of DROPEFFECT_NONE always means // that the DnD operation was aborted. We need to free the // allocated memory. GlobalFree ( hgDrop ); GlobalFree ( hgBool ); TRACE0( "DND had a problem. We had to manually free the data.\n" ); } } break; } }
void FunctionBlockTree::OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult) { INXString csIconName = ""; INXString csBlockName = ""; // if ( GetChildItem(m_hItemLeftClicked)== NULL) { // SetItemState( m_hItemLeftClicked, TVIS_SELECTED, TVIS_SELECTED ); // } if( !leafIsSelected() ) // If he hasn't selected something draggable, don't let him carry // on wasting his time. return; else{ for (int i=0; i<m_iL2MenuSize; i++) { SetItemState( secondlev[i], !TVIS_SELECTED, TVIS_SELECTED ); } // next check if a level3 item is selected for (int i=0; i<m_iL3MenuSize; i++) { SetItemState( thirdlev[i], !TVIS_SELECTED, TVIS_SELECTED ); } // next check if a level3 item is selected for (int i=0; i<m_iL4MenuSize; i++) { SetItemState( forthlev[i], !TVIS_SELECTED, TVIS_SELECTED ); } //if(m_hPrevItemClicked) // SetItemState( m_hPrevItemClicked, !TVIS_SELECTED, TVIS_SELECTED ); if(m_hItemClicked) SetItemState( m_hItemClicked, TVIS_SELECTED, TVIS_SELECTED ); for (int i=0; i<m_iL2MenuSize; i++) { if (m_hItemClicked==secondlev[i]) { csIconName = m_csaL2IconName.GetAt(i); csBlockName = m_csaL2MenuName.GetAt(i); } } // next check if a level3 item is selected for (int i=0; i<m_iL3MenuSize; i++) { if (m_hItemClicked==thirdlev[i]) { csIconName = m_csaL3IconName.GetAt(i); csBlockName = m_csaL3MenuName.GetAt(i); // Needs to be set to trigger a subsystem drop action } } // next check if a level3 item is selected for (int i=0; i<m_iL4MenuSize; i++) { if (m_hItemClicked==forthlev[i]) { csIconName = m_csaL4IconName.GetAt(i); csBlockName = m_csaL4MenuName.GetAt(i);// Needs to be set to trigger a subsystem drop action } } LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); //NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; *pResult = 0; #ifdef LEGACY // Create the drag&drop source and data objects COleDropSource *pDropSource = new COleDropSource; COleDataSource *pDataSource = new COleDataSource; #endif // now determine which rows are selected // here it's a dirty copy from the CodeGurus's // CListCtrl section //int idx = GetSelectedItem(); // nothing selected (must be for dragging) // or error while registering the clipboard format if (/*idx == -1 ||*/ !m_DragDropFormat) { ASSERT(FALSE); return; } // now grab the data (here: the count and text) // and serialize it into an clipboard archive INXString Data; // getting the column count, thanks Zafir! // CHeaderCtrl* pHeader = (CHeaderCtrl*)m_Table.GetDlgItem(0); //int number = m_Table.GetSelectedCount(), // colCou = pHeader?pHeader->GetItemCount():0; /* This is some rubbish serialisation that is needed to retrieve data from files in the draw windows etc.. !!! */ TRY { CSharedFile file(GMEM_ZEROINIT|GMEM_DDESHARE|GMEM_MOVEABLE); TRY { CArchive ar(&file, CArchive::store); TRY { INXString format = AfxGetApp()->GetProfileString("DragDrop", "Clipformat", "Common"); if (format == "Private") { ar << (CString)csIconName; ar << (CString)csBlockName; } else // common data format { ar.WriteString( csIconName + "\n" + csBlockName + "\n" ); } ar.Close(); } CATCH_ALL(eInner) { // exception while writing into or closing the archive ASSERT(FALSE); } END_CATCH_ALL; } CATCH_ALL(eMiddle) { // exception in the destructor of ar ASSERT(FALSE); } END_CATCH_ALL; // put the file object into the data object #ifdef LEGACY pDataSource->CacheGlobalData(m_DragDropFormat, file.Detach()); pDataSource->DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY, NULL, pDropSource); #endif } CATCH_ALL(eOuter) { // exception while destructing the file ASSERT(FALSE); } END_CATCH_ALL; #ifdef LEGACY delete pDropSource; delete pDataSource; #endif *pResult = 0; } // if( leafIsSelected() ) }
/*** 拷贝列表到剪贴板 */ void CReportListCtrl::Copy( ) { // Write to shared file (REMEBER: CF_TEXT is ANSI, not UNICODE, so we need to convert) CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); // Get a tab delimited string to copy to cache CString str; // Column CHeaderCtrl * pHeader = GetHeaderCtrl(); int nColCount = pHeader ? pHeader->GetItemCount() : 0 ; str.Empty(); char buffer[256]; LVCOLUMN column; memset( &column, 0, sizeof( column ) ); column.mask = LVCF_TEXT; column.pszText = buffer; column.cchTextMax = 255; int nColumn = 0; while( GetColumn( nColumn++, &column ) ) { str += buffer; str += _T("\t"); } str += _T("\r\n"); sf.Write(T2A(str.GetBuffer(1)), str.GetLength()); str.ReleaseBuffer(); // Data for( int nRow = 0; nRow <GetItemCount(); nRow ++ ) { str.Empty(); for( int nCol = 0; nCol <nColCount; nCol ++ ) { CString strTemp = GetItemText( nRow, nCol ); str += (strTemp.IsEmpty() ? _T(" ") : strTemp ); if( nCol != nColCount-1 ) str += _T("\t"); } if( nRow != GetItemCount()-1 ) str += _T("\r\n"); sf.Write(T2A(str.GetBuffer(1)), str.GetLength()); str.ReleaseBuffer(); } char c = '\0'; sf.Write(&c, 1); DWORD dwLen = (DWORD)sf.GetLength(); HGLOBAL hMem = sf.Detach(); if (!hMem) return; hMem = ::GlobalReAlloc(hMem, dwLen, GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); if (!hMem) return; // Cache data COleDataSource* pSource = new COleDataSource(); pSource->CacheGlobalData(CF_TEXT, hMem); pSource->SetClipboard(); }
/////////////////////////////////////////////////// //Copy this object out to the clipboard or drag/drop //buffer based on Keith Rule's //serialization algorithm //from the MFC Programmer's Sourcebook website, //and Chapter 1 of "the Essence of OLE with Active X" //by David S. Platt. // //pDropEffect is only set if doing a drag-drop. // //You usually call this function from: // //1) Your view class's OnLButtonDown() method // when starting a drag-drop. // //2) Your document class when copying data // to the clipboard. /////////////////////////////////////////////////// BOOL CDragDropMgr::PrepareDrop( BOOL bToClipboard, LPCTSTR lpstrFormat, CObject* pObj, DROPEFFECT* pDropEffect, LPCTSTR lpstrFormat2, CObject* pObj2) { if (pObj == NULL) return FALSE; CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); CSharedFile sf2(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); UINT format = ::RegisterClipboardFormat(lpstrFormat); if (format == 0) return FALSE; TRY { CArchive ar(&sf, CArchive::store); pObj->Serialize(ar); ar.Close(); HGLOBAL hMem = sf.Detach(); if (hMem == NULL) return FALSE; COleDataSource* pSrc = new COleDataSource(); if (pSrc == NULL) return FALSE; pSrc->CacheGlobalData(format,hMem); if (pObj2) { // special case for when the second data type is a filelist UINT format2 = (strcmp(lpstrFormat2, "CF_HDROP") ? ::RegisterClipboardFormat(lpstrFormat2) : CF_HDROP); if (format2 != CF_HDROP) { CArchive ar2(&sf2, CArchive::store); pObj2->Serialize(ar2); ar2.Close(); HGLOBAL hMem2 = sf2.Detach(); if (hMem2 == NULL) return FALSE; pSrc->CacheGlobalData(format2,hMem2); } else { // fake file list DROPFILES *pDrop = (DROPFILES*)pObj2; HGLOBAL hgDrop = GlobalAlloc ( GHND | GMEM_SHARE, sizeof(DROPFILES)+1 ); DROPFILES *pDrop2 = (DROPFILES*) GlobalLock ( hgDrop ); memcpy((void*)pDrop2, (void*)pDrop, sizeof(DROPFILES)+1); GlobalUnlock(hgDrop); pSrc->CacheGlobalData(format2, hgDrop); } } //Pasting to the clipboard: //do not free the data source //(OLE will free it when no longer needed) if (bToClipboard) pSrc->SetClipboard(); //Starting a drag-drop: //Set the type of drag-drop effect, and //free the data source object. //OLE has created a data source object in //the drag-drop global cache; it's //not our problem anymore... else if (pDropEffect != NULL) { *pDropEffect = pSrc->DoDragDrop(); delete pSrc; } return TRUE; } //catch CATCH_ALL(ce) { return FALSE; } END_CATCH_ALL }