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
'프로그래밍 > VC++' 카테고리의 다른 글
프로세스 실행시키고 종료될때까지 기다리기. (0) | 2007.09.22 |
---|---|
다른 Application으로 Drag & Drop. MFC 클래스를 이용해서. (0) | 2007.08.29 |
Dialog Based의 트리컨트롤에서 Enter키를 눌러서 라벨내용 바꾸는 경우 (0) | 2007.08.16 |
다이얼로그에서 ESC나 Enter키 눌렀다고 창 닫혀지지 않도록 하기 (0) | 2007.08.16 |
MainFrame, Doc, View 포인터 얻기 (0) | 2007.08.16 |