实现一个拖放目标






4.27/5 (10投票s)
2000 年 11 月 10 日

141314

1828
循序渐进的文章,解释如何实现一个拖放目标
本文是 拖放界面 示例的一部分。
- 序列化 ASCII 数据
- 无模式子对话框
- 无模式兄弟对话框
- 拖放源
- MFC 目标
- TBTextTarget 类
数据拖动即将到来... 拖放目标
你想象一下? 对,有不止一种可能性,这次我将给你三种。 一种用于你的私有数据,一种用于接收来自其他应用程序(如 Excel,WinWord 等)的通用数据,最后,我将给你 一个方便的类,你可以从中派生任何 MFC 对象,使其成为一个拖放目标。
从拖放的对象中获取数据,MFC 方法
我假设你想把你的 CFormView
的 CListControl
中一些行拖到本系列文章前面提到的一个模态对话框中。 在现实生活中,你可以使用这种方法来实现任何 CWnd
派生对象的拖放功能,无论是在模态对话框中还是不在。
第一步与实现拖放源时相同
- 对于你的拖放目标类,例如,基于我的
CDialog
的类CDropDialog
,添加一个UINT
类型的成员变量UINT m_DragDropFormat;
- 在视图的构造函数中,将其初始化为与私有数据交换
m_DragDropFormat = ::RegisterClipboardFormat("YourInterfaceClipboardFormat");
对于通用格式,只需使用
m_DragDorpFormat = CF_TEXT;
- 将以下行添加到 stdafx.h
#include <afxdisp.h> #include <afxole.h>
- 在应用程序的
InitInstance
函数中,在创建文档模板之前调用AfxOleInit()
。 - 如果用作拖放目标的窗口是
CView
派生的,那么你现在很幸运,大部分工作已经完成。 在OnInitialUpdate
函数中,调用Register()
函数并覆盖OnDragOver
和OnDrop
函数(实现与步骤 9 中的CInterfaceDropTarget
相同)在“正常”情况下应该足够了 - 完成! - 如果你有另一种目标,还需要做更多的工作。
- 使用
ClassWizard
创建一个从 MFC 类COleDropTarget
派生的新的通用(!)类。 我称之为CInterfaceDropTarget
。 - 创建并初始化一个
UINT m_DragDropFormat
,如步骤 2 中所示。 - 创建 - 至少 - 函数
OnDragOver
和OnDrop
。DROPEFFECT CInterfaceDropTarget::OnDragOver (CWnd *pDrop, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point ) { CFile *pFile = pDataObject->GetFileData(m_DragDropFormat); if (pFile != NULL) // perhaps some point checking here? return DROPEFFECT_COPY; // data fits else return DROPEFFECT_NONE; // data won't fit } BOOL CInterfaceDropTarget::OnDrop(CWnd *pDrop, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point ) { CFile *pFile = pDataObject->GetFileData(m_DragDropFormat); if (pFile != NULL) { int number, colCou; CString Data; // perhaps some point checking first? TRY { CArchive ar(&file, CArchive::load); TRY { if (DragDropFormat != CF_TEXT) { // "Serialize" your data object from the archive // (yes, you may use YourObject.Serialize(ar) here!) ar >> number; ar >> colCou; for (int i=0; i<colCou; i++) { ar >> Data ; #pragma message(__FILE__ " dont't forget to process Data here.....") } } else { CString Data, t; TRY { while(ar.ReadString(t)) Data += t + "\n"; } #pragma message(__FILE__ " ... and here!") CATCH_ALL(eInnerMost) { #ifdef _DEBUG TCHAR szCause[255]; CString strFormatted; eInnerMost->GetErrorMessage(szCause, 255); strFormatted = _T("Exception: "); strFormatted += szCause; AfxMessageBox(strFormatted); #endif //_DEBUG ASSERT(FALSE); } END_CATCH_ALL; } ar.Close(); } CATCH_ALL(eInner) { // exception while reading // from or closing the archive ASSERT(FALSE); } END_CATCH_ALL; } CATCH_ALL(eOuter) { // exception in the destructor of ar ASSERT(FALSE); } END_CATCH_ALL; return TRUE; } return COleDropTarget::OnDrop(pDrop, pDataObject, dropEffect, point); }
- 不要忘记在
OnDrop
函数中处理数据。 你应该将刚刚拖放的对象发送到你的CWnd
类并在那里“做一些事情”。 该示例通过函数ProcessData(CString data)
和ProcessData(int rowcount, int linecount, CString Data)
来实现这一点。 - 在用作拖放目标的
CWnd
派生类中,添加一个CInterfaceDropTarget
类型的成员变量,例如,为了方便起见,将其命名为m_DT
。 - 在此窗口存在的任何时候(例如:
OnInitDialog
很好),调用m_DT
的Register
函数BOOL CDropDialog::OnInitDialog() { CDialog::OnInitDialog(); m_DT.Register(this); // the other stuff follows .... }
完成!
许可证
本文档没有附加明确的许可证,但可能在文章文本或下载文件中包含使用条款。 如果有疑问,请通过下面的讨论区与作者联系。 可以在这里找到作者可能使用的许可证列表。