Click here to Skip to main content
Click here to Skip to main content

Implementing a drop target

, 31 Mar 2001
Rate this:
Please Sign up or sign in to vote.
Simple step by step article explaining how to implement a drop target.

This article is part of the drag and drop interface samples.

  1. Serializing ASCII Data
  2. Modeless child dialog
  3. Modeless sibling dialog
  4. The drag source
  5. The MFC drop target
  6. The TBTextTarget class

Data Drag is coming to town... the drop target

You imagine? Right, there's more than one possibility, this time I'll give you tree. One for your private data, one for the common data in order to receive data from other applications like Excel, WinWord etc. and at last, I'll 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

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 implementing the drop source:

  1. To your drop target class, e.g. my CDialog based class CDropDialog, add a member variable of type UINT:
    UINT m_DragDropFormat;
  2. 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_DragDorpFormat = CF_TEXT;
  3. Add the following lines to stdafx.h:
       #include <afxdisp.h>
       #include <afxole.h>
  4. In your application's InitInstance function, make a call to AfxOleInit() before creating the document template
  5. 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!
  6. If you have another kind of target, there's some more work.
  7. Use the ClassWizard to create a new generic(!) class derived from the MFC(!) class COleDropTarget. I call it CInterfaceDropTarget.
  8. Create and initialize a UINT m_DragDropFormat as in step 2.
  9. 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 won't 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__ " dont't 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);
    }
  10. Don't 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).
  11. In the CWnd-derived class used as drop target, add a member variable of type CInterfaceDropTarget, for example's sake name it m_DT.
  12. At any point where this window exists (for example: OnInitDialog is great) call the Register function of m_DT:
    BOOL CDropDialog::OnInitDialog() 
    {
        CDialog::OnInitDialog();
       m_DT.Register(this);
       // the other stuff follows ....
    }

Done!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Thomas Blenkers
Web Developer
Germany Germany
PhD Chemist,
programming with MSVC & MFC since 1996

Comments and Discussions

 
QuestionHow to get the link and tilte by Drag and drop a link PinmemberEmile.Tu14-Apr-05 15:15 
QuestionHow to get the link and tilte by Drag and drop a link PinmemberEmile.Tu14-Apr-05 15:13 
Questionhow to save a CF_DIB type data to a file Pinmemberhury16-Dec-01 22:34 
AnswerRe: how to save a CF_DIB type data to a file Pinmemberpeluquero8017-Feb-05 11:54 
HANDLE hMem = GetClipboardData(CF_DIB); // handle
LPBYTE lpLock = (LPBYTE) GlobalLock((HGLOBAL) hMem); // locks memory obj
BITMAPINFO *lpBI = (BITMAPINFO *) lpLock;
DWORD nSizeOfDib = sizeof (BITMAPINFO) + lpBI->bmiHeader.biSizeOfImage; // perhaps... check this member
LPBYTE lpBuff = (LPBYTE) calloc((size_t) nSizeOfDib, sizeof(BYTE));
memcpy(lpBuff, lpLock, nSizeOfDib); // copied on buffer!!!
HFILE hFile = OpenFile(...);
DWORD dwWritten;
BOOL bRes = WriteFile(hFile, lpLock, nSizeOfDib, &dwWritten, NULL);
 
// just this, saved!!!
 
to retrieve make the inverse procedure and set the memory into CB...
GeneralMust delete pFile to prevent memory leaks PinmemberAndy [F/C/M]1-Dec-01 0:17 
Generalabout typos in this acticle PinmemberNgHwan Kim11-Jun-01 21:05 
GeneralCorrection: InterfaceView.obj : error LNK2001: unresolved external ... PinmemberThomas Blenkers3-Jun-01 11:42 
QuestionBuggy Sample App??? PinmemberThomas Blenkers12-Nov-00 7:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 1 Apr 2001
Article Copyright 2000 by Thomas Blenkers
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid