Data is going
abroad... implementing the drag source
Again, the
implementation of this idea is in two different
versions.
Version one uses
user-defined data and may better fit your needs.
As we are dealing
here with a list control, it may be considerable to
use a standard format instead with version two. As a
side-effect, you can now
drag the contents of your list control to
Word,
Excel, Visual
Studio, or any other drop-enabled texteditor - do I
see you smile?
Both versions are
very similar. To implement both of them with my
application, I made use of the registry settings.
Use the menu items at "Clipboard
format" or the
HKEY_CURRENT_USER\Software\Codeguru\Interface\DragDrop\Clipformat
string to specify either the default of "Common" or
the string "Private". Any other value will cause an
error message and the assumption of the Common type.
Follow these
steps:
- To the view,
add a member-variable of type
UINT
:
Collapse | Copy
Code
UINT m_DragDropFormat;
- In the
constructor of the view, initialize it for
private data exchange with:
Collapse | Copy
Code
m_DragDropFormat =
::RegisterClipboardFormat("YourInterfaceClipboardFormat");
and for the
common format just use:
Collapse | Copy
Code
m_DragDorpFormat = CF_TEXT;
Do the same to
your drop target. In our case, it�s either of
the modal dialogs created in step one.
- Add the
following lines to stdafx.h:
Collapse | Copy
Code
#include <afxdisp.h>
#include <afxole.h>
In your
application�s
InitInstance
function, make a call to
AfxOleInit()
before creating the document template
#include
<afxadv.h>
in your drag-source-class source file (or in
stdafx.h, its for
CSharedFile
used in Step 5).
-
(Private data)
Use the Class Wizard to add a message handler to
your view, which responds to the
LVN_BEGINDRAG
message of the list control. Here is the
function
OnBeginDragList1
for the private-data-version:
Collapse | Copy
Code
void CInterfaceView::OnBeginDragList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
*pResult = 0;
COleDropSource *pDropSource = new COleDropSource;
COleDataSource *pDataSource = new COleDataSource;
int idx = GetSelectedItem();
if (idx == -1 || !m_DragDropFormat)
{
ASSERT(FALSE);
return;
}
CString Data;
CHeaderCtrl* pHeader = (CHeaderCtrl*)m_Table.GetDlgItem(0);
int number = m_Table.GetSelectedCount(),
colCou = pHeader?pHeader->GetItemCount():0;
TRY
{
CSharedFile file(GMEM_ZEROINIT|GMEM_DDESHARE|GMEM_MOVEABLE);
TRY
{
CArchive ar(&file, CArchive::store);
TRY
{
ar << number;
ar << colCou
do
{
for (int i=0; i<colCou; i++)
{
Data = m_Table.GetItemText(idx, i);
ar << Data ;
}
idx = GetSelectedItem(idx);
} while (idx != -1);
ar.Close();
}
CATCH_ALL(eInner)
{
ASSERT(FALSE);
}
END_CATCH_ALL;
}
CATCH_ALL(eMiddle)
{
ASSERT(FALSE);
}
END_CATCH_ALL;
pDataSource->CacheGlobalData(m_DragDropFormat, file.Detach());
pDataSource->DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY,
NULL, pDropSource);
}
CATCH_ALL(eOuter)
{
ASSERT(FALSE);
}
END_CATCH_ALL;
delete pDropSource;
delete pDataSource;
}
Here is the
function
OnBeginDragList1
for the common-data-version. It even allows you
to drag your data to
Excel! (common data)
Collapse | Copy
Code
CSharedFile file;
TRY
{
CArchive ar(&file, CArchive::store);
TRY
{
CString number;
number.Format("%i\n", m_Table.GetSelectedCount());
ar.WriteString(number);
do
{
Data.Empty();
for (int i=0; i<colCou; i++)
Data += m_Table.GetItemText(idx, i) + "\t";
ar.WriteString(Data + "\n");
idx = GetSelectedItem(idx);
} while (idx != -1);
ar.Close();
}
CATCH_ALL(eInner)