1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
| TFiche *Fiche;
class CDropTarget : public IDropTarget
{
public:
static void SetFormat(UINT Outl);
CDropTarget(HWND hListView);
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragLeave)();
STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
private:
static UINT m_Outl;
HWND m_hListView;
ULONG m_refs;
BOOL m_bDropOK;
DWORD GetEffect(DWORD grfKeyState);
void FillFormatEtc(LPFORMATETC lpfect);
};
//---------------------------------------------------------------------------
__fastcall TFiche::TFiche(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
UINT CDropTarget::m_Outl;
void CDropTarget::SetFormat(UINT Outl)
{
m_Outl = Outl;
}
CDropTarget::CDropTarget(HWND hListView): m_hListView(hListView)
{
m_refs = 1;
m_bDropOK = FALSE;
}
STDMETHODIMP CDropTarget::QueryInterface(REFIID iid, void** ppv)
{
if(iid == IID_IUnknown || iid == IID_IDropTarget)
{
*ppv = this;
AddRef();
return NOERROR;
}
*ppv = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CDropTarget::AddRef(void)
{
return ++m_refs;
}
STDMETHODIMP_(ULONG) CDropTarget::Release(void)
{
if(--m_refs == 0)
{
delete this;
return 0;
}
return m_refs;
}
STDMETHODIMP CDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
tagSTGMEDIUM stgm;
tagFORMATETC fmtetc;
IStorage * pstg = NULL;
IStream * pstm = NULL;
FillFormatEtc(&fmtetc); // définit le format
m_bDropOK = false;
// A cause de la valeur de fmtetc.cfFormat, seuls les objets provenant de d'Outlook seront acceptés
if (pDataObj->GetData(&fmtetc, &stgm) == S_OK ) { // Génère le rendu des données qui sont décrites dans la structure pFormatEtc spécifiée et les transfèrent au paramètre b.
pstg = stgm.pstg;
*pdwEffect = GetEffect(grfKeyState);
m_bDropOK = true;
pstm = NULL;
return S_OK;
}
else {
pstg = NULL;
ReleaseStgMedium(&stgm);
ShowMessage("Objet non conforme");
}
}
// Fonction appelée dès que la souris bouge au dessus de la fenêtre
// On a juste a choisir le bon effet (qui dépend de l'état des touches du clavier)
STDMETHODIMP CDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
*pdwEffect = GetEffect(grfKeyState);
return S_OK;
}
// Passage en dehors de la fenêtre: rien a faire
STDMETHODIMP CDropTarget::DragLeave()
{
return S_OK;
}
// Fin du déplacement
STDMETHODIMP CDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
FORMATETC fmtetc;
STGMEDIUM stgm;
*pdwEffect = GetEffect(grfKeyState);
FillFormatEtc(&fmtetc);
// On récupère les données de l'objet
pDataObj->GetData(&fmtetc, &stgm);
ShowMessage("Drag n Drop éfféctué");
return S_OK;
}
// Récupère l'effet en fonction des touches du clavier et de m_bDropOK
DWORD CDropTarget::GetEffect(DWORD grfKeyState)
{
if(!m_bDropOK) return DROPEFFECT_NONE;
if(grfKeyState & MK_CONTROL) return DROPEFFECT_COPY;
return DROPEFFECT_MOVE;
}
void CDropTarget::FillFormatEtc(LPFORMATETC lpfect)
{
lpfect->cfFormat = RegisterClipboardFormat(CFSTR_FILECONTENTS);
lpfect->ptd = NULL;
lpfect->dwAspect = 1;
lpfect->lindex = 0;
lpfect->tymed = TYMED_ISTORAGE;
}
void __fastcall TFiche::FormCreate(TObject *Sender)
{
CDropTarget * pDropTarget = new CDropTarget(GbMSG->Handle);
// Permet a la GbMSG de devenir une cible
RegisterDragDrop(GbMSG->Handle, pDropTarget);
} |