MFC
Example: Using MFC For Drag
'& Drop, Cut, Copy, and Paste
Alex Rest
March 28, 2003
VC++ Source
Codes
In the given article,
practically all operations on moving a group of files
from one application to another are described.
Considered are both the reception of files by the
given application and transfer of files from the given
application in other programs.
In the article,
the operations drag and drop,
cut, copy,
paste are
described. The description is constructed using the
demonstration project.
While developing the program
Mp3 Music Explorer, I have confronted the fact that in
the documentation from Microsoft, and also on the
known sites devoted to development of the software,
there is no example
in which all necessary operations on moving files
would be presented. Therefore, I have created the
demonstration project FilesDragDrop.
It is based on the MFC
SDI. For the files display, the class CListView
is used.
|
Receiving the drop
of the list of files
in the application is possible by two methods: using the
message WM_DROPFILES and using the mechanism Ole. Both
methods, as well transferring a file through the Clipboard,
use one structure of file description DROPFILES. To drag
a file from the
application, only the mechanism Ole is used. Therefore, I
implemented all operations of moving files by using the
Ole technology.
1. Initialization
The realization of
moving files is possible without such concepts as Ole
Server and Ole Client. They are excessive for this tucancode.net.
It is possible to use the usual MFC
project. But, for the necessary Ole classes to work, we
need to initialize the Ole library. For this purpose, the
following lines are inserted into the function CFilesDragDropApp::
InitInstance ():
if (!AfxOleInit())
{
AfxMessageBox("AfxOleInit Error!");
return FALSE;
}
2. Receiving the
Files in the Application
To receiving files
using the Drag&Drop
technology, I used OnDragOver
and OnDrop
notifications.
In the OnDragOver
function, I determine whether the list of files or
something else is carried above a window, and I return the
assumed result of the operation. If it is not the files,
the returned value is DROPEFFECT_NONE. It allows the
system to establish the correct mouse cursor.
In the OnDrop
function, the extraction of files and the clearing of the
buffer are made. For these functions to work, the window
should be registered as the handler of the Drag&Drop
operation. For the registration, the object such as COleDropTarget
is used as follows:
void CFilesDragDropView::OnInitialUpdate()
{
.
VERIFY( m_DropTarget.Register(this) );
.
}
Clipboard
and Drag&Drop use
the same structure for data transfer. In processing the
messages OnPaste and OnDrop,
there is an extraction of the list of files from the
object COleDataObject:
void CFilesDragDropView::OnEditPaste()
{
COleDataObject DataObject;
if( DataObject.AttachClipboard() )
DataObjectToList(&DataObject);
}
}
BOOL CFilesDragDropView::OnDrop(COleDataObject* pDataObject,
DROPEFFECT dropEffect,
CPoint point)
{
BOOL bRet = DataObjectToList(pDataObject);
.
}
The data type used
for transferring the files is CF_HDROP. The data are
passed through the global memory, its handle. It is
possible to take from COleDataObject
by using the GetData function. The amount of transferred
files and paths to them can be received with the help of a
handle by using the DragQueryFile ( CFilesDragDropView::
FileNamesToList) function. The received files are
displayed in a ListView window.
3. Transferring
Files from the Application
To transfer files
from the application using Copy/Paste and Drag&Drop
technologies, it is necessary to create a DROPFILES
structure. This structure corresponds to a data type
CF_HDROP of the exchange buffer. The paths to files in the
structure are separated from each other by the '\0'
symbol; the end of the list of files is marked by two
symbols: '\0 '. There is a standard function of path
extraction from the DragQueryFile buffer, but there is no
standard function for creating a buffer. For this purpose,
I have designed a CDropFiles class. The class is used in
the following way: 1) first, the AddFile function enters
all the paths of transferred files, 2) then the
CreateBuffer function creates a necessary data structure.
For access to the structure, the GetBuffer and GetBuffSize
functions are used.
When using the Copy
or Cut command, the
data generated in CDropFile:: m_pBuff are entered in the
exchange buffer between the applications by the
SetClipboardData function.
In Drag&Drop
technology, for the transfer of files from the application
the function OnBeginDrag is used. It is called by the
LVN_BEGINDRAG message of the CListCtrl class. If we use a
window that does not generate the similar message, it is
possible to use the WM_LBUTTONDOWN message. The data for
the transfer are entered in COleDataSource
object by the CacheGlobalData
function; the data transfer is carried out by the
DoDragDrop function. For the object COleDataSource
to work, it is necessary to create a COleDropSource
object. This object is not used in any way in the
transfer. All necessary actions are carried out in the
constructor.
Memory of the
exchange buffer is emptied by the receiving party.
The text of the
function follows:
void CFilesDragDropView::OnBeginDrag(NMHDR* pNMHDR,
LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CDropFiles DropFiles;
if(!PrepareFileBuff(DropFiles)){
ASSERT(0);
}
COleDropSource DropSource;
COleDataSource DropData;
HGLOBAL hMem = ::GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|
GMEM_DDESHARE,
DropFiles.GetBuffSize());
memcpy( (char*)::GlobalLock(hMem), DropFiles.GetBuffer(),
DropFiles.GetBuffSize() );
::GlobalUnlock(hMem);
DropData.CacheGlobalData( CF_HDROP, hMem );
DROPEFFECT de = DropData.DoDragDrop(DROPEFFECT_COPY|
DROPEFFECT_MOVE,NULL);
if(de == DROPEFFECT_COPY){
}
else{
DeleteSelectedFiles();
}
*pResult = 0;
}
4. Testing the
Demonstration Project
If you transfer files
from any catalogue to the FilesDragDrop
application, and then from the application to another
catalogue, the files really will be transferred. That's
why, when testing, I recommend using the special temporary
catalogues to avoid the transfer of necessary files.
Downloads
Download
demo project - 23 Kb
|