Rewrote GetData so support multiple selections.
This commit is contained in:
parent
4b0dea2cac
commit
910169fd14
|
@ -12,6 +12,7 @@
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "shell32_main.h"
|
#include "shell32_main.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
#include "wine/undocshell.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(shell)
|
DEFAULT_DEBUG_CHANNEL(shell)
|
||||||
|
|
||||||
|
@ -58,20 +59,25 @@ LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
|
||||||
IEnumFORMATETCImpl* ef;
|
IEnumFORMATETCImpl* ef;
|
||||||
DWORD size=cfmt * sizeof(FORMATETC);
|
DWORD size=cfmt * sizeof(FORMATETC);
|
||||||
|
|
||||||
ef=(IEnumFORMATETCImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETCImpl));
|
ef=(IEnumFORMATETCImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumFORMATETCImpl));
|
||||||
ef->ref=1;
|
|
||||||
ef->lpvtbl=&efvt;
|
|
||||||
|
|
||||||
ef->posFmt = 0;
|
if(ef)
|
||||||
ef->countFmt = cfmt;
|
{
|
||||||
ef->pFmt = SHAlloc (size);
|
ef->ref=1;
|
||||||
|
ef->lpvtbl=&efvt;
|
||||||
|
|
||||||
if (ef->pFmt)
|
ef->countFmt = cfmt;
|
||||||
{ memcpy(ef->pFmt, afmt, size);
|
ef->pFmt = SHAlloc (size);
|
||||||
|
|
||||||
|
if (ef->pFmt)
|
||||||
|
{
|
||||||
|
memcpy(ef->pFmt, afmt, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
shell32_ObjCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("(%p)->()\n",ef);
|
TRACE("(%p)->()\n",ef);
|
||||||
shell32_ObjCount++;
|
|
||||||
return (LPENUMFORMATETC)ef;
|
return (LPENUMFORMATETC)ef;
|
||||||
}
|
}
|
||||||
static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
|
static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
|
||||||
|
@ -241,13 +247,15 @@ static IDLList_VTable idllvt =
|
||||||
};
|
};
|
||||||
|
|
||||||
LPIDLLIST IDLList_Constructor (UINT uStep)
|
LPIDLLIST IDLList_Constructor (UINT uStep)
|
||||||
{ LPIDLLIST lpidll;
|
{
|
||||||
if (!(lpidll = (LPIDLLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IDLList))))
|
LPIDLLIST lpidll;
|
||||||
return NULL;
|
lpidll = (LPIDLLIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDLList));
|
||||||
|
|
||||||
lpidll->lpvtbl=&idllvt;
|
if (lpidll)
|
||||||
lpidll->uStep=uStep;
|
{
|
||||||
lpidll->dpa=NULL;
|
lpidll->lpvtbl=&idllvt;
|
||||||
|
lpidll->uStep=uStep;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("(%p)\n",lpidll);
|
TRACE("(%p)\n",lpidll);
|
||||||
return lpidll;
|
return lpidll;
|
||||||
|
@ -261,11 +269,13 @@ static UINT WINAPI IDLList_GetState(LPIDLLIST this)
|
||||||
{ TRACE("(%p)->(uStep=%u dpa=%p)\n",this, this->uStep, this->dpa);
|
{ TRACE("(%p)->(uStep=%u dpa=%p)\n",this, this->uStep, this->dpa);
|
||||||
|
|
||||||
if (this->uStep == 0)
|
if (this->uStep == 0)
|
||||||
{ if (this->dpa)
|
{
|
||||||
|
if (this->dpa)
|
||||||
return(State_Init);
|
return(State_Init);
|
||||||
return(State_OutOfMem);
|
|
||||||
}
|
return(State_OutOfMem);
|
||||||
return(State_UnInit);
|
}
|
||||||
|
return(State_UnInit);
|
||||||
}
|
}
|
||||||
static LPITEMIDLIST WINAPI IDLList_GetElement(LPIDLLIST this, UINT nIndex)
|
static LPITEMIDLIST WINAPI IDLList_GetElement(LPIDLLIST this, UINT nIndex)
|
||||||
{ TRACE("(%p)->(index=%u)\n",this, nIndex);
|
{ TRACE("(%p)->(index=%u)\n",this, nIndex);
|
||||||
|
@ -344,7 +354,6 @@ typedef struct
|
||||||
ICOM_VTABLE(IDataObject)* lpvtbl;
|
ICOM_VTABLE(IDataObject)* lpvtbl;
|
||||||
DWORD ref;
|
DWORD ref;
|
||||||
/* IDataObject fields */
|
/* IDataObject fields */
|
||||||
LPSHELLFOLDER psf;
|
|
||||||
LPIDLLIST lpill; /* the data of the dataobject */
|
LPIDLLIST lpill; /* the data of the dataobject */
|
||||||
LPITEMIDLIST pidl;
|
LPITEMIDLIST pidl;
|
||||||
} IDataObjectImpl;
|
} IDataObjectImpl;
|
||||||
|
@ -382,26 +391,29 @@ static struct ICOM_VTABLE(IDataObject) dtovt =
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* IDataObject_Constructor
|
* IDataObject_Constructor
|
||||||
*/
|
*/
|
||||||
LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT cidl)
|
LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPITEMIDLIST pMyPidl, LPITEMIDLIST * apidl, UINT cidl)
|
||||||
{
|
{
|
||||||
IDataObjectImpl* dto;
|
IDataObjectImpl* dto;
|
||||||
if (!(dto = (IDataObjectImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObjectImpl))))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dto->ref=1;
|
|
||||||
dto->lpvtbl=&dtovt;
|
|
||||||
dto->psf=psf;
|
|
||||||
dto->pidl=ILClone(((IGenericSFImpl*)psf)->pMyPidl); /* FIXME:add a reference and don't copy*/
|
|
||||||
|
|
||||||
/* fill the ItemID List List */
|
dto = (IDataObjectImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDataObjectImpl));
|
||||||
dto->lpill = IDLList_Constructor (8);
|
|
||||||
if (! dto->lpill )
|
if (dto)
|
||||||
return NULL;
|
{
|
||||||
|
dto->ref=1;
|
||||||
|
dto->lpvtbl=&dtovt;
|
||||||
|
dto->pidl=ILClone(pMyPidl);
|
||||||
|
|
||||||
|
/* fill the ItemID List List */
|
||||||
|
dto->lpill = IDLList_Constructor (8);
|
||||||
|
if (! dto->lpill )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl);
|
dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl);
|
||||||
|
|
||||||
|
shell32_ObjCount++;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
|
TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
|
||||||
shell32_ObjCount++;
|
|
||||||
return (LPDATAOBJECT)dto;
|
return (LPDATAOBJECT)dto;
|
||||||
}
|
}
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
@ -430,7 +442,7 @@ static HRESULT WINAPI IDataObject_fnQueryInterface(LPDATAOBJECT iface, REFIID ri
|
||||||
}
|
}
|
||||||
TRACE("-- Interface: E_NOINTERFACE\n");
|
TRACE("-- Interface: E_NOINTERFACE\n");
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* IDataObject_AddRef
|
* IDataObject_AddRef
|
||||||
*/
|
*/
|
||||||
|
@ -469,11 +481,11 @@ static ULONG WINAPI IDataObject_fnRelease(LPDATAOBJECT iface)
|
||||||
*/
|
*/
|
||||||
static BOOL DATAOBJECT_InitShellIDList(void)
|
static BOOL DATAOBJECT_InitShellIDList(void)
|
||||||
{ if (cfShellIDList)
|
{ if (cfShellIDList)
|
||||||
{ return(TRUE);
|
{ return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
|
cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
|
||||||
return(cfShellIDList != 0);
|
return(cfShellIDList != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -485,11 +497,11 @@ static BOOL DATAOBJECT_InitShellIDList(void)
|
||||||
/* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
|
/* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
|
||||||
static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
|
static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
|
||||||
{ if (cfFileGroupDesc)
|
{ if (cfFileGroupDesc)
|
||||||
{ return(TRUE);
|
{ return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfFileGroupDesc = RegisterClipboardFormatA(CFSTR_FILEDESCRIPTORA);
|
cfFileGroupDesc = RegisterClipboardFormatA(CFSTR_FILEDESCRIPTORA);
|
||||||
return(cfFileGroupDesc != 0);
|
return(cfFileGroupDesc != 0);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -501,81 +513,94 @@ static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
|
||||||
/* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
|
/* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
|
||||||
static BOOL32 DATAOBJECT_InitFileContents(void)
|
static BOOL32 DATAOBJECT_InitFileContents(void)
|
||||||
{ if (cfFileContents)
|
{ if (cfFileContents)
|
||||||
{ return(TRUE);
|
{ return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfFileContents = RegisterClipboardFormatA(CFSTR_FILECONTENTS);
|
cfFileContents = RegisterClipboardFormatA(CFSTR_FILECONTENTS);
|
||||||
return(cfFileContents != 0);
|
return(cfFileContents != 0);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* interface implementation
|
* IDataObject_fnGetData
|
||||||
*/
|
*/
|
||||||
static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
|
static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
|
||||||
{
|
{
|
||||||
ICOM_THIS(IDataObjectImpl,iface);
|
ICOM_THIS(IDataObjectImpl,iface);
|
||||||
char temp[256];
|
|
||||||
|
char szTemp[256];
|
||||||
UINT cItems;
|
UINT cItems;
|
||||||
DWORD size, size1, size2;
|
DWORD sizeCIDA, sizePidl, nOffset, nSize;
|
||||||
LPITEMIDLIST pidl;
|
LPCIDA pcida;
|
||||||
LPCIDA pcida;
|
HGLOBAL hmem;
|
||||||
HGLOBAL hmem;
|
int i;
|
||||||
|
LPITEMIDLIST pidl;
|
||||||
|
|
||||||
GetClipboardFormatNameA (pformatetcIn->cfFormat, temp, 256);
|
GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
|
||||||
WARN("(%p)->(%p %p format=%s)semi-stub\n", This, pformatetcIn, pmedium, temp);
|
TRACE("(%p)->(%p %p format=%s)\n", This, pformatetcIn, pmedium, szTemp);
|
||||||
|
|
||||||
if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
|
/* is the clipformat registred? */
|
||||||
{ return(E_UNEXPECTED);
|
if (!DATAOBJECT_InitShellIDList()) return(E_UNEXPECTED);
|
||||||
}
|
|
||||||
|
|
||||||
if (pformatetcIn->cfFormat == cfShellIDList)
|
/* test expected format */
|
||||||
{ if (pformatetcIn->ptd==NULL
|
if (!(pformatetcIn->cfFormat == cfShellIDList))
|
||||||
&& (pformatetcIn->dwAspect & DVASPECT_CONTENT)
|
{
|
||||||
&& pformatetcIn->lindex==-1
|
FIXME("-- clipformat not implemented\n");
|
||||||
&& (pformatetcIn->tymed&TYMED_HGLOBAL))
|
return (E_INVALIDARG);
|
||||||
{ cItems = This->lpill->lpvtbl->fnGetCount(This->lpill);
|
|
||||||
if (cItems < 1)
|
|
||||||
{ return(E_UNEXPECTED);
|
|
||||||
}
|
|
||||||
pidl = This->lpill->lpvtbl->fnGetElement(This->lpill, 0);
|
|
||||||
|
|
||||||
pdump(This->pidl);
|
|
||||||
pdump(pidl);
|
|
||||||
|
|
||||||
/*hack consider only the first item*/
|
|
||||||
cItems = 2;
|
|
||||||
size = sizeof(CIDA) + sizeof (UINT)*(cItems-1);
|
|
||||||
size1 = ILGetSize (This->pidl);
|
|
||||||
size2 = ILGetSize (pidl);
|
|
||||||
hmem = GlobalAlloc(GMEM_FIXED, size+size1+size2);
|
|
||||||
pcida = GlobalLock (hmem);
|
|
||||||
if (!pcida)
|
|
||||||
{ return(E_OUTOFMEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
pcida->cidl = 1;
|
|
||||||
pcida->aoffset[0] = size;
|
|
||||||
pcida->aoffset[1] = size+size1;
|
|
||||||
|
|
||||||
TRACE("-- %lu %lu %lu\n",size, size1, size2 );
|
|
||||||
TRACE("-- %p %p\n",This->pidl, pidl);
|
|
||||||
TRACE("-- %p %p %p\n",pcida, (LPBYTE)pcida+size,(LPBYTE)pcida+size+size1);
|
|
||||||
|
|
||||||
memcpy ((LPBYTE)pcida+size, This->pidl, size1);
|
|
||||||
memcpy ((LPBYTE)pcida+size+size1, pidl, size2);
|
|
||||||
TRACE("-- after copy\n");
|
|
||||||
|
|
||||||
GlobalUnlock(hmem);
|
|
||||||
|
|
||||||
pmedium->tymed = TYMED_HGLOBAL;
|
|
||||||
pmedium->u.hGlobal = (HGLOBAL)pcida;
|
|
||||||
pmedium->pUnkForRelease = NULL;
|
|
||||||
TRACE("-- ready\n");
|
|
||||||
return(NOERROR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FIXME("-- clipformat not implemented\n");
|
|
||||||
|
if (pformatetcIn->ptd==NULL
|
||||||
|
&& (pformatetcIn->dwAspect & DVASPECT_CONTENT)
|
||||||
|
&& pformatetcIn->lindex==-1
|
||||||
|
&& (pformatetcIn->tymed&TYMED_HGLOBAL))
|
||||||
|
{
|
||||||
|
cItems = This->lpill->lpvtbl->fnGetCount(This->lpill);
|
||||||
|
if (cItems < 1) return(E_UNEXPECTED);
|
||||||
|
|
||||||
|
sizeCIDA = sizeof(CIDA) + sizeof (UINT)*(cItems); /* without any pidl */
|
||||||
|
sizePidl = ILGetSize (This->pidl); /* add root pidl */
|
||||||
|
|
||||||
|
nSize = sizeCIDA + sizePidl;
|
||||||
|
hmem = GlobalAlloc(GHND|GMEM_SHARE, nSize);
|
||||||
|
if (!hmem) return(E_OUTOFMEMORY);
|
||||||
|
pcida = GlobalLock (hmem);
|
||||||
|
|
||||||
|
nOffset = sizeCIDA; /* start after the CIDA */
|
||||||
|
pcida->cidl = cItems;
|
||||||
|
|
||||||
|
pcida->aoffset[0] = nOffset; /* first element */
|
||||||
|
memcpy(((LPBYTE)pcida)+nOffset, This->pidl, sizePidl);
|
||||||
|
nOffset += sizePidl;
|
||||||
|
pdump(This->pidl);
|
||||||
|
|
||||||
|
for (i=0; i< cItems; i++)
|
||||||
|
{
|
||||||
|
pidl = This->lpill->lpvtbl->fnGetElement(This->lpill, i);
|
||||||
|
sizePidl = ILGetSize (pidl);
|
||||||
|
nSize += sizePidl; /* size of the structure */
|
||||||
|
pdump(pidl);
|
||||||
|
|
||||||
|
GlobalUnlock(hmem); /* grow memory */
|
||||||
|
hmem = GlobalReAlloc(hmem, nSize, GHND|GMEM_SHARE);
|
||||||
|
if (!hmem) return(E_OUTOFMEMORY);
|
||||||
|
pcida = GlobalLock (hmem);
|
||||||
|
|
||||||
|
pcida->aoffset[i+1] = nOffset; /* copy element */
|
||||||
|
memcpy(((LPBYTE)pcida)+nOffset, pidl, sizePidl);
|
||||||
|
nOffset += sizePidl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalUnlock(hmem);
|
||||||
|
|
||||||
|
pmedium->tymed = TYMED_HGLOBAL;
|
||||||
|
pmedium->u.hGlobal = hmem;
|
||||||
|
pmedium->pUnkForRelease = NULL;
|
||||||
|
|
||||||
|
TRACE("(%p)->(cida at %p)\n", This, pcida);
|
||||||
|
return hmem;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME("-- can't serve format\n");
|
||||||
return (E_INVALIDARG);
|
return (E_INVALIDARG);
|
||||||
}
|
}
|
||||||
static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium)
|
static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium)
|
||||||
|
|
Loading…
Reference in New Issue