VC++ Tutorial: Drag,
Drop, COleDataSource, CSharedFile,
RegisterClipboardFormat
|
|
Keith
Rule.
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.
- Create a new COleDataSource.
- Create a new CSharedFile
(see initialization in example below).
- Write info to the CSharedFile
instance.
- Detach the memory
associated with the CSharedFile.
- Pass the detached
memory and format info to CacheGlobalData().
- 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 1... 2... 3...");
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();
}
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.
- Create a COleDataObject
instance.
- Check to see if the
format you want is available.
- Place the data
associated with the clipboard into a CMemFile.
- Read the data out of
the CMemFile.
- 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'\r\n", buffer);
}
}
}
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 1... 2... 3...");
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'\r\n", buffer);
return TRUE;
}
return FALSE;
}
Housekeeping Issues
A few additional
housekeeping things must be done make drag/drop work
correctly.
- Make sure that your
applications InitInstance() member function calls the
AfxOleInit() function.
- 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.
- 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
|