views:

662

answers:

7

as in winamp or vlc player, how to do a file drag and drop? i mean i want to know what sort of coding goes into application? i want to know for c++

+1  A: 

edit after I posted this, the question was edited to qualify as C++; I'm going to leave this answer here for reference only.


"what sort off coding goes into application":

That depends hugely on the platform and language. For example, here are examples for Windows via C#/.NET or VB/.NET. For C++, Delphi, etc - the tricks will be different.

Marc Gravell
he explicitly asked about C++
Eli Bendersky
No, he really didn't. Check the revisions, and check when I replied. The C++ tags and note were added later.
Marc Gravell
+9  A: 

In pure C/C++ on Windows, start reading about the DragAcceptFiles function and the WM_DROPFILES message. If you're using a more powerful C++ library (Qt, Wx, etc) check their respective documentation. It would help to know what you use, more specifically.

Also, this discussion may answer your question. If it's what you meant, please close this question.

Eli Bendersky
Your downvote was unwarranted; the OP added the C++ bits *after* I had replied.
Marc Gravell
Marc, I'm removing my downvote then. Your're right (it's difficult to track edits vs. comments that are posted very quickly), sorry
Eli Bendersky
A: 

In this sample have an implementation of Drag an Drop by Dom Box :
http://www.microsoft.com/msj/0895/activex0895.aspx

See source IFDROP.CPP

lsalamon
A: 

You should use COM's Ole Drag and drop interfaces.

Vinay
A: 

Before the days of OLE/COM/ActiveX, we would do something like the following:

  • If we received a mouse down event, take note of cursor position.
  • If we received a mouse movement and it moved a certain distance from the original point then we're starting a drag operation. Build a cursor that represents the object you're dragging (determined from the original cursor position).
  • When we received a mouse down: if dragging never started then it's a click otherwise use the drop position to determine what to do with the object.

Note: none of this would allow you to drag objects between apps, just inside individual apps.

Ferruccio
A: 

For almost any question like "How do I do this UI thing?"

My answer is always: "Use wxWidgets."

Hugo

Rocketmagnet
A: 

With com:

Create a class that public extends IDropTarget

Register your class for drops. Do this in WM_CREATE

RegisterDragDrop(hwnd,static_cast<IDropTarget*>(pointer_to_your_class));

In your class you need to override a couple of functions since they are pure virtual:

virtual HRESULT STDMETHODCALLTYPE DragEnter( /* [unique][in] */ __RPC__in_opt IDataObject pDataObj, / [in] / DWORD grfKeyState, / [in] / POINTL pt, / [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

virtual HRESULT STDMETHODCALLTYPE DragOver( 
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

virtual HRESULT STDMETHODCALLTYPE DragLeave( void) = 0;

virtual HRESULT STDMETHODCALLTYPE Drop( 
    /* [unique][in] */ __RPC__in_opt IDataObject *pDataObj,
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

Each of those functions will get called when those events occur, i.e. when someone pass the mouse in your window with a file DragEnter on your class will get called.

You will also need to implement a couple more functions that IDropTarget extends, check out IUnknown in your MSDN.

Then you need to query IDataObject param to get the data:

FORMATETC fdrop = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};

      if (SUCCEEDED(pDataObj->QueryGetData(&fdrop)) ){
       STGMEDIUM stgMedium = {0};
       stgMedium.tymed = TYMED_HGLOBAL;
       HRESULT hr = pDataObj->GetData(&fdrop, &stgMedium);
       if (SUCCEEDED(hr))
       {
        HGLOBAL gmem = stgMedium.hGlobal;
        HDROP hdrop = (HDROP)GlobalLock(gmem);
        UINT numOfFiles =  DragQueryFile( (HDROP) hdrop,
          0xFFFFFFFF,
            NULL,
          0
         );

        TCHAR buffer[MAX_PATH];
        for( int i=0;i<numOfFiles;i++ ){
         UINT charsCopied = DragQueryFile( (HDROP) hdrop,
          i,
            buffer,
          MAX_PATH
         );
         MessageBox(NULL,buffer,_T("Archivos a copiar: "),MB_OK);


        }
        // use str
        GlobalUnlock(gmem);


        /*TCHAR* str = (TCHAR*)GlobalLock(gmem);
        // use str
        GlobalUnlock(gmem);*/
        ::ReleaseStgMedium(&stgMedium);
       }

      }

Cheers!

Franco