在视图类中为文档创建一个新的剪切板类型。拥有这种剪贴板类型的文档可以粘贴到该剪贴板,但其他类型的文档不行。创建自己的自定义格式,要遵循在注册任何自定义剪贴板格式时,使用相同的过程;将格式名称传递给RegisterDlipboardFormat函数,然后使用其返回值作为格式表示符,具体方法是:
1. 在视图类的声明文档中声明一个静态的自定义剪贴板类型:
Static CLIPFORMAT m_cfDraw;//自定义剪贴板格式
2. 在视图类实现文档中注册自定义剪贴板格式:
CLIPFORMAT CvisDrawView::m_cfDraw = (CLIPFORMAT)
::RegisterClipboardFormat(_T(“VISDRAW”));
RegisterClipboardFormat是Win32 API函数,它注册一个新的剪贴板格式,此后这个格式可作为有效的剪贴板格式。RegisterClipboardFormat的原型是:
UINT RegisterClipboardFormat( LPCTRSTR lpszFormat //新格式名称);
如果注册格式已经存在,将返回已经存在格式的值而不是注册新的格式。这样做的好处是可以在多个应用程序中使用同一种格式来复制和粘贴数据。
void CHookupDrawView::OnEditCopy()
{
// TODO: 在此添加命令处理程序代码
ASSERT_VALID(this);
ASSERT(m_cfDraw != NULL);
//创建一个共享文件并把它与CArchive相关联
CSharedFile file;
CArchive ar(&file, CArchive::store);//CArchive::store 指存储数据到file里
m_selection.Serialize(ar);
ar.Close();
COleDataSource * pDataSource = NULL;
TRY
{
pDataSource = new COleDataSource;
pDataSource->CacheGlobalData(m_cfDraw, file.Detach());
CFigureObj * pDrawObj = m_selection.GetHead();
pDataSource->SetClipboard();
}
CATCH_ALL(e)
{
delete pDataSource;
THROW_LAST();
}
END_CATCH_ALL
}
OnEditCopy函数完成的任务如下:
1. 序列化被拾取列表到一个共享内存文件中。因为CsharedFile被全局分配,而这正是我们所要求的,我们将把这项放到剪贴板中。
CsharedFile file;
Carchive ar(&file, Carchive::store);
m_selection.Serialize(ar);
ar.Close();
2. 把这个文件放到剪贴板中。
我们使用已注册过的剪贴板类型,并把从内存文件中获得的句柄传给他,该句柄实际是一个在全局堆中分配的内存句柄。当应用程序需要将数据复制到剪贴板时,将创建数据源。以下是一个典型的创建方案。
[1]用户选择一些数据。
[2]用户从“编辑”菜单中选择“复制”(或“剪切”)或开始进行托放操作。
[3]应用程序创建ColeDataSource对象或来自ColeDataSource派生的类的对象,具体取决于程序设计。
[4]通过调用ColeDataSource::CacheData组中的一个函数,将选定的数据插入数据源。
[5]应用程序调用属于步骤[3]中创建的对象的SetClipboard成员函数(如果这是托放操作,则为DoDaragDrop成员函数)。
[6]如果这是“剪切”操作,或者DoDaragDrop返回DROPEFFECT_MOVE,则步骤[1]中选定的数据将从文档中删除。
上述过程的实现代码如下:
pDataSource = new ColeDataSource;
pDataSource->CacheGlobalData(m_cfDraw, file.Detach()) ;
CfigureObj * pDrawObj = m_selection.GetHead();
pDataSource->SetClipboard();
3. 销毁数据源:
数据源必须由当前对其负责的应用程序销毁。如果将数据源传递给OLE(如调用ColeDataSource::SetClipBoard),则不必考虑如何销毁,因为数据源将由OLE销毁。如果不讲数据源传递给OLE,则与处理典型的C++对象一样,你必须负责销毁数据源:delete pDataSource.
粘贴数据:
实现粘贴数据需要以下几个步骤:
1. 在视图类中,实现OnEditPaste以处理用户从“编辑”菜单上选择“粘贴”选项的情况。
2. 在OnEditPaste函数中,创建ColeDataObject对象并调用其AttachClipboard成员函数,将该对象链接到剪贴板上的数据。
3. 调用ColeDataObject::IsDataAvailable检查特定格式是否可用。
4. 或者使用ColeDataObject::BeginEnumFormats查找其他格式,直到找到一个最适合应用程序的格式为止。
5. 执行格式的粘贴。
6. 销毁数据对象,如果遵循在创建数据对象中所描述的方案,则销毁数据对象仅是数据传输中的一个方向;当年函数返回时,在粘贴函数中创建的数据对象将被 MFC销毁。