Click here to Skip to main content
12,296,162 members (62,969 online)
Click here to Skip to main content

Stats

123.9K views
2.4K downloads
105 bookmarked
Posted

WTL for MFC Programmers, Part X - Implementing a Drag and Drop Source

, 16 Jun 2006
A tutorial on using drag and drop in your WTL application.
// DragDropSource.h: interface for the CDragDropSource class.
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DRAGDROPSOURCE_H__93E203FE_B672_421E_A008_FE8B3BD71FFA__INCLUDED_)
#define AFX_DRAGDROPSOURCE_H__93E203FE_B672_421E_A008_FE8B3BD71FFA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// Drag/drop source implementation, IDataObject impl is taken from a
// technical article in MSDN:
// http://msdn.microsoft.com/library/en-us/dnwui/html/ddhelp_pt2.asp

class CDragDropSource : public CComObjectRootEx<CComSingleThreadModel>,
                        public CComCoClass<CDragDropSource>,
                        public IDataObject,
                        public IDropSource
{
public:
    // Construction
    CDragDropSource();
    ~CDragDropSource();

    // Maps
    BEGIN_COM_MAP(CDragDropSource)
        COM_INTERFACE_ENTRY(IDataObject)
        COM_INTERFACE_ENTRY(IDropSource)
    END_COM_MAP()

    // Operations
    bool Init ( LPCTSTR szCabFilePath, std::vector<CDraggedFileInfo>& vec );

    HRESULT DoDragDrop ( DWORD dwOKEffects, DWORD* pdwEffect );
    const std::vector<CDraggedFileInfo>& GetDragResults() const { return m_vecDraggedFiles; }

    // IDataObject
    STDMETHODIMP SetData ( FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease );
    STDMETHODIMP GetData ( FORMATETC* pformatetcIn, STGMEDIUM* pmedium );
    STDMETHODIMP EnumFormatEtc ( DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc );
    STDMETHODIMP QueryGetData ( FORMATETC* pformatetc );

    STDMETHODIMP GetDataHere(FORMATETC* pformatetc, STGMEDIUM *pmedium)
        { return E_NOTIMPL; }
    STDMETHODIMP GetCanonicalFormatEtc(FORMATETC* pformatectIn,
                                       FORMATETC* pformatetcOut)
        { return E_NOTIMPL; }
    STDMETHODIMP DAdvise(FORMATETC* pformatetc, DWORD advf,
                         IAdviseSink* pAdvSink, DWORD* pdwConnection)
        { return E_NOTIMPL; }
    STDMETHODIMP DUnadvise(DWORD dwConnection)
        { return E_NOTIMPL; }
    STDMETHODIMP EnumDAdvise(IEnumSTATDATA** ppenumAdvise)
        { return E_NOTIMPL; }

    // IDropSource
    STDMETHODIMP QueryContinueDrag ( BOOL fEscapePressed, DWORD grfKeyState );
    STDMETHODIMP GiveFeedback ( DWORD dwEffect );

    // Implementation
protected:
    bool  m_bInitialized;
    DWORD m_dwLastEffect;

    std::vector<CDraggedFileInfo> m_vecDraggedFiles;
    CString m_sCabFilePath;
    CString m_sFileBeingExtracted;
    std::vector<CDraggedFileInfo>::iterator m_it;   // itr on file currently being extracted
    bool m_bAbortingDueToMissingCab;

    // List of FORMATETCs for which we have data, used in EnumFormatEtc
    std::vector<FORMATETC> m_vecSupportedFormats;

    typedef struct 
    {
        FORMATETC fe;
        STGMEDIUM stgm;
    } DATAENTRY, *LPDATAENTRY;

    LPDATAENTRY m_rgde;                 // Array of active DATAENTRY entries
    int m_cde;                          // Size of m_rgde

    // Helper functions used by IDataObject methods
    HRESULT   FindFORMATETC ( FORMATETC* pfe, LPDATAENTRY* ppde, BOOL fAdd );
    HRESULT   AddRefStgMedium ( STGMEDIUM* pstgmIn, STGMEDIUM* pstgmOut, BOOL fCopyIn );
    HGLOBAL   GlobalClone ( HGLOBAL hglobIn );
    IUnknown* GetCanonicalIUnknown ( IUnknown* punk );

    // CAB extraction/callback methods
    bool ExtractFilesFromCab();

    static int DIAMONDAPI fdi_Notify ( FDINOTIFICATIONTYPE message, PFDINOTIFICATION pInfo );
    int Notify_PartialFile ( LPCTSTR szFilename, LPCTSTR szStartingCabName, LPCTSTR szStartingDiskName );
    int Notify_CopyFile ( LPCTSTR szFilename, long cbyUncompressedSize, USHORT uDate, USHORT uTime,
                          USHORT uAttribs, USHORT uFolderIdx );
    int Notify_FileDone ( LPCTSTR szFilename, int nFileHandle, USHORT uDate, USHORT uTime,
                          USHORT uAttribs, USHORT uFolderIdx, bool bRunAfterExtracting );
    int Notify_NextCabinet ( LPCTSTR szNextCabName, LPCTSTR szNextDiskName, LPCTSTR szNextCabDir, FDIERROR err );
};

#endif // !defined(AFX_DRAGDROPSOURCE_H__93E203FE_B672_421E_A008_FE8B3BD71FFA__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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

Michael Dunn
Software Developer (Senior) VMware
United States United States
Michael lives in sunny Mountain View, California. He started programming with an Apple //e in 4th grade, graduated from UCLA with a math degree in 1994, and immediately landed a job as a QA engineer at Symantec, working on the Norton AntiVirus team. He pretty much taught himself Windows and MFC programming, and in 1999 he designed and coded a new interface for Norton AntiVirus 2000.
Mike has been a a developer at Napster and at his own lil' startup, Zabersoft, a development company he co-founded with offices in Los Angeles and Odense, Denmark. Mike is now a senior engineer at VMware.

He also enjoys his hobbies of playing pinball, bike riding, photography, and Domion on Friday nights (current favorite combo: Village + double Pirate Ship). He would get his own snooker table too if they weren't so darn big! He is also sad that he's forgotten the languages he's studied: French, Mandarin Chinese, and Japanese.

Mike was a VC MVP from 2005 to 2009.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 16 Jun 2006
Article Copyright 2006 by Michael Dunn
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid