打开附件

适用于:Outlook 2013 | Outlook 2016

打开附件涉及显示其数据。 例如,打开文件附件时,将显示该文件的内容。 邮件和文件夹是使用其条目标识符打开的,而附件是使用其附件编号( PR_ATTACH_NUM 属性)打开的。 有关详细信息,请参阅 PR_ATTACH_NUM (PidTagAttachNumber) 。 附件编号可通过邮件的附件表获得。

打开邮件中的所有附件

  1. 调用邮件的 IMessage::GetAttachmentTable 方法来访问其附件表。

  2. 调用 HrQueryAllRows 以检索表中的所有行。

  3. 对于每一行:

    1. 通过在调用邮件的 IMessage::OpenAttach 方法时传递PR_ATTACH_NUM列中表示的附件编号,打开附件。 有关详细信息,请参阅 IMessage::OpenAttachOpenAttach 返回指向 IAttach 实现的指针,该实现提供对附件属性的访问。

    2. 调用附件的 IMAPIProp::GetProps 方法以检索其 PR_ATTACH_METHOD 属性。 有关详细信息,请参阅 IMAPIProp::GetPropsPR_ATTACH_METHOD (PidTagAttachMethod) 。

    3. 如果 PR_ATTACH_METHOD 设置为 ATTACH_BY_REF_ONLY,请调用 IMAPIProp::GetProps 以检索 PR_ATTACH_PATHNAME 属性。 有关详细信息,请参阅 PR_ATTACH_PATHNAME (PidTagAttachPathname) 。

    4. 如果PR_ATTACH_METHOD设置为 ATTACH_BY_VALUE,请调用 IMAPIProp::OpenProperty 以使用 IStream 接口打开 PR_ATTACH_DATA_BIN 属性。 请参阅此过程后面的示例代码。 有关详细信息,请参阅 IMAPIProp::OpenPropertyPR_ATTACH_DATA_BIN (PidTagAttachDataBinary) 。

    5. 如果 PR_ATTACH_METHOD 设置为 ATTACH_OLE并且附件为 OLE 2 对象:

      1. 调用 IMAPIProp::OpenProperty 以使用 IStreamDocfile 接口打开 PR_ATTACH_DATA_OBJ 属性。 尝试使用此接口,因为它是 IStream 的实现,保证使用开销最少的结构化存储。 有关详细信息,请参阅 PR_ATTACH_DATA_OBJ (PidTagAttachDataObject) 。

      2. 如果 OpenProperty 调用失败,请再次调用它以使用 IStreamDocfile 接口检索 PR_ATTACH_DATA_BIN 属性。

      3. 如果第二次 OpenProperty 调用失败,请尝试再次调用 OpenProperty 以检索 PR_ATTACH_DATA_OBJ。 但是,指定 IStorage 接口,而不是指定 IStreamDocfile

  4. 如果 PR_ATTACH_METHOD 设置为 ATTACH_EMBEDDED_MSG,则 PR_ATTACH_DATA_OBJ 的值包含错误并不罕见。 这是因为你和表实现者无法就要返回的对象类型达成一致。 若要检索指向附加邮件的指针,请使用 IMessage::OpenAttach 打开附件。 然后,通过调用其 IMAPIProp::OpenProperty 方法访问附件数据。 有关详细信息,请参阅 IMessage::OpenAttachIMAPIProp::OpenProperty

可以请求在读/写或只读模式下打开附件。 只读是默认模式,许多消息存储提供程序会在此模式下打开所有附件,而不管客户端请求什么。 传递MAPI_BEST_ACCESS标志以请求消息存储提供程序授予其可以达到的最高访问级别,然后检索打开的附件 的 PR_ACCESS_LEVEL 属性,以确定实际授予的访问权限级别。 有关详细信息,请参阅 PR_ACCESS_LEVEL (PidTagAccessLevel) 。

以下示例演示如何在附件的 PR_ATTACH_DATA_BIN 属性中打开数据。 它分配指向两个流的指针:一个用于文件,一个用于附件。 OpenStreamOnFile 函数以只读模式打开文件流。 调用附件的 IMAPIProp::OpenProperty 方法以读/写模式打开附件流。 有关详细信息,请参阅 PR_ATTACH_DATA_BINOpenStreamOnFileIMAPIProp::OpenProperty。 然后,代码从文件流复制到附件流,并释放这两个流。

LPSTREAM pStreamFile, pStreamAtt;
HRESULT hr;
hr = OpenStreamOnFile (MAPIAllocateBuffer, MAPIFreeBuffer,
                       STGM_READ, "myfile.doc", NULL, &pStreamFile);
if (HR_SUCCEEDED(hr))
{
    // Open the destination stream in the attachment object
    hr = pAttach->OpenProperty (PR_ATTACH_DATA_BIN,
                                &IID_IStream,
                                0,
                                MAPI_MODIFY | MAPI_CREATE,
                                (LPUNKNOWN *)&pStreamAtt);
    if (HR_SUCCEEDED(hr))
    {
        STATSTG StatInfo;
        pStreamFile->Stat (&StatInfo, STATFLAG_NONAME);
        hResult = pStreamFile->CopyTo (pStreamAtt, StatInfo.cbSize,
                                       NULL, NULL);
        pStreamAtt->Release();
    }
    pStreamFile->Release();
}