0

Outlook 2K3 では問題なく動作していますが、Outlook 2K7 および 2K10 では動作しません。

問題 - アプリケーションからファイルをドラッグして Outlook 2007 の新しいメッセージのメッセージ本文にドロップしても、何も起こりません。代わりに、予想される動作は次のとおりです。ファイルはメッセージに添付する必要があります。Outlook 2003 で問題なく動作し、コードを変更していません。
アプリケーションからファイルをドラッグして Windows デスクトップにドロップすると、問題なく動作します。同じファイルを Windows デスクトップからドラッグして Outlook 2007 の新しいメッセージにドロップすると、ファイルが添付されます。これにより、コードを変更する必要があると推測できますが、わかりません。

調査 -

CFSTR_FILEDESCRIPTORメソッドに、 、CFSTR_FILECONTENTSを実装しCF_TXTましたCDataObject::Getdata()。Outlook 2007 の場合、(アプリケーションから) ファイルを新しいメッセージのメッセージ本文にドロップすると、CFSTR_FILEDESCRIPTORクリップボード形式のみが呼び出されることに気付きました。Outlook 2003 の場合、(アプリケーションから) ファイルをドロップすると、新しいメッセージのメッセージ本文 CDataObject::GetData()が 2 回呼び出され、CFSTR_FILEDESCRIPTORその後にCFSTR_FILECONTENTSクリップボード形式が続きます。

GetData が 2 回目に呼び出されないため、2 番目のファイルの内容が抽出されます。そのため、ファイルは電子メールに添付されません。以下はサンプルコードです。

何が原因か誰か知っていますか?または、問題を絞り込むために他に何ができるでしょうか。

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 で 1 回、次に CFSTR_FILECONTENTS で 2 回呼び出されていた場合は、最初に失敗したことを意味しますTYMED。その後、CFSTR_FILECONTENTS で再試行しています。

CFSTR_FILEDESCRIPTOR が機能しなかったと思われます。最初のフォーマットが失敗した後、Outlook は 2 番目のフォーマットを試行しなくなりました。

  • またはに応答して、サポートしていない TYMED を指定しましたQueryGetDataEnumFORMATETC?

その場合、Outlook は、たとえば IStream で FILEGROUPDESCRIPTOR を要求している可能性があり、エラーを返すと、単にあきらめているだけです。

于 2012-06-19T13:50:57.670 に答える