Discussion:
Help : Unable to drop a file on a new message in outlook 2007
(too old to reply)
sisrahul
2012-06-19 12:04:41 UTC
Permalink
Hello,

I am facing a strange issue.It is working well with outlook 2K3 but not anymore on outlook 2K7 and 2K10.

Problem -
If I drag a file from my application and drop onto the message body in a new message in outlook 2007 nothing happens. Instead the expected behavior is - file should attach to the message. It work well in outlook 2003 and I haven't made any change in my code.
If I drag file from my application and drop on to windows desktop, it works without any problem. Now if I drag the same file from Windows desktop and drop onto the new message in outlook 2007, file gets attached. This leaves me guessing that there is something need to change in my code but I unable to figure out.

Investigation -

We have implemented the CFSTR_FILEDESCRIPTOR, CFSTR_FILECONTENTS and CF_TXT in the CDataObject::Getdata() method.
I have noticed is that in case of outlook 2007, when I drop file(from my application) to message body in new message, only CFSTR_FILEDESCRIPTOR clipboard format is called.
While in case of outlook 2003, if I drop file(from my application) to message body in new message CDataObject::GetData() is called two times, CFSTR_FILEDESCRIPTOR followed by CFSTR_FILECONTENTS clipboard formats.

In the second file contents are extracted since GetData is not called second time hence file is not attached to email. Following is the sample code.

Does anyone know what could be the reason ? Or what else i can try to narrow down the issue.


STDMETHODIMP CDataObject::GetData (
LPFORMATETC pFE,
LPSTGMEDIUM pSTM)
{
HGLOBAL hMem;
LPFILEGROUPDESCRIPTOR pfgd;
UINT uFormat, uBytes;
void* p;

m_uFmtUsed = 0;
uFormat = pFE->cfFormat;

// FILEDESCRIPTOR format
if (uFormat == m_fe[0].cfFormat)
{
if (!(pFE->dwAspect & DVASPECT_CONTENT))
return DV_E_DVASPECT;
if (!(pFE->tymed & TYMED_HGLOBAL))
return DV_E_FORMATETC;

hMem=GlobalAlloc (GMEM_SHARE | GMEM_MOVEABLE,
sizeof(FILEGROUPDESCRIPTOR));

if (hMem == NULL)
return STG_E_MEDIUMFULL;

pfgd = (LPFILEGROUPDESCRIPTOR)GlobalLock (hMem);
pfgd->cItems = 1;
pfgd->fgd[0].dwFlags = FD_ATTRIBUTES;
pfgd->fgd[0].dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
lstrcpy (pfgd->fgd[0].cFileName, m_pszName);

GlobalUnlock (hMem);

pSTM->hGlobal = hMem;
pSTM->tymed = TYMED_HGLOBAL;
pSTM->pUnkForRelease = NULL;
m_uFmtUsed = uFormat;
return S_OK;
}

// FILECONTENTS clipboard format
else if (uFormat == m_fe[1].cfFormat)
{
if (!(pFE->dwAspect & DVASPECT_CONTENT))
return DV_E_DVASPECT;
if (!(pFE->tymed & TYMED_HGLOBAL))
return DV_E_FORMATETC;

if (!m_pData)
{
m_pData = PKDropKeysGetData (
(PPGPKEYSSTRUCT)m_pKeysStruct, FALSE, FALSE, &uBytes);
}

hMem = GlobalAlloc (GMEM_SHARE|GMEM_MOVEABLE, uBytes);

if (hMem == NULL)
return STG_E_MEDIUMFULL;

p = GlobalLock (hMem);
memcpy (p, m_pData, uBytes);
GlobalUnlock (hMem);

pSTM->hGlobal = hMem;
pSTM->tymed = TYMED_HGLOBAL;
pSTM->pUnkForRelease = NULL;
m_uFmtUsed = uFormat;
return S_OK;
}

....
.....
....
return DV_E_FORMATETC;
}

~Rahul
sisrahul
2012-06-20 11:47:58 UTC
Permalink
Fixed the problem -
I noticed in the QueryGetData outlook 2K7 is looking for IStream or IStorage TYMED so I modified GetData and QueryGetData methods accordingly. Drag n Drop works fine now
Post by sisrahul
Hello,
I am facing a strange issue.It is working well with outlook 2K3 but not anymore on outlook 2K7 and 2K10.
Problem -
If I drag a file from my application and drop onto the message body in a new message in outlook 2007 nothing happens. Instead the expected behavior is - file should attach to the message. It work well in outlook 2003 and I haven't made any change in my code.
If I drag file from my application and drop on to windows desktop, it works without any problem. Now if I drag the same file from Windows desktop and drop onto the new message in outlook 2007, file gets attached. This leaves me guessing that there is something need to change in my code but I unable to figure out.
Investigation -
We have implemented the CFSTR_FILEDESCRIPTOR, CFSTR_FILECONTENTS and CF_TXT in the CDataObject::Getdata() method.
I have noticed is that in case of outlook 2007, when I drop file(from my application) to message body in new message, only CFSTR_FILEDESCRIPTOR clipboard format is called.
While in case of outlook 2003, if I drop file(from my application) to message body in new message CDataObject::GetData() is called two times, CFSTR_FILEDESCRIPTOR followed by CFSTR_FILECONTENTS clipboard formats.
In the second file contents are extracted since GetData is not called second time hence file is not attached to email. Following is the sample code.
Does anyone know what could be the reason ? Or what else i can try to narrow down the issue.
STDMETHODIMP CDataObject::GetData (
LPFORMATETC pFE,
LPSTGMEDIUM pSTM)
{
HGLOBAL hMem;
LPFILEGROUPDESCRIPTOR pfgd;
UINT uFormat, uBytes;
void* p;
m_uFmtUsed = 0;
uFormat = pFE->cfFormat;
// FILEDESCRIPTOR format
if (uFormat == m_fe[0].cfFormat)
{
if (!(pFE->dwAspect & DVASPECT_CONTENT))
return DV_E_DVASPECT;
if (!(pFE->tymed & TYMED_HGLOBAL))
return DV_E_FORMATETC;
hMem=GlobalAlloc (GMEM_SHARE | GMEM_MOVEABLE,
sizeof(FILEGROUPDESCRIPTOR));
if (hMem == NULL)
return STG_E_MEDIUMFULL;
pfgd = (LPFILEGROUPDESCRIPTOR)GlobalLock (hMem);
pfgd->cItems = 1;
pfgd->fgd[0].dwFlags = FD_ATTRIBUTES;
pfgd->fgd[0].dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
lstrcpy (pfgd->fgd[0].cFileName, m_pszName);
GlobalUnlock (hMem);
pSTM->hGlobal = hMem;
pSTM->tymed = TYMED_HGLOBAL;
pSTM->pUnkForRelease = NULL;
m_uFmtUsed = uFormat;
return S_OK;
}
// FILECONTENTS clipboard format
else if (uFormat == m_fe[1].cfFormat)
{
if (!(pFE->dwAspect & DVASPECT_CONTENT))
return DV_E_DVASPECT;
if (!(pFE->tymed & TYMED_HGLOBAL))
return DV_E_FORMATETC;
if (!m_pData)
{
m_pData = PKDropKeysGetData (
(PPGPKEYSSTRUCT)m_pKeysStruct, FALSE, FALSE, &uBytes);
}
hMem = GlobalAlloc (GMEM_SHARE|GMEM_MOVEABLE, uBytes);
if (hMem == NULL)
return STG_E_MEDIUMFULL;
p = GlobalLock (hMem);
memcpy (p, m_pData, uBytes);
GlobalUnlock (hMem);
pSTM->hGlobal = hMem;
pSTM->tymed = TYMED_HGLOBAL;
pSTM->pUnkForRelease = NULL;
m_uFmtUsed = uFormat;
return S_OK;
}
....
.....
....
return DV_E_FORMATETC;
}
~Rahul
Loading...