Basic Copy/Paste '& Drag/Drop Support | CodeGuru

Basic Copy/Paste ‘& Drag/Drop Support

Overview The clipboard is used to transfer data between windows or applications. It is used either during Drag/Drop operation or during a Cut/Copy/Paste operation. Whether you are using Drag/Drop or Cut/Copy/Paste, the code used to place data on the clipboard is very similar. This article will show you the basics for accessing the clipboard. Placing […]

Written By
CodeGuru Staff
CodeGuru Staff
Aug 6, 1998
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Overview


The clipboard is used to transfer data between windows or applications. It is used either during Drag/Drop operation or during a Cut/Copy/Paste operation. Whether you are using Drag/Drop or Cut/Copy/Paste, the code used to place data on the clipboard is very similar. This article will show you the basics for accessing the clipboard.


Placing Data on the Clipboard


Writing to the Clipboard is straightforward. By following a few simple steps you can place nearly any supported clipboard format onto the clipboard.


  1. Create a new COleDataSource.

  2. Create a new CSharedFile (see initialization in example below).

  3. Write info to the CSharedFile instance.

  4. Detach the memory associated with the CSharedFile.

  5. Pass the detached memory and format info to CacheGlobalData().

  6. Place the data on the clipboard using SetClipboard().

Example 1 – Source for Writing to Clipboard


void CClipExamView::OnEditCopy()
{
	COleDataSource*	pSource = new COleDataSource();
	CSharedFile	sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
	CString		text = _T(“Testing 123…”);

sf.Write(text, text.GetLength()); // You can write to the clipboard as you would to any CFile

HGLOBAL hMem = sf.Detach();
if (!hMem) return;
pSource-CacheGlobalData(CF_TEXT, hMem);
pSource-SetClipboard();
}

Advertisement

Serializing to the Clipboard


Often it is useful to be able to serialize your data to the clipboard so that you can create a custom clipboard for your application. This can be done by registering a custom clipboard format and serializing to a CSharedFile. The following source illustrates how to serialize a CObject to the clipboard.


Example 2 – Serializing to the Clipboard


void SerializeToClipboard(CObject* obj, CString formatname )
{
	COleDataSource*	pSource = new COleDataSource();
	CSharedFile	sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
	UINT		format = RegisterClipboardFormat(formatname);
	CArchive		ar(&sf, CArchive::store);
	obj-Serialize(ar);
	ar.Close();
	HGLOBAL hMem = sf.Detach();
	if (!hMem) return;
	pSource-CacheGlobalData(format, hMem);
	pSource-SetClipboard();
}

Reading Data from the Clipboard


Reading data from the clipboard is nearly the inverse of placing data on the clipboard.


  1. Create a COleDataObject instance.

  2. Check to see if the format you want is available.

  3. Place the data associated with the clipboard into a CMemFile.

  4. Read the data out of the CMemFile.

  5. Release the global memory.

Example 3 – Reading Data from the Clipboard


void CClipExamView::OnEditPaste()
{
	COleDataObject	obj;

if (obj.AttachClipboard()) {
if (obj.IsDataAvailable(CF_TEXT)) {
HGLOBAL hmem = obj.GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
CString buffer;

LPSTR str = buffer.GetBufferSetLength(::GlobalSize(hmem));
sf.Read(str, ::GlobalSize(hmem));
::GlobalUnlock(hmem);

// Do something with the data in ‘buffer’
TRACE(“Paste received = ‘%s’rn”, buffer);
}
}
}

Advertisement

Serializing from the Clipboard


Serializing from the Clipboard is only a slight modification of the previous example.


Example 4 – Reading Serialized Data from the Clipboard


void SerializeFromClipboard(COleDataObject* obj, CObject* cobj, CString formatname)
{
	UINT		format = RegisterClipboardFormat(formatname);
	if (obj-IsDataAvailable(format)) {
		HGLOBAL hmem = obj-GetGlobalData(format);
		CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
		
		CArchive ar(file, CArchive::load);
		cobj-Serialize(ar);
		ar.Close();
		::GlobalUnlock(hmem);
	}
}

Drag/Drop Support


All of the examples thus far are placing the data on the clipboard as if a copy operation had been invoked. Enabling Drag/Drop is a simple change to the above code.


Sourcing a Drag/Drop


The code for the origination of a drag/drop is identical to examples for placing data on the clipboard, with one little modification. Rather than executing the SetClipboard() command, you should execute the DoDragDrop() command.


Example 5 – Sourcing a Drag/Drop


// Initiate the Drag/Drop
void CClipExamView::OnLButtonDown(UINT nFlags, CPoint point)
{
	COleDataSource*	pSource = new COleDataSource();
	CSharedFile	sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
	CString		text = _T(“Testing 123…”);
	sf.Write(text, text.GetLength()); // You can write to the clipboard as you would to any CFile
	HGLOBAL hMem = sf.Detach();
	if (!hMem) return;
	pSource-CacheGlobalData(CF_TEXT, hMem);
	pSource-DoDragDrop();
}

Accepting a Drag/Drop


Example 5 – Accepting a Drag/Drop


// OnDragOver

Called when mouse moves over window during a Drag/Drop


DROPEFFECT CClipExamView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)


{


if (pDataObject-IsDataAvailable(CF_TEXT)) {


return DROPEFFECT_COPY;


}


return DROPEFFECT_NONE;


}

// OnDrop – Called when drop occurs
BOOL CClipExamView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
if (pDataObject-IsDataAvailable(CF_TEXT)) {
HGLOBAL hmem = pDataObject-GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
CString buffer;

LPSTR str = buffer.GetBufferSetLength(::GlobalSize(hmem));
sf.Read(str, ::GlobalSize(hmem));
::GlobalUnlock(hmem);

// Do something with the data in ‘buffer’
TRACE(“OnDrop received = ‘%s’rn”, buffer);
return TRUE;
}
return FALSE;
}

Housekeeping Issues


A few additional housekeeping things must be done make drag/drop work correctly.


  1. Make sure that your applications InitInstance() member function calls the AfxOleInit() function.

  2. The view must be registered as a drag/drop target. If you don’t do this you won’t be able to accept a drag/drop. See Example 6.

  3. Several includes must be added to stdafx.h to insure that your code will compile. See Example 7.

Example 6 – Initializing View as Drop Target


// Enable view as a drop target. Assumes COleDropTarget	m_DropTarget is defined in view object.
void CClipExamView::OnInitialUpdate()
{
	CView::OnInitialUpdate();
	m_DropTarget.Register(this);
}

Example 7 – Include to Add to stdafx.h


#include <afxole.h>         // MFC OLE classes
#include <afxodlgs.h>       // MFC OLE dialog classes
#include <afxdisp.h >       // MFC OLE automation classes
#include <afxpriv.h>

Download files 33KB

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.