From: Brendan on
I'm having trouble tring to get the contents of a file draged from
Explorer to my app.

I was wondering what I'm doing wrong, here's what I have

//---------------------------------------------------------------------------





#pragma hdrstop

#define DEBUG



#include <windows.h>

#include <objidl.h>

#include <shlobj.h>



class MyDropTarget : public IDropTarget{



public:

// IUnknown implementation

HRESULT __stdcall QueryInterface (REFIID iid, void ** ppvObject);

ULONG __stdcall AddRef (void);

ULONG __stdcall Release (void);



// IDropTarget implementation

HRESULT __stdcall DragEnter(IDataObject * pDataObject, DWORD
grfKeyState, POINTL pt, DWORD * pdwEffect);

HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *
pdwEffect);

HRESULT __stdcall DragLeave(void);

HRESULT __stdcall Drop(IDataObject * pDataObject, DWORD
grfKeyState, POINTL pt, DWORD * pdwEffect);



// Constructor

MyDropTarget(HWND hwnd);





private:



// internal helper function

DWORD DropEffect(DWORD grfKeyState, POINTL pt, DWORD dwAllowed);

bool QueryDataObject(IDataObject *pDataObject);



// Private member variables

long refCount;

HWND hWnd;

bool AllowDrop;

short FileContentsFormat;

short FileDescriptorFormat;



// Other internal window members

} ;



#include "debug.h"

void EnumFormats(IDataObject *DataObject){

IEnumFORMATETC * enumObj;

FORMATETC frmt;

DataObject->EnumFormatEtc(DATADIR_GET,&enumObj);

while (enumObj->Next(1,&frmt,NULL) == S_OK){

char * Name = new char[300];

GetClipboardFormatName(frmt.cfFormat,Name,300);

Debug_Msg(Name);

}

}

void DropData(HWND hWnd, IDataObject *DataObject, short
FileDescriptorFormat, short FileContentsFormat)

{

Debug_Func();

// construct a FORMATETC object

FORMATETC frmtEtc = {FileDescriptorFormat, 0,

DVASPECT_CONTENT, -1, TYMED_HGLOBAL};

STGMEDIUM stgMed;



// See if the dataobject contains any TEXT stored as a HGLOBAL



if(DataObject->QueryGetData(&frmtEtc) == S_OK)

{

// Yippie! the data is there, so go get it!

DataObject->GetData(&frmtEtc, &stgMed);

if(DataObject->GetData(&frmtEtc, &stgMed) == S_OK)

{

Debug_Func();

// we asked for the data as a HGLOBAL, so access it appropriately

FILEGROUPDESCRIPTOR * data = (FILEGROUPDESCRIPTOR
*)GlobalLock(stgMed.hGlobal);

Debug_Msg((ULONG)data);

Debug_Msg( data->cItems);

FILEDESCRIPTOR * files = data->fgd;

for (unsigned int i = 0; i < data->cItems;++i){

Debug_Msg(files[i].cFileName);

}

//SetWindowText(hWnd, (char *)data);

//GlobalUnlock(stgMed.hGlobal);



// release the data using the COM API

ReleaseStgMedium(&stgMed);

}

}

}



void RegisterDropWindow(HWND hWnd, MyDropTarget **DropTarget)

{

Debug_Func();

HRESULT Result;

*DropTarget = new MyDropTarget(hWnd);



// acquire a strong lock

CoLockObjectExternal(*DropTarget, TRUE, FALSE);



// tell OLE that the window is a drop target



RegisterDragDrop(hWnd, *DropTarget);



}



void UnregisterDropWindow(HWND hWnd, IDropTarget *DropTarget)

{

Debug_Func();

// remove drag+drop

RevokeDragDrop(hWnd);



// remove the strong lock

CoLockObjectExternal(DropTarget, FALSE, TRUE);



// release our own reference

DropTarget->Release();

}



//---------------- Class Implementation ------------------------------







//

// Constructor for the CDropTarget class

//

MyDropTarget::MyDropTarget(HWND hwnd)

{

Debug_Func();

refCount = 1;

hWnd = hwnd;

AllowDrop = false;

FileContentsFormat = RegisterClipboardFormat(CFSTR_FILECONTENTS );

FileDescriptorFormat = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR
);

}



ULONG __stdcall MyDropTarget::AddRef(){

return InterlockedIncrement(&refCount);

}



//

// IUnknown::Release

//

ULONG __stdcall MyDropTarget::Release(){

LONG count = InterlockedDecrement(&refCount);

if(count == 0){

delete this;

return 0;

} else

return count;

}



//

// IUnknown::QueryInterface

//

HRESULT __stdcall MyDropTarget::QueryInterface(REFIID iid, void
**object){

Debug_Func();

if(iid == IID_IDropTarget || iid == IID_IUnknown){

AddRef();

*object = this;

return S_OK;

}



*object = NULL;

return E_NOINTERFACE;



}





//

// QueryDataObject private helper routine

//

bool MyDropTarget::QueryDataObject(IDataObject *pDataObject)

{

Debug_Func();

FORMATETC FrmtEtc = {FileDescriptorFormat, 0, DVASPECT_CONTENT, -1,
TYMED_ISTREAM };

//EnumFormats(pDataObject);


HRESULT result = pDataObject->QueryGetData(&FrmtEtc);



return true;

// does the data object support FILEDESCRIPTOR using a HGLOBAL?

return pDataObject->QueryGetData(&FrmtEtc) == S_OK ? true : false;

}



//

// DropEffect private helper routine

//

DWORD MyDropTarget::DropEffect(DWORD KeyState, POINTL point, DWORD
Allowed)

{

Debug_Func();

DWORD Effect = 0;



// 1. check "pt" -> do we allow a drop at the specified coordinates?



// 2. work out that the drop-effect should be based on grfKeyState

if(KeyState & MK_CONTROL)

Effect = Allowed & DROPEFFECT_COPY;

else if(KeyState & MK_SHIFT)

Effect = Allowed & DROPEFFECT_MOVE;



// 3. no key-modifiers were specified (or drop effect not allowed), so

// base the effect on those allowed by the dropsource

if(Effect == 0)

{

if(Allowed & DROPEFFECT_COPY)

Effect = DROPEFFECT_COPY;

if(Allowed & DROPEFFECT_MOVE)

Effect = DROPEFFECT_MOVE;

}



return Effect;

}





//

// IDropTarget::DragEnter

//

//

//

HRESULT __stdcall MyDropTarget::DragEnter(IDataObject * DataObject,

DWORD KeyState, POINTL point, DWORD * Effect)

{

Debug_Func();

// does the dataobject contain data we want?

AllowDrop = QueryDataObject(DataObject);



if(AllowDrop)

{

// get the dropeffect based on keyboard state