//////////////////////////////////////////////////////// //This function loads data from the clipboard //or drag/drop into a local object of the proper //type for use. // //If pasting from clipboard, pDataObject should be NULL. // //You usually call this function from: // //1) Your view class's OnDrop() method when a drag- // drop operation ends, to load the data for use. // //2) Your view (or document) class's OnEditPaste() // method when doing a paste from the clipboard. //////////////////////////////////////////////////////// BOOL CDragDropMgr::DoDrop( CObject* pO, COleDataObject* pDataObject, LPCTSTR lpstrFormat) { // try { UINT format = ::RegisterClipboardFormat(lpstrFormat); COleDataObject* pObj = NULL; // If from clipboard, then there is no // data object passed in, so use a local copy if (pDataObject == NULL) pObj = new COleDataObject(); else pObj = pDataObject; // Make sure basic data is OK if (pObj == NULL) return FALSE; else if (pDataObject == NULL && !pObj->AttachClipboard()) return FALSE; else if (format == 0 || pO == NULL) return FALSE; else if (!pObj->IsDataAvailable(format)) return FALSE; FORMATETC fe; fe.cfFormat = format; fe.tymed = TYMED_HGLOBAL; fe.lindex = -1; fe.dwAspect = DVASPECT_CONTENT; fe.ptd = NULL; // Fetch the data from the OLE data object HGLOBAL hMem = pObj->GetGlobalData(format,&fe); if (hMem == NULL) return FALSE; // TRY { CMemFile mf((BYTE*)::GlobalLock(hMem), ::GlobalSize(hMem)); CArchive ar(&mf, CArchive::load); pO->Serialize(ar); ar.Close(); ::GlobalUnlock(hMem); pObj->Release(); if (pDataObject == NULL) delete pObj; return TRUE; } /* CATCH_ALL(ce) { pObj->Release(); if (pDataObject == NULL) delete pObj; return FALSE; } END_CATCH_ALL*/ } /* catch(...) { CErrorDlg error; error.Error("Drag/drop error", "A serious error occured while dropping objects. Please report this to the Construct team."); return FALSE; }*/ return TRUE; }
//////////////////////////////////////////////////////// //This function loads CF_TEXT data from the clipboard //or drag/drop into a CStringArray, one line of text //per array entry. A null in the input text //denotes a new line. // //If pasting from clipboard, pDataObject should be NULL. // //You usually call this function from: // //1) Your view class's OnDrop() method when a drag- // drop operation ends, to load the data for use. // //2) Your view (or document) class's OnEditPaste() // method when doing a paste from the clipboard. //////////////////////////////////////////////////////// BOOL CDragDropMgr::GetCFText( CStringArray* pcsText, COleDataObject* pDataObject) { BOOL bOk = FALSE; CString csLine = ""; COleDataObject* pObj = NULL; //If from clipboard, then there is no //data object passed in, so use a local copy if (pDataObject == NULL) pObj = new COleDataObject(); else pObj = pDataObject; //Make sure basic data is OK if (pObj == NULL) return FALSE; else if ((pDataObject == NULL && !pObj->AttachClipboard()) || pcsText== NULL || !pObj->IsDataAvailable(CF_TEXT)) { pObj->Release(); if (pDataObject == NULL) delete pObj; return FALSE; } //The format etc struct tells how the data //should be transferred. //Do NOT use the MFC defaults here - they are no good FORMATETC fe; fe.cfFormat = CF_TEXT; fe.tymed = TYMED_HGLOBAL; fe.lindex = -1; fe.dwAspect = DVASPECT_CONTENT; fe.ptd = NULL; //Fetch the data from the OLE data object HGLOBAL hMem = pObj->GetGlobalData(CF_TEXT,&fe); if (hMem != NULL) { char* pchT = (char*)::GlobalLock(hMem); if (pchT != NULL) { DWORD dwSize = ::GlobalSize(hMem); int i = 0; BOOL bDone = FALSE; while (!bDone) { //Hit a crlf: Add current line if (pchT[i+1] == '\n' && pchT[i] == '\r') { pcsText->Add(csLine); csLine = ""; i += 2; } //End of the block: Add final line else if (pchT[i] == '\0' || i >= DD_MAXCHARS) { pcsText->Add(csLine); bDone = TRUE;; } //Normal character: Add to line being built else { csLine += pchT[i]; i++; } } ::GlobalUnlock(hMem); bOk = TRUE; } } //hmem not null pObj->Release(); if (pDataObject == NULL) delete pObj; return bOk; }
// Called within Copy Thread: void CCopyThread::OnClipboardChange() { Log(_T("OnClipboardChange - Start")); SyncConfig(); // synchronize with the main thread's copy configuration // if we are told not to copy on change, then we have nothing to do. if(!m_LocalConfig.m_bCopyOnChange) return; CClip* pClip = new CClip; CClipTypes* pSupportedTypes = m_LocalConfig.m_pSupportedTypes; bool bDeleteMemory = false; //If we are copying from a Ditto Buffer then save all to the database, so when we paste this it will paste //just like you were using Ctrl-V if(theApp.m_CopyBuffer.Active()) { Log(_T("LoadFromClipboard - Copy buffer Active Start")); pSupportedTypes = new CClipTypes; if(pSupportedTypes) { bDeleteMemory = true; COleDataObject oleData; if(oleData.AttachClipboard()) { oleData.BeginEnumFormats(); FORMATETC format; while(oleData.GetNextFormat(&format)) { pSupportedTypes->Add(format.cfFormat); } oleData.Release(); } } else { pSupportedTypes = m_LocalConfig.m_pSupportedTypes; } Log(_T("LoadFromClipboard - Copy buffer Active End")); } Log(_T("LoadFromClipboard - Before")); bool bResult = pClip->LoadFromClipboard(pSupportedTypes); Log(_T("LoadFromClipboard - After")); if(!bResult) { DWORD delay = CGetSetOptions::GetNoFormatsRetryDelay(); if(delay > 0) { Log(StrF(_T("LoadFromClipboard didn't find any clips to save, sleeping %dms, then trying again"), delay)); Sleep(delay); Log(_T("LoadFromClipboard #2 - Before")); bResult = pClip->LoadFromClipboard(pSupportedTypes); Log(_T("LoadFromClipboard #2 - After")); } else { Log(_T("LoadFromClipboard didn't find any clips to save, retry setting is not set, not retrying")); } } if(bDeleteMemory) { delete pSupportedTypes; pSupportedTypes = NULL; } if(!bResult) { delete pClip; return; // error } if(m_LocalConfig.m_bAsyncCopy) ::PostMessage(m_LocalConfig.m_hClipHandler, WM_CLIPBOARD_COPIED, (WPARAM)pClip, 0); else ::SendMessage(m_LocalConfig.m_hClipHandler, WM_CLIPBOARD_COPIED, (WPARAM)pClip, 0); Log(_T("OnClipboardChange - End")); }