0

我遇到了一个奇怪的问题。它在 Outlook 2K3 上运行良好,但在 Outlook 2K7 和 2K10 上运行良好。

问题 - 如果我从我的应用程序中拖放一个文件并放到 Outlook 2007 中新消息的消息正文中,则不会发生任何事情。相反,预期的行为是 - 文件应附加到消息中。它在 Outlook 2003 中运行良好,我没有对我的代码进行任何更改。
如果我将文件从我的应用程序拖放到 Windows 桌面,它可以正常工作。现在,如果我将同一文件从 Windows 桌面拖放到 Outlook 2007 中的新消息上,文件就会被附加。这让我猜测我的代码需要更改,但我无法弄清楚。

调查 -

我们已经在方法中实现了CFSTR_FILEDESCRIPTOR,CFSTR_FILECONTENTS和。我注意到,在 Outlook 2007 的情况下,当我将文件(从我的应用程序)拖放到新邮件中的邮件正文时,只会调用剪贴板格式。而在 Outlook 2003 的情况下,如果我将文件(从我的应用程序)拖放到新邮件中的邮件正文, 则会调用两次,然后是剪贴板格式。 CF_TXTCDataObject::Getdata()CFSTR_FILEDESCRIPTORCDataObject::GetData()CFSTR_FILEDESCRIPTORCFSTR_FILECONTENTS

在第二个文件中提取内容,因为第二次没有调用 GetData,因此文件没有附加到电子邮件中。以下是示例代码。

有谁知道可能是什么原因?或者我还能尝试缩小问题范围。

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 = PKDropGetData ( 
                                    m_pStruct, 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; 
} 


QueryGetData(LPFORMATETC pFE )
{
UINT uFormat = pFE->cfFormat;
BOOL bRet = FALSE;
if (uFormat == m_fe[0].cfFormat)            // filegroupdescriptor
{
bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
 }
else if (uFormat == m_fe[1].cfFormat)       // filecontents
{
    bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
}
else 
bRet = false; 

 ----
 ----
return (bRet ? S_OK : DV_E_FORMATETC);
 }
4

1 回答 1

0

要调试它,请在调试器中运行它并在此行上设置一个断点:

// FILEDESCRIPTOR format  
if (uFormat == m_fe[0].cfFormat) 

然后一步步过去。

笔记:

如果它之前被调用了两次,一次使用 CFSTR_FILEDESCRIPTOR,然后再次使用 CFSTR_FILECONTENTS,这意味着它第一次失败,可能是因为您不支持所需的TYMED. 然后它再次尝试使用 CFSTR_FILECONTENTS。

我怀疑 CFSTR_FILEDESCRIPTOR 从来没有工作过,Outlook 在第一次失败后根本不再尝试第二种格式。

  • 您是否指定了一个您不支持的 TYMED 来响应QueryGetDataEnumFORMATETC

如果是这样,Outlook 可能会要求在 IStream 中输入 FILEGROUPDESCRIPTOR,当您返回错误时,它只是放弃了。

于 2012-06-19T13:50:57.670 回答