DropTarget - A library to support "Drop target" functionality

Environment: MSVC++6.0 SP3, Win98/2000/NT4(SP5)

Code Description

Purpose:

DropTarget adds a "Drop target" (Drag&Drop client) functionality to your C++ code

Implementation:

[Any files you need to import in your project are shown in Red, any code to be added is shown in Blue]

(1)
Add the class definition files
- DropFileArray.cpp / .h
- MyDropTarget.cpp / .h
to your project.

(2)
#include "MyDropTarget.h" to your main *.cpp file
(in case of this demo "DropTargetDlg.cpp".


(3)
Define a message that will be recieved by your application if files are dropped on it:

   
[DropTargetDlg.h:]
// message constant
#define WM_DROPACTION WM_APP+1
// message handler definition
LRESULT OnDropAction(WPARAM wParam = 0, LPARAM lParam = 0);

[DropTargetDlg.cpp:]
BEGIN_MESSAGE_MAP(CDropTargetDlg, CDialog)
  // [...]
  ON_MESSAGE(WM_DROPACTION, OnDropAction)
END_MESSAGE_MAP()

(4)
Add the following to your dialog's "OnInitDialog()"-member function

OleInitialize(NULL); BOOL br =
   m_DropTarget.Register(this);

to register your application as a drop target.

(5)
Implement a message handler for drop action:

[DropTargetDlg.cpp:]
LRESULT CDropTargetDlg::OnDropAction(WPARAM wParam, LPARAM lParam)
{
// [...]
}  

(6)
Define a member variable for the new class instance

[DropTargetDlg.h:]
CMyDropTarget m_DropTarget;

Member functions:

Besides the existing inherited functions, MyDropTarget.cpp / .h overrides / implements the following member functions:

 // retrieve number of files dropped onto target. 0 if none
 int GetNumDroppedFiles(); 
   
 // get first (ASCII) name of dropped file
 char* GetFirstDroppedFileName(); 
   
 // get any (position iNum) name of dropped file
 char* GetDroppedFileName(int iNum=0); 
   
 // get wide char name of dropped file
 wchar_t* GetDroppedFileNameW(int iNum=0); 
   
 // get first wide char name of dropped file
 wchar_t* GetFirstDroppedFileNameW(); 
   
 // handle file dropping
 BOOL OnDrop( CWnd* pWnd, COleDataObject* pDataObject, 
                    DROPEFFECT dropEffect, CPoint point );

OnDrop() retrieves a struct containing a (wide char) list of dropped files via the COleDataObject-pointer. The list is then separated into single file names which are filled into an array derived from CArray in order no to limit the possible number of files that can be dropped onto the application.

Normal character set (Win3.X, 9X) and wide character sets (WinNT4 & W2K) are transparently supported via in-line conversion functions.

Example:

Download the attached DropTarget demonstration workspace

Final word:

I hope, you find the supplied code useful.
Please feel free to send comments to VolkerBartheld@reetcom.de

Downloads

DropTargetDemoExe.zip is a compiled executable of the demo application.
DropTargetDemo.zip is a MSVC++ V6 workspace of the demo application.
DropTargetSrc.zip are the complete sources to be added to your project for compilation with MSVC++ V6.0 (SP3) including all necessary libraries.

Download demo project executable
DropTargetDemoExe.zip - 6.065 kBytes

Download demo project workspace
DropTargetDemo.zip - 14.618 kBytes

Download demo project source
DropTargetSrc.zip - 3.800 kBytes



Comments

  • how to use this functionality

    Posted by orichisonic on 07/03/2005 02:05am

    please say in detail to how to use this functionality,because of my motherland is china

    Reply
  • This is really interesting but...

    Posted by Legacy on 11/27/2002 12:00am

    Originally posted by: Alan

    when dragging an image file from a web page to the dialog, it displays the cached file path on the c:\ instead of the actual web address of the file.

    It would be super helpful to me if you could show how to do this in you app. That is show get the actual web address of the .gif when dropping it.

    example of a dragged web graphic:

    C:\Documents and Settings\alan\Local Settings\Temporary Internet Files\Content.IE5\CDIF8XUB\ddmgr[1].gif

    Reply
  • some problems

    Posted by Legacy on 08/12/2002 12:00am

    Originally posted by: Gabi Julien

    I putted a file name myself in the clipboard with:

    /**********************************************/

    std::list<Thumb *>::iterator iList;
    //We put every selected image in the clipboard
    iList = listImag.begin();
    int i = 1;
    while(true)
    {
    if ((*iList)->Select)
    {
    sFile = (*iList)->FileName;
    lsDraggedFiles.AddTail(sFile);
    uBuffSize += lstrlen ( sFile ) + 1;
    sFile = _itoa( (*iList)->Page, &tempInt[0], 10 );
    lsDraggedFiles.AddTail(sFile);
    uBuffSize += lstrlen ( sFile ) + 1;
    DragCount++;
    }
    i++;
    if ((*iList) != listImag.back()) iList++;
    else break;
    }

    // Add 1 extra for the final null char, and the size of the DROPFILES struct.
    uBuffSize = sizeof(DROPFILES) + sizeof(TCHAR) * (uBuffSize + 1);

    HGLOBAL hgDrop;
    DROPFILES* pDrop;

    // Allocate memory from the heap for the DROPFILES struct.
    hgDrop = GlobalAlloc ( GHND | GMEM_SHARE, uBuffSize );

    if ( NULL == hgDrop )
    return;

    pDrop = (DROPFILES*) GlobalLock ( hgDrop );

    if ( NULL == pDrop )
    {
    GlobalFree ( hgDrop );
    return;
    }

    // Fill in the DROPFILES struct.
    pDrop->pFiles = sizeof(DROPFILES);

    #ifdef _UNICODE
    // If we're compiling for Unicode, set the Unicode flag in the struct to
    // indicate it contains Unicode strings.
    pDrop->fWide = TRUE;
    #endif

    TCHAR* pszBuff;

    // Copy all the filenames into memory after the end of the DROPFILES struct.
    pos = lsDraggedFiles.GetHeadPosition();
    pszBuff = (TCHAR*) (LPBYTE(pDrop) + sizeof(DROPFILES));

    CString Test;
    while ( NULL != pos )
    {
    lstrcpy ( pszBuff, LPCTSTR) lsDraggedFiles.GetNext ( pos ) );
    pszBuff = 1 + _tcschr ( pszBuff, '\0' );
    }

    GlobalUnlock ( hgDrop );

    COleDataSource datasrc;
    FORMATETC etc = { g_uCustomClipbrdFormat /*CF_HDROP*/, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

    // Put the data in the data source.
    datasrc.CacheGlobalData ( g_uCustomClipbrdFormat /*CF_HDROP*/, hgDrop, &etc );

    DROPEFFECT dwEffect;

    bob<<"Drag Begin"<<endl;
    FireThumbDrag(DragCount,GetVBKeyFlag(nFlags));
    dwEffect = datasrc.DoDragDrop ( DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_SCROLL);

    dragFlagDelay = -1;

    switch ( dwEffect )
    {
    case DROPEFFECT_COPY:
    break;
    case DROPEFFECT_MOVE:
    {
    DeleteSelectedThumb();
    //*DrawBasic();
    AfxBeginThread(DrawThread,NULL,THREAD_PRIORITY_NORMAL);
    }
    break;

    case DROPEFFECT_NONE:
    {
    // ** Omitted code for NT/2000 that checks if the operation actually succeeded. **

    // The drag operation wasn't accepted, or was canceled, so we
    // should call GlobalFree() to clean up.

    GlobalFree ( hgDrop );
    }
    break;
    }
    }


    /**********************************************/

    But cannot read special caracters like: �, �, etc... with this code. Althought I can read sutch special caracters when I drop then directly from an explorer window. Do you have an idea what could be the problem?

    Reply
  • Drop Target Implementation

    Posted by Legacy on 04/26/2002 12:00am

    Originally posted by: Amish

    Hi,
    Please if you can help me how to get URL's name if they are dropped to your application.
    I tried with CF_TEXT but I can't found a way to get the data .
    So please reply me
    Thanks,
    Amish

    Reply
  • www.terminaltechnologies.com

    Posted by Legacy on 01/06/2002 12:00am

    Originally posted by: Joshua Page

    I'm currently writing a shell Namespace extension that provides an interface to a remote operating system . You code will defiantly help me with dragging files/directories into the NSE, but I'm having a hard time figuring out how to drag out of the NSE since the files at the time of the drag don't exist yet on the hard drive. Do you know of a way to get the target path of a drop?

    thanks
    - Josh

    Reply
  • Is it possible to Register only the ComboBox(m_DropComboCtrl) as the drag&drop target?

    Posted by Legacy on 06/27/2001 12:00am

    Originally posted by: Vaclav Jedlicka

    Is it possible to Register only the ComboBox(m_DropComboCtrl) as the drag&drop target?(not the whole dialog).
    I tried but I could not make it work.

    I need it for another application where I need to drag&drop items from 1 listbox to another.

    Please can anyone help me?
    Thanks

    Vaclav Jedlicka

    Reply
  • Adding URL-drops from IExplorer

    Posted by Legacy on 05/30/2001 12:00am

    Originally posted by: Volker Bartheld

    > -----Original Message-----
    
    > From: Pros Chum
    > To: Volker Bartheld
    > Subject: DropTarget on CodeGuru

    > How would I enable my program to get drag/drop
    > notifications and the URL of the links that are dragged
    > and dropped from a web page in Internet Explorer?
    >
    > Thanks in advance for any help!

    Hi Pros!

    You might want to edit the CMyDropTarget::OnDrop() member function. At line 74 to 77 I'm checking, whether valid data (in my case the type is CF_HDROP) is present in the clipboard (dragging and dropping is pretty likewise copying to and pasting from the clipboard) which then gets attached
    a file.

    In winuser.h from line 2100 you can see, what other types are available. In your case, CF_TEXT might be of interest as the URL might get stored in some kind of unicode string. Just set a breakpoint at line 74 of MyDropTarget.cpp and check out, what types are available when dropping URLs from the internet explorer.


    HTH,
    Volker

    P.S.: I'm adding your inquiry to the "comments"-section of CodeGuru, because I think it might be of some use/inspiration for other programmers.

    Reply
  • Just What the Doctor Ordered!!

    Posted by Legacy on 05/29/2001 12:00am

    Originally posted by: Bill H.

    I've been struggling for the last few days to find an
    
    implementation of the drag 'n drop to a dialog for files.
    This article couldn't have arrived at a better time!

    Thanks,
    Bill H.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Live Event Date: November 13, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT APIs can be a great source of competitive advantage. The practice of exposing backend services as APIs has become pervasive, however their use varies widely across companies and industries. Some companies leverage APIs to create internal, operational and development efficiencies, while others use them to drive ancillary revenue channels. Many companies successfully support both public and private programs from the same API by varying levels …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds