充当外部通讯簿提供程序
适用于:Outlook 2013 | Outlook 2016
外部提供程序是通讯簿提供程序,可:
- 为其收件人分配模板标识符。
- 支持 IABLogon::OpenTemplateID 方法。
- 提供用于维护其他通讯簿提供程序(称为主机提供程序)容器中的收件人的代码。 此代码涉及属性对象,通常是 IMAPIProp 接口实现,该实现包装主机提供程序中的属性对象。
充当外部提供商是一个可选角色;并非所有提供程序都需要支持模板标识符及其相关代码。 如果要保持对宿主提供程序使用提供商提供的模板创建的收件人的控制,请将提供程序实现为外部提供商。
提供程序用于其条目标识符的格式也可用于其模板标识符。 模板标识符必须包含提供程序的已注册 MAPIUID ,使 MAPI 能够成功将收件人绑定到相应的提供程序。
当主机提供程序调用 IMAPISupport ::OpenTemplateID 时,MAPI 调用提供程序的 IABLogon::OpenTemplateID 方法。 主机提供程序在调用 IMAPISupport::OpenTemplateID 时传递 lpTemplateID 参数中收件人的模板标识符。 MAPI 通过将模板标识符中的 MAPIUID 与提供程序在登录时注册的 MAPIUID 相匹配来确定模板标识符属于提供程序。 然后,MAPI 通过 IABLogon::OpenTemplateID 方法将主机提供程序的调用转发到提供程序。
主机提供程序还会在 lpMAPIPropData 参数中传递指向其属性对象实现的指针、 lpInterface 参数中的接口标识符(对应于 在 lpMAPIPropData 中传递的接口实现类型)和可选标志(FILL_ENTRY)。 提供程序应在 lppMAPIPropNew 参数中返回指向 lpInterface 中指定的类型的属性对象实现的指针。 返回的指针可以是指向提供程序实现的包装属性对象,也可以是 指向 lpMAPIPropData 中主机提供程序提供的对象。 在以下情况下,提供程序应返回包装的属性对象指针:
- 收件人的显示表包含列表框控件。
- 收件人的电子邮件地址必须从多个显示表控件中的数据进行组合。
- 提供商会发出显示表通知。
FILL_ENTRY标志向提供程序指示主机提供程序要求更新收件人的所有属性。 需要提供商才能满足此请求。
当主机提供程序调用提供程序的 OpenTemplateID 方法时,提供程序可能会:
- 定期更新复制条目的数据。
- 使复制的条目与其原始项保持同步,例如,将通讯簿条目复制到个人通讯簿时。
- 实现主机提供程序无法实现的功能,例如从服务器上的数据动态填充复制条目的详细信息表中的列表框。
- 控制复制的条目或实例化模板中属性之间的交互。 例如,从详细信息表中显示的其他属性计算 PR_EMAIL_ADDRESS 。
前两项是不需要提供程序提供包装属性对象的任务示例,即基于主机提供程序实现的 IMAPIProp 的实现。 提供程序只需根据需要更新属性并返回,将 lppMAPIPropNew 参数设置为指向主机提供程序在 lpMAPIPropData 参数中传递的指针。
第二个任务要求提供程序向主机提供程序返回一个属性对象,该对象包装具有附加功能(例如显示条目的属性表的功能)。 此属性对象将是消息用户或通讯组列表,具体取决于主机提供程序在 lpMAPIPropData 参数中传入的对象类型,并由 lpInterface 参数中的接口标识符指示。 如果 lpMAPIPropData 参数指向消息传递用户,则提供程序的包装属性对象必须是 IMailUser 实现。 如果 lpMAPIPropData 指向通讯组列表,则它必须是 IDistList 实现。
提供程序的包装属性对象截获 IMAPIProp 方法调用,以对主机提供程序的接收方(它正在包装的对象)执行特定于上下文的操作。 MAPI 对包装的属性对象只有一个要求:对 IMAPIProp::OpenProperty 的所有调用应将请求 PR_DETAILS_TABLE (PidTagDetailsTable) 属性传递给主机提供程序。 提供程序的实现可以使用返回的表来截获显示表通知,或根据需要添加其自己的通知。
以下列表包括通常在由外部提供程序实现的包装属性对象中实现的任务:
- IMAPIProp::GetProps 中主机收件人的预处理和后处理属性值。
- 处理详细信息在 IMAPIProp::OpenProperty 中显示表控件,例如按钮和列表框。
- 验证或操作 IMAPIProp::SetProps 中主机收件人的属性值。
- 在 IMAPIProp::SaveChanges 中保存主机收件人之前,计算所需的属性,例如PR_EMAIL_ADDRESS和验证是否已设置所有必要的属性。
实现 IABLogon::OpenTemplateID
检查使用 lpTemplateID 参数传入的模板标识符是否有效,以及是否采用提供程序可识别的格式。 否则,失败并返回MAPI_E_INVALID_ENTRYID。
创建由模板标识符指示的类型的对象,可以是消息用户、通讯组列表或一次性收件人。
在主机提供程序的属性对象(lpMAPIPropData 参数指向的对象)中调用 IUnknown::AddRef 方法。
如果将 ulTemplateFlags 参数设置为 FILL_ENTRY:
如果新对象是消息传递用户或通讯组列表:
检索新对象的所有属性,可能通过调用其 IMAPIProp::GetProps 方法。
调用主机提供程序的 IMAPIProp::SetProps 方法,将所有检索到的属性复制到主机提供程序的属性对象。
如果新对象是一次性收件人,请调用主机提供程序的 IMAPIProp::SetProps 方法以设置以下属性:
PR_ADDRTYPE (PidTagAddressType) 提供程序处理的地址类型。
PR_TEMPLATEID (PidTagTemplateid) lpTemplateID 和 cbTemplateID 参数中的模板标识符。
PR_DISPLAY_TYPE (PidTagDisplayType) 根据需要DT_MAILUSER或DT_DISTLIST。
将 lppMAPIPropNew 参数的内容设置为指向提供程序的新对象或使用 lpMAPIPropData 参数传入的属性对象,具体取决于提供程序是否确定需要包装的对象。
如果发生严重错误(例如网络故障或内存不足),则返回相应的错误值。 此值应传播到具有相应 MAPIERROR 结构的客户端,这是由主机提供程序执行的任务。