Home
Serializing ASCII Data
Modeless child dialog
Modeless sibling dialog
The drag source
The MFC drop target
The TBTextTarget class
VC6 flat toolbar support
| |
Data Drag is coming to town... the drop target
You imagine? Right, theres more than one possibility, this time
Ill give you three. One for your private data, one for the common
data in order to recieve data from other applications like Excel, WinWord
etc., and at last Ill give you a handy-dandy
class you can derive ANY MFC object from to make it a drop target.
Getting the data from the dropped object, the MFC way
The
source code for this one is step3
I assume you want to drag the contents of some rows of a CListControl of your CFormView
into one of the modal dialogs mentioned earlier in this article series. In real-life you
can use this approach to implement the drop functions to any CWnd-derived object, whether
in the modal dialog or not.
The first steps are the same as done when implenting the drop source:
- To your drop target class, e.g. my CDialog based class CDropDialog,
add a member variable of type UINT:
UINT m_DragDropFormat;
- In the constructor of the view, initialize it for private data exchange
with
m_DragDropFormat = ::RegisterClipboardFormat("YourInterfaceClipboardFormat");
and for the common format just use:
m_DragDropFormat = CF_TEXT;
- Add the following lines to stdafx.h
#include <afxdisp.h>
#include <afxole.h>
- In your applications InitInstance function make a call to AfxOleInit()
before creating the document template
- If the window used as drop target is CView-derived you are now in
luck, most of it is at the hand. In the OnInitialUpdate function call
the Register() function and overwriting the functions OnDragOver and
OnDrop (implementation same as CInterfaceDropTarget in step 9) should
be enough in "normal" cases - READY!
- If you have another kind of target theres some more work.
- Use the ClassWizard to create a new generic(!) class derived from
the MFC(!) class COleDropTarget. I call it CInterfaceDropTarget
- Create and initialize a UINT m_DragDropFormat as in step 2
- Create - at least - the functions OnDragOver and 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 wont 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__ " dontt 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);
}
- Dontt forget to process the data in the OnDrop function. You
should send the just-dropped-object to your CWnd-class and "do
something" with it there. The example does this with the functions
ProcessData(CString data)
and ProcessData(int rowcount,
int linecount, CString Data) .
- If the CWnd-derived class used as drop target add a member variable
of type CInterfaceDropTarget, for exapmles sake name it m_DT
- At any point where this window exists (OnInitDialog is great) call
the Register function
of m_DT:
BOOL CDropDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_DT.Register(this);
// the other stuff follows ....
}
Ready!
|