总结:使用自己的导出为 PDF 格式的逻辑创建适用于 Office 2024 Office LTSC 2024 和 Microsoft 365 版本 2408 及更高版本的应用程序的 COM 加载项。 所述的技术需要了解C++和 COM。
适用于:Office 2024、Office LTSC 2024 中的 Excel、OneNote、PowerPoint、Publisher、Visio 和 Word Microsoft 365 版本 2408 及更高版本。
Office (2024) Fixed-Format 导出功能简介
本文介绍第三方软件开发人员如何连接到 Office 2024、Office LTSC 2024 Microsoft 365 版本 2408 及更高版本中提供的固定格式导出功能,以便他们可以添加自己的导出程序。
这些应用程序包括用于Microsoft XML 纸张规范的内置导出程序 (XPS) 和可移植文档格式 (PDF) 。 固定文件格式以既独立于应用程序又独立于平台的分页形式公开文档的内容。
软件开发人员可以通过编写实现 IMsoDocExporter COM 接口的 Office 加载项来添加自己的导出程序。 本文介绍 IMsoDocExporter 及其与托管Microsoft 365 应用程序(例如Word)的交互。
自 Office 2007 版本以来,固定格式导出一直可用,本文包含有关 Office 2024、Office LTSC 2024 Microsoft 365 版本 2408 版本中的新增功能的信息。
重要说明 |
---|
固定格式导出功能在前面的“应用于”部分中列出的所有应用程序中均可用。 但是,下面的讨论使用 Publisher 作为示例应用程序,但说明与不同应用程序更相关的情况除外。 |
初始化 Add-Ins
要使用户访问外接程序功能,外接程序应向应用程序添加新菜单项或新的工具栏按钮。 当用户选择此菜单项或按钮时,外接程序应使用 Microsoft Office 对象模型来获取指向活动文档的指针。 然后,它应使用通过调用 QueryInterface 方法支持 IMsoDocExporter 接口的 IUnknown 接口指针调用活动文档的 ExportAsFixedFormat 方法。 接口指针的对象模型参数是具有VT_UNKNOWN类型的 VARIANT。
注意 |
---|
对于 OneNote,外接程序使用字符串参数调用 Publish 方法,该字符串参数是外接程序实现 的 IMsoDocExporter 接口的类 ID。 然后,OneNote 使用类 ID 调用 CoCreateInstance ,以从外接程序的类工厂获取 IUnknown 接口指针。 |
发布服务器具有指向 IMsoDocExporter 接口的指针后,它会通过 IMsoDocExporter 公开的方法调用外接程序。 通过这些回调,Word向加载项提供文档内容和有关文档的其他信息。
codeproject.com 文章使用 VC++/ATL 生成 Office2K COM 外接程序,这是有关为 Microsoft Office 应用程序生成 COM 外接程序的极佳信息来源。
IMsoDocExporter
IMsoDocExporter 接口公开以下方法。
表 1. 由 IMsoDocExporter 接口公开的方法
方法 |
说明 |
---|---|
HrCreateDoc |
在固定格式导出过程开始时调用。 |
HrAddPageFromEmf |
调用 以向加载项传递增强型图元文件 (EMF) ,该图元文件表示要导出的内容的呈现视图。 |
HrAddDocumentMetadataString |
调用 以指定文档的字符串格式元数据。 |
HrAddDocumentMetadataDate |
调用 以指定文档的日期格式元数据。 |
HrSetDefaultLcid |
调用 以指定要导出内容的默认区域设置 ID (LCID) 。 |
HrAddOutlineNode |
调用 以指定用户可导航的文档大纲信息。 |
HrGetPageBreaks |
调用 以从加载项获取分页信息。 |
HrSetPageHeightForPagination |
调用 以指定页面高度,使外接程序能够对文档进行分页。 |
HrFinalize |
在固定格式导出过程结束时调用。 允许加载项执行任何最终处理。 |
HrBeginStructNode |
调用 后,为跨多个页面的文档结构节点传递起始结构。 |
HrEndStructNode |
调用 以传递跨多个页面的文档结构节点的结束结构加载项。 |
EnableCancel |
调用 以向加载项传递指向 IDocExCancel 接口的指针。 |
GetOutputOption |
调用 以检索固定格式的输出选项。 |
SetOutputOption |
由 Office 调用以设置固定格式的输出选项。 |
SetDocExporterSite |
调用 可为加载项提供指向 IMsoDocExporterSite 接口的指针,以便获得扩展的颜色支持。 |
此外, IMsoDocExporter 还公开从 IUnknown 接口继承的以下方法。
表 2. 从 IUnknown 接口继承的方法
方法 |
说明 |
---|---|
AddRef |
使引用计数递增。 |
QueryInterface |
返回指向受支持接口的指针。 外接程序的 QueryInterface 实现应支持从 IID_IMsoPdfWriter 返回 IMsoDocExporter 接口指针。 |
发布 |
使引用计数递减。 |
有关实现 IUnknown 接口方法的信息,请参阅 IUnknown (COM) 。
呼叫流
下图显示了发布服务器调用 IMsoDocExporter 中公开的方法的顺序。 并非所有方法都由每个Microsoft Office 应用程序使用,并且并非所有方法都用于导出的每个文档。
图 1. 从 IMsoDocExporter 接口调用方法
以下部分进一步介绍 IMsoDocExporter 接口公开的方法。 这些方法按发布服务器调用它们的顺序进行大致描述。
GetOutputOption 和 SetOutputOption
Publisher 调用 GetOutputOption 和 SetOutputOption 方法来检索和设置固定格式导出过程的输出选项。
void GetOutputOption(
MSODOCEXOPTION docexoption,
DWORD* pdwVal
);
void SetOutputOption(
MSODOCEXOPTION docexoption,
DWORD dwVal
);
docexoption 参数指定输出选项, (p) dwVal 参数指定选项的值。
虽然 Office 中的内置导出程序使用 GetOutputOption 和 SetOutputOption,但加载项可以实现其自己的获取和设置选项的方法,并拥有选项的用户体验。
Microsoft Office 调用 GetOutputOption 仅限 msodocexOptionTargetDPIColor for Fixed-Format Add-Ins
对于在 Office 中实现固定格式导出,Publisher 调用 GetOutputOption 方法来检索输出选项,以便在“ 发布为 PDF 或 XPS ”对话框中向用户显示。 对于第三方软件开发人员开发的加载项,发布者仅使用 msodocexOptionTargetDPIColor 值调用 GetOutputOption 。 这是外接程序需要支持的唯一值。 如果使用此值调用加载项的 GetOutputOption 实现,则它应返回目标每英寸点数 (DPI) 三维效果光栅化。
适用于 Fixed-Format 加载项的 Microsoft Office 调用 SetOutputOption
对于在 Office 中实现固定格式导出和加载项实现,发布服务器会在固定格式导出过程开始时调用 SetOutputOption 。 在 Office 中的实现中,传入的参数值指定固定格式的输出选项。 但是,如果加载项实现其自己的选项集,则外接程序可以忽略 Publisher 传递给它的选项。
EnableCancel
Publisher 调用 EnableCancel 方法,以向加载项传递指向 IMsoDocExCancel 接口的指针。 加载项可以使用此界面来查询用户是否选择取消长时间的文档导出作。
void EnableCancel(
IMsoDocExCancel* pdec
);
HrBeginStructNode
Publisher 调用 HrBeginStructNode 方法,为包含文档中多个完整页面的内容指定文档结构节点的开头。 文档结构节点用于完全驻留在页面中的文档元素 (例如,段落) 由 Publisher 嵌入到增强型图元文件中, (EMF) 使用 DocExComment_BeginStructNode 和 DocExComment_EndStructNode 结构本身。 有关文档结构节点的详细信息,请参阅本文中的 HrAddPageFromEmf 和 DocExComment_BeginStructNode部分。
HRESULT HrBeginStructNode(
int idNodeParent,
int iSortOrder,
const MSODOCEXSTRUCTNODE* pnode,
BOOL fNoEndNode
);
idNodeParent 参数指定作为要传递给外接程序的节点的父节点的 ID。 如果此参数为 0,则节点位于文档结构树的根目录下。 多个同级节点可能位于根目录下。 如果此参数为 -1,则节点位于当前打开的节点下,即 HrBeginStructNode 指定的最后一个节点下,该节点尚未通过对 HrEndStructNode 的调用关闭。
iSortOrder 参数指定结构节点在其同级之间的排序顺序。 不能有两个节点具有相同的排序顺序。 但是,构成排序顺序的整数集不必是连续的。 值为 -1 表示同级排序顺序与节点在 EMF 注释中的显示顺序相同。
pnode 参数指向 MSODOCEXSTRUCTNODE 结构,该结构具有以下声明:
typedef struct _MsoDocexStructNode
{
int idNode;
MSODOCEXSTRUCTTYPE nodetype;
WCHAR* pwchAltText;
union
{
int iHeadingLevel;
ULONG idPara;
ULONG idDropCap;
int iPage;
WCHAR* pwchActualText;
MSODOCEXLINEBREAKTYPE bt;
int iListLevel;
MSODOCEXLISTTYPE listType;
ULONG idAtn;
long cpLim;
int shapeProperty;
MsoDocexTableAttr tableAttr;
long cpNoteRef;
WCHAR* idTableHeader;
long cpXchAtnMainDod;
int iTargetParentId;
WCHAR* wzMathMlText;
MsoDocexListAttr* pListAttr;
};
} MSODOCEXSTRUCTNODE;
idNode 成员指定在对 HrBeginStructNode 的调用中传递的节点的 ID。 此成员的值可能不为 0。 值为 -1 表示子节点不使用 idNodeParent 参数将此节点指定为其父节点。 相反,此节点只能通过将子节点括在 EMF 中来成为父节点。 多个节点的 ID 可以为 -1。 如果 ID 不是 -1,则该值在文档中是唯一的。
MSODOCEXSTRUCTNODE 末尾的嵌入联合以不同的方式解释,具体取决于节点的类型:
- iHeadingLevel 是 msodocexStructTypeHeading 的标题级别。
- idPara 是 P、TOCI 或 ListBody 的段落 ID。
- idDropCap 是 msodocexStructTypeDropCap 的 ID。
- iPage 是 msodocexStructTypePage 的页码。
- bt 是 msodocexStructTypeTextLine 的换行类型。
- iListLevel 是 msodocexStructTypeList 或 msodocexStructTypeListItem 的列表级别。
- listType 是 msodocexStructTypeListItem 的列表类型。
- idAtn 是 msodocexStructTypeAnnotationBegin 或 msodocexStructTypeAnnotationEnd 的 ID。
- cpLim 用于确定 msodocexStructTypeTable、msodocexStructTypeTOC 或 msodocexStructTypeListBody 表中表的嵌套顺序。
- shapeProperty 适用于 msodocexStructTypeFigure,其中的内容是形状、文本框或表格单元格,并包含 MSODOCEXSHAPEPROPERTY 枚举中的位字段。
- tableAttr 是 msodocexStructTypeTH 或 msodocexStructTypeTD 的表单元格属性。
- cpNoteRef 用于将 msodocexStructTypeIntLinkNoteRef 与 msodocexStructTypeFootnote/msodocexStructTypeEndnote 链接。 本节稍后将对此进行更详细的介绍。
- idTableHeader 是 msodocexStructTypeTH 或 msodocexStructTypeTD 的唯一 ID。
- cpXchAtnMainDod 用于链接 msodocexStructTypeCommentAnchor 与 msodocexStructTypeAnnot。 本节稍后将对此进行更详细的介绍。
- iTargetParentId 是将 msodocexStructTypeDiagram 重新父化的节点的 ID。
- wzMathMlText 是 msodocexStructTypeEquation 的 MathML 字符串。
- pListAttr 是 msodocexStructTypeList 的列表属性。
注意:cpNoteRef、cpXchAtnMainDod、wzMathMlText 和 pListAttr 在Word时可用。Document.ExportAsFixedFormat3 使用 ImproveExportTagging = true 调用。 所需的最低版本为 Microsoft 365 Beta 频道 16.0.18720.20000。
表 3. MSODOCEXLINEBREAKTYPE 的枚举值
值 |
说明 |
---|---|
msodocexLineBreakTypeNormal |
普通换行符。 |
msodocexLineBreakTypeManual |
手动换行。 |
msodocexLineBreakTypeEOP |
段落结尾。 |
表 4. MSODOCEXLISTTYPE 的枚举值
值 |
说明 |
---|---|
msodocexListTypeNone |
无项目符号或编号。 |
msodocexListTypeBulletDisc |
圆盘形子弹。 |
msodocexListTypeBulletCircle |
圆形项目符号。 |
msodocexListTypeBulletSquare |
方形项目符号。 |
msodocexListTypeBulletDecimal |
十进制编号。 |
msodocexListTypeUpperRoman |
大写罗马数字编号。 |
msodocexListTypeLowerRoman |
小写罗马数字编号。 |
msodocexListTypeUpperAlpha |
大写字母编号。 |
msodocexListTypeLowerAlpha |
小写字母编号。 |
表 5. MSODOCEXSHAPEPROPERTY 位字段的枚举值
值 |
数值 |
说明 |
---|---|---|
msodocexShape |
0x00000001 |
对象是形状或文本框。 |
msodocexShapeText |
0x00000002 |
对象具有非空格文本。 |
msodocexShapePath |
0x00000004 |
对象具有填充和/或轮廓。 |
msodocexShapeAltText |
0x00000008 |
对象具有替换文字。 |
msodocexShapeEquation |
0x00000010 |
对象具有包含公式的文本。 |
msodocexShapeTabelCell |
0x00000020 |
对象是表中的单元格。 |
MsoDocexTableAttr
MsoDocexTableAttr 结构适合 32 位,包括表单元格的行和列范围以及标头范围信息。
struct MsoDocexTableAttr
{
static constexpr unsigned int MaxSpanBits = sizeof(unsigned int) * 8 / 2 - 1;
static constexpr unsigned int MaxSpanValue = (1u << MaxSpanBits) - 1;
unsigned int rowSpan : MaxSpanBits;
unsigned int fRowScope : 1;
unsigned int colSpan : MaxSpanBits;
unsigned int fColScope : 1;
};
MsoDocexTableAttr 结构的成员如下所示:
MaxSpanBits 指定可用于 rowSpan 和 colSpan 值的位数,即 15 位。
MaxSpanValue 指定可以为 rowSpan 和 colSpan 指定的最大值。
rowSpan 指定表单元格所跨越的行数。
fRowScope 指定标头是行/两者还是列。
colSpan 指定表单元格跨越的列数。
fColScope 指定标题是 Column/Both 还是 Row。
MsoDocexListAttr
MsoDocexListAttr 结构包含列表的信息。
struct MsoDocexListAttr
{
int iListLevel;
long cpLim;
};
MsoDocexListAttr 结构的成员如下所示:
iListLevel 指定列表的嵌套顺序。
cpLim 指定文档中列表结束的位置。
后期处理提示
在某些情况下,需要对节点进行后处理才能获得所需的结果。
脚注/尾注后期处理
在导出期间,脚注/尾注链接将标记为 msodocexStructTypeIntLinkNoteRef。 脚注/尾注正文将分别标记为 msodocexStructTypeFootnote 和 msodocexStructTypeEndnote,它们将始终是 msodocexStructTypeDocument 节点下的顶级节点。 msodocexStructTypeIntLinkNoteRef 节点和相应的 msodocexStructTypeFootnote/msodocexStructTypeEndnote 节点将具有相同的 cpNoteRef 值。 这可用于在相应的链接节点下移动脚注/尾注节点,以保持逻辑读取顺序。
批注后期处理
在导出期间,每个注释定位点都将标记为 msodocexStructTypeCommentAnchor。 注释正文将标记为 msodocexStructTypeAnnot,并且它们始终是 msodocexStructTypeDocument 节点下的顶级节点。 msodocexStructTypeCommentAnchor 节点和相应的 msodocexStructTypeAnnot 节点将具有相同的 cpXchAtnMainDod 值。 这可用于将批注节点移动到其相应的注释定位点节点下,以维护逻辑读取顺序。
布局表后期处理
在导出期间,如果检测到表是布局表,我们会将其标记为 msodocexStructTypeTable,但会将节点的 cpLim 设置为 -2 (常量值,以指示这是布局表) 。 然后,此值可用于确定是否应将表节点重新标记为段落节点。
跨页面后期处理的节点 (段落、列表、表)
对于段落,可以检查两个 para 节点的 idPara 值,以确定它们是否跨页面表示同一段落。 对于表,可以检查 cpLim 值,以查看它们是否相同。
对于列表,我们向 MsoDocexStructNode、MsoDocexListAttr 添加了一个新类,其中包含列表的 cpLim。 这可用于检查两个列表节点是否具有相同的 cpLim,这意味着它们都表示文档中的相同列表。
对于表结构节点,联合被解释为通过使用 cpLim(可用于确定表内表的嵌套顺序)相对于其他表的表结束排序。
在 DocExComment_BeginStructNode的上下文中,加载项可以忽略此联合的 pwchActualText 成员。
pwchAltText 成员为结构节点指定备用文本。
HrBeginStructNode 的 fNoEndNode 参数指定 Publisher 是否调用 HrEndStructNode 方法来标记结构节点的结束。 如果 fNoEndNode 为 false,则发布服务器调用 HrEndStructNode 以关闭由节点绑定的内容。 如果此参数具有 true 值,则节点不绑定任何内容。
fNoEndNode 参数会影响后续节点的父 ID 值的解释。 如果 fNoEndNode 为 false,则在此对 HrBeginStructNode 的调用和对 HrEndStructNode 的后续调用之间插入的节点(其父 ID 为 -1)是此节点的子级。 但是,如果 fNoEndNode为 true,则在此调用 HrBeginStructNode 之后插入的节点(父 ID 为 -1)不是此节点的子级,而是 fNoEndNode 等于 false 的下一个最近指定的节点的子级。
文档结构节点可以嵌套到任意深度。
HrBeginStructNode 指定的节点和DocExComment_BeginStructNode指定的节点共享相同的 ID 空间,并存在于同一文档结构树中。 HrBeginStructNode 和 DocExComment_BeginStructNode 是向此树添加节点的两种替代方法。 例如,如果最近打开的节点由 HrBeginStructNode 打开,并且遇到的下一个节点来自 idNodeParent 等于 -1的DocExComment_BeginStructNode EMFcommentrecord,则意味着 HrBeginStructNode 中的节点是DocExComment_BeginStructNode记录中的节点的父节点。
HrEndStructNode
Publisher 调用 HrEndStructNode 方法,为包含文档中多个页面的内容指定文档结构节点的末尾。 由 HrEndStructNode 结束的结构节点以前是通过调用 HrBeginStructNode 方法启动的。 有关详细信息,请参阅本文中的 HrBeginStructNode。
HRESULT HrEndStructNode();
HrCreateDoc
Publisher 调用 HrCreateDoc 方法以指定创建新的空固定格式文档。
HRESULT HrCreateDoc(
const WCHAR* wzDocExFile
);
Publisher 在固定格式导出过程开始时调用 HrCreateDoc 方法,以指定创建空固定格式文档。 wzDocExFile 参数指定要写入固定格式文档的输出文件的名称。
对于外接程序实现,Publisher 使用外接程序在调用 Microsoft Office 对象模型中 ExportToFixedFormat 方法时提供的文件名调用 HrCreateDoc。 但是,由于外接程序通常提供配置 UI 以允许用户指定输出文件名,因此加载项可能会在导出过程中忽略此文件名。
对于需要外接程序对文档进行分页的Microsoft Office 应用程序, 将调用 HrCreateDoc 两次,在分页调用序列的开头调用一次,在外接程序对文档进行分页后再调用一次。 有关详细信息,请参阅 HrSetPageHeightForPagination 方法和 HrGetPageBreaks 方法的说明。
HrSetDefaultLcid
Publisher 调用 HrSetDefaultLcid 方法以指定要导出内容的默认区域设置 ID (LCID) 。
HRESULT HrSetDefaultLcid(
DWORD lcid
);
有关有效 LCID 的列表,请参阅由 Microsoft 分配的区域设置 ID (LCID) 值列表。
HrAddPageFromEmf
Publisher 调用 HrAddPageFromEmf 方法,将外接程序的句柄传递给表示要导出的文档中内容的内存中 EMF。
HRESULT HrAddPageFromEmf(
HENHMETAFILE hemf
);
Microsoft Office 传递给加载项的 EMF 是加载项导出为固定格式文件的内容的主要源。 Microsoft Office 针对应用程序源文档中的每一页内容调用 HrAddPageFromEmf 一次。
EMF 注释传达语义信息
EMF 是一系列绘制命令, (GDI 和 GDI+ 命令) 指定如何呈现文档的视觉元素。 EMF 不包含除这些命令之外的任何信息, (例如,“在此处绘制图像”或“在那里绘制线条”) 。 具体而言,传统的 EMF 不支持文档的语义方面,例如超链接、区域设置信息和辅助功能信息。 为了保留导出文档中的语义信息,Publisher 在 EMF 中注入了特殊记录。 这些记录包含语义信息。
表示语义信息的记录实现为特殊格式的 EMF 注释。 EMF 格式允许注释记录类型被图形设备接口 (GDI) 的呈现引擎忽略,但可以包含任意信息。
例如,请考虑包含备用文本的文档。 (文档阅读器使用备用文本来描述有视力障碍的用户的图像。) Publisher 在呈现图像前后注入 EMF 注释,这些 EMF 注释指定图像的备用文本。 加载项解释注释并将信息写入固定格式导出文件。
下表显示了 Microsoft Office 固定格式导出功能支持的语义记录类型。 这些类型由 MSODOCEXSTRUCTTYPE 枚举进行枚举。 每个类型对应于描述记录格式的结构类型。
表 6. 固定格式导出支持的语义记录类型
注释值 |
结构类型 |
---|---|
msodocexcommentExternalHyperlink |
DocExComment_ExternalHyperlink |
msodocexcommentExternalHyperlinkRctfv |
DocExComment_ExternalHyperlink |
msodocexcommentInternalHyperlink |
DocExComment_InternalHyperlink |
msodocexcommentInternalHyperlinkRctfv |
DocExComment_InternalHyperlink |
msodocexcommentColorInfo |
DocExComment_ColorInfo |
msodocexcommentColorMapEnable |
DocExComment_ColorEnable |
msodocexcommentBeginTextRun |
DocExComment_BeginTextRun |
msodocexcommentBeginTextRunRTL |
DocExComment_BeginTextRun |
msodocexcommentEndTextRun |
DocExComment_EndTextRun |
msodocexcommentBeginStructNode |
DocExComment_BeginStructNode |
msodocexcommentEndStructNode |
DocExComment_EndStructNode |
msodocexcommentUnicodeForNextTextOut |
DocExComment_UnicodeForNextTextOut |
msodocexcommentUnicodeForNextTextOutRTL |
DocExComment_UnicodeForNextTextOut |
msodocexcommentEPSColor |
DocExComment_EPSColor |
msodocexcommentEPSCMYKJPEG |
DocExComment_EPSColorCMYKJPEG |
msodocexcommentEPSSpotImage |
DocExComment_EPSColorSpotImage |
msodocexcommentEPSStart |
DocExComment_EPSStart |
msodocexcommentPageName |
DocExComment_PageName |
msodocexcommentTransparent |
DocExComment_Transparent |
DocExComment_ExternalHyperlink (Rctfv)
DocExComment_ExternalHyperlink (Rctfv) 结构描述链接到文档外部的超链接,例如链接到 Internet 上的网站。
struct DocExComment_ExternalHyperlink
{
DWORD ident {};
DWORD iComment {};
union
{
RECT rcdvRegion;
struct
{
float xLeft;
float yTop;
float dxWidth;
float dyHeight;
} rctfvRegion;
};
WCHAR wzLink[MAX_PATH];
};
DocExComment_ExternalHyperlink (Rctfv) 结构的成员如下:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentExternalHyperlink 或 msodocexcommentExternalHyperlinkRctfv。
rcdvRegion 和 rctfvRegion 一个联合,指定作为超链接源位置的页面区域。 该区域可以表示为使用设备像素作为度量单位 (rcdvRegion) 的 RECT 类型,也可以表示为包含浮点坐标 (rctfvRegion) 的结构,在这种情况下,度量单位为磅。
如果 iComment 成员等于 msodocexcommentExternalHyperlink,则外接程序应使用 rcdvRegion。 在这种情况下,外接程序需要将当前 EMF 转换矩阵应用到 rcdvRegion ,以将其转换为页面空间。
如果 iComment 成员等于 msodocexcommentExternalHyperlinkRctfv,则外接程序应使用 rctfvRegion。 在这种情况下, rctfvRegion 已在页面空间中,因此不需要转换。
wzLink[MAX_PATH] 指定此超链接的目标 URL。
DocExComment_InternalHyperlink (Rctfv)
DocExComment_InternalHyperlink (Rctfv) 结构描述链接到文档中某个位置的超链接。 请注意,尽管 Publisher 为文档的每一页传递单独的 EMF,但 DocExComment_InternalHyperlink (Rctfv) 指定的超链接目标可能位于与源位置不同的页面上。
struct DocExComment_InternalHyperlink
{
DWORD ident {};
DWORD iComment {};
union
{
RECT rcdvRegion;
struct
{
float xLeft;
float yTop;
float dxWidth;
float dyHeight;
} rctfvRegion;
};
DWORD iTargetPage {};
float xtfvTarget {};
float ytfvTarget {};
float dytfTargetPage {};
};
DocExComment_InternalHyperlink (Rctfv) 结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentInternalHyperlink 或 msodocexcommentInternalHyperlinkRctfv。
rcdvRegion 和 rctfvRegion 与 DocExComment_ExternalHyperlink 结构一样,此成员是一个联合,它指定作为超链接源位置的页面区域。 该区域可以表示为使用设备像素作为度量单位 (rcdvRegion) 的 RECT 类型,也可以表示为包含浮点坐标 (rctfvRegion) 的结构,在这种情况下,度量单位为磅。
如果 iComment 成员等于 msodocexcommentInternalHyperlink,则外接程序应使用 rcdvRegion。 在这种情况下,外接程序需要将当前 EMF 转换矩阵应用到 rcdvRegion ,以将其转换为页面空间。
如果 iComment 成员等于 msodocexcommentInternalHyperlinkRctfv,则外接程序应使用 rctfvRegion。 在这种情况下, rctfvRegion 已在页面空间中,因此不需要转换。
iTargetPage 指定文档中目标页的页码。
xtfvTarget 指定目标页上目标位置的 x 坐标。 此值的度量单位为磅。
ytfvTarget 指定目标页上目标位置的 y 坐标。 此值的度量单位为磅。
dytfTargetPage 目标页的高度(以磅为单位)。 ytfvTarget 成员指定的偏移量相对于页面的左上角。 但是,某些固定格式类型使用相对于页面左下角的坐标系。 对于这些类型的文档,需要页面高度才能转换偏移量。
DocExComment_ColorInfo
DocExComment_ColorInfo结构指定 EMF 的颜色状态信息。 有关此结构的详细信息,请参阅扩展颜色支持部分。
struct DocExComment_ColorInfo
{
DWORD ident {};
DWORD iComment {};
COLORREF clr { 0 };
BOOL fForeColor {};
};
DocExComment_ColorInfo 结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentColorInfo。
clr 指定表示 EMF 中当前颜色状态的颜色 ID。
fForeColor 指定 clr 成员中的颜色 ID 是代表前景色还是背景色。 如果此成员的值为 true,则颜色 ID 表示前景色。 如果此成员的值为 false,则颜色 ID 表示背景色。
DocExComment_ColorEnable
DocExComment_ColorEnable结构指定是否为 EMF 中的后续内容启用颜色映射。 有关此结构的详细信息,请参阅扩展颜色支持部分。
struct DocExComment_ColorEnable
{
DWORD ident {};
DWORD iComment {};
BOOL fEnable {};
};
DocExComment_ColorEnable结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentColorMapEnable。
fEnable 指定是否为后续内容启用颜色映射。 值为 true 表示已启用颜色映射。 值为 false 表示禁用颜色映射。
DocExComment_BeginStructNode
DocExComment_BeginStructNode结构标记文档结构节点的开始。 结构节点具有以下两种可能用途之一:
结构节点可以标识它们包含的内容类型,并指定该内容与文档中其他内容之间的分层关系。
结构节点可以为文档中的元素指定备用文本。
如果 fContentNode 成员具有 true 值,则 文档中 稍后将DocExComment_BeginStructNode后跟 DocExComment_EndStructNode。 DocExComment_EndStructNode标记由DocExComment_BeginStructNode中的信息包装的内容的末尾。
文档中结构节点的集合形成树;每个节点都有一个父节点,并且可能还有同级节点。 idNodeParent 和 iSortOrder 成员描述此树的结构。 请注意,子节点可能在 EMF 中父节点的 DocExComment_BeginStructNode 和 DocExComment_EndStructNode 结构之间出现,也可能不会出现。
struct DocExComment_BeginStructNode
{
DWORD ident {};
DWORD iComment {};
int idNodeParent {};
int iSortOrder {};
MSODOCEXSTRUCTNODE desn;
BOOL fContentNode {};
int cwchAltText {};
};
DocExComment_BeginStructNode结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentBeginStructNode。
idNodeParent 指定父节点的 ID。 值 0 指定根节点。 值 -1 指定当前打开的结构节点,即 封闭 结构节点。
iSortOrder 指定结构节点在其同级节点中的排序顺序。 排序顺序使外接程序能够正确对导出文档中的内容进行排序。
不能有两个节点具有相同的排序顺序。 但是,构成排序顺序的整数集不需要是连续的。
值为 -1 表示同级顺序与节点在 EMF 注释中的显示顺序相同。 请注意,内容在 EMF 中的显示顺序不一定是文档用户使用内容的顺序。
desn 指定在文档前面定义的 MSODOCEXSTRUCTTYPE 结构。
idNode 成员指定节点的 ID。 此成员的值可能不为 0。 值为 -1 表示子节点不使用 idNodeParent 成员将此节点指定为其父节点。 相反,此节点只能通过将子节点括在 EMF 中来成为父节点。 多个节点的 ID 可以为 -1。 如果 ID 不是 -1,则该值在文档中是唯一的。
节点类型指定结构节点的类型。 此成员等于 MSODOCEXSTRUCTTYPE 枚举类型中的值之一。 下表列出了文档结构节点类型的示例。
表 7. 文档结构节点类型
类型值 |
说明 |
---|---|
msodocexStructTypePara |
文章中的文本块。 其父节点必须是项目。 |
msodocexStructTypeFigure |
图形元素 (例如,具有文本表示形式) 形状的图像或集合。 文本表示形式是用于阅读或搜索文档的备用文本。 |
msodocexStructTypeArticle |
一组节点,构成应作为连续内容块进行读取或搜索的单个文本流。 有些文档只有一篇文章,而另一些文档则包含多个文章。 |
msodocexStructTypeHeading |
文本中的标题。 |
msodocexStructTypeTable |
形成表格的文本块。 |
msodocexStructTypeTR |
形成表格单行的文本块。 |
msodocexStructTypeTD |
在表格行中形成单个单元格的文本块。 |
msodocexStructTypeTH |
在表格行中形成单个标题单元格的文本块。 |
msodocexStructTypeList |
形成列表的文本块。 |
msodocexStructTypeListItem |
形成列表项的文本块。 |
msodocexStructTypeListBody |
构成列表项正文的文本块。 |
msodocexStructTypeDocument |
文档。 |
msodocexStructTypePage |
文档中的一页。 |
msodocexStructTypeTOC |
目录。 |
msodocexStructTypeTOCI |
目录中的项。 |
msodocexStructTypeExtLink |
指向外部资源的链接。 |
msodocexStructTypeIntLink |
指向内部资源的链接。 |
msodocexStructTypeFootnote |
脚注。 |
msodocexStructTypeEndnote |
尾注。 |
msodocexStructTypeTextbox |
文本框。 |
msodocexStructTypeHeader |
形成标题的文本块。 |
msodocexStructTypeFooter |
页脚。 |
msodocexStructInlineShape |
内联形状。 |
msodocexStructAnnotation |
批注。 |
msodocexStructTypeSpanBlock |
文本块。 |
msodocexStructTypeWorkbook |
工作簿。 |
msodocexStructTypeWorksheet |
工作表。 |
msodocexStructTypeMacrosheet |
宏表。 |
msodocexStructTypeChartsheet |
图表表。 |
msodocexStructTypeDialogsheet |
对话框表。 |
msodocexStructTypeSlide |
幻灯片。 |
msodocexStructTypeChart |
图表。 |
msodocexStructTypeDiagram |
SmartArt 图表。 |
msodocexStructTypeBulletText |
Buller 文本。 |
msodocexStructTypeTextLine |
文本行。 |
msodocexStructTypeDropCap |
下沉帽。 |
msodocexStructTypeSection |
一节。 |
msodocexStructTypeAnnotationBegin |
批注的开头。 |
msodocexStructTypeAnnotationEnd |
批注的末尾。 |
msodocexStructTypeParaRTLAttr |
文章中具有从右到左布局的文本块。 |
msodocexStructTypeTableRTLAttr |
形成具有从右到左布局的表格的文本块。 |
msodocexStructTypeHeadingRTLAttr |
文本中具有从右向左布局的标题。 |
msodocexStructTypeListItemRTLAttr |
形成具有从右到左布局的列表项的文本块。 |
msodocexStructTypeParaUnannotatableAttr |
项目内不可更改的文本块。 |
msodocexStructTypeTHead |
表中的标题行区域。 |
msodocexStructTypeTBody |
表格中的正文区域,即 THead 和 TFoot 之间的部分。 |
msodocexStructTypeLabel |
标签。 |
msodocexStructTypeEquation |
公式。 |
msodocexStructTypeIntLinkNoteRef |
脚注或尾注引用标记链接。 |
msodocexStructTypeTFoot |
表中的页脚行区域。 |
msodocexStructTypeTitle |
文本中的标题。 |
msodocexStructTypeBlockQuote |
段落引用或密集引用。 |
msodocexStructTypeCommentAnchor |
链接到批注的一些文本。 |
msodocexStructTypeAnnot |
单个注释的内容。 |
msodocexStructTypeQuote |
内联引号。 |
msodocexStructTypeCaption |
公式/图/表的描述文字。 |
注意:msodocexStructTypeTitle、msodocexStructTypeBlockQuote、msodocexStructTypeCommentAnchor、msodocexStructTypeAnnot、msodocexStructTypeQuote 和 msodocexStructTypeCaption 在Word时可用。Document.ExportAsFixedFormat3 使用 ImproveExportTagging = true 调用。 所需的最低版本为 Microsoft 365 Beta 频道 16.0.18720.20000。
fContentNode 指定 DocExComment_EndStructNode 结构是否标记此结构节点的末尾。 如果 fContentNode为 true, 则DocExComment_EndStructNode 结构将关闭节点绑定的内容。 如果此 fContentNode 具有 false 值,则节点不绑定任何内容。
fContentNode 成员影响后续节点的父 ID 值的解释。 如果 fContentNode为 true,则在此 DocExComment_BeginStructNode 与后续 DocExComment_EndStructNode之间插入且父 ID 为 -1 的节点是此节点的子级。 但是,如果 fContentNode为 true,则在此 DocExComment_BeginStructNode之后插入且父 ID 为 -1 的节点不是此节点的子级。 它们是 fContentNode 等于 false 的下一个最近指定的节点的子级。
可以将文档结构节点嵌套到任意深度。
cwchAltText 指定结构后面的备用文本块中的 Unicode 字符数。 此 Unicode 字符串指定节点的备用文本 (例如图像) 的备用文本。
DocExComment_EndStructNode
DocExComment_EndStructNode结构标记由DocExComment_BeginStructNode中的信息修饰的内容的末尾。
struct DocExComment_EndStructNode
{
DWORD ident {};
DWORD iComment {};
};
DocExComment_EndStructNode 结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentEndStructNode。
DocExComment_BeginTextRun
DocExComment_BeginTextRun 结构标识文档中文本序列的语言,并提供文本的 Unicode 码位。
尽管某些文本呈现 EMF 记录使用 Unicode 作为文本表示形式,但其他记录使用在屏幕上绘制的字形,而不是原始源文本。 字形是字体中给定形状的索引,可能不同于字体。
在某些情况下,多个 Unicode 码位合并为单个标志符号,或者单个 Unicode 码位被分解为多个标志符号。 由于从代码点到字形的映射依赖于上下文,因此用户无法在仅包含字形的文档中进行文本搜索或复制/粘贴。 因此,Publisher 有时提供 Unicode 文本和字形。
struct DocExComment_BeginTextRun
{
DWORD ident {};
DWORD iComment {};
DWORD lcid {};
int cGlyphIndex {};
int cwchActualText {};
};
DocExComment_BeginTextRun结构的成员如下所示:
Ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentBeginTextRun。
lcid 指定文本序列的 LCID。
cGlyphIndex 指定此结构后面的数组的大小。 此数组实现一个字形索引表,该表将实际文本中的 Unicode 码位映射到 EMF 中的相应字形。 数组的每个元素对应于文本中的一个代码点。 该元素的值指定用于在 EMF 中呈现该代码点的第一个字形。 两个或多个相邻码位在数组中可能具有相同的值,这意味着它们都解析为同一字形。 该值也可以为 0,这意味着此码位不会映射到任何字形。
cwchActualText 指定字形索引表后面的 Unicode 码位序列的大小。 这是文档使用者可用于搜索、复制/粘贴和辅助功能的文本。 此成员的值可以为 0,这意味着不提供任何 Unicode 文本。
DocExComment_EndTextRun
DocExComment_EndTextRun 结构标记文本序列的结尾,其开头由DocExComment_BeginTextRun结构标记。
struct DocExComment_EndTextRun
{
DWORD ident {};
DWORD iComment {};
};
DocExComment_EndTextRun结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentEndTextRun。
DocExComment_UnicodeForNextTextOut
DocExComment_UnicodeForNextTextOut结构与DocExComment_BeginTextRun和DocExComment_EndTextRun结构类似。 但是, DocExComment_UnicodeForNextTextOut 仅为以下 EMF TextOut 记录指定 Unicode 码位,而不是指定由开始和结束结构绑定的 EMF 内容块。
struct DocExComment_UnicodeForNextTextOut
{
DWORD ident {};
DWORD iComment {};
int cGlyphIndex {};
int cwchActualText {};
};
DocExComment_UnicodeForNextTextOut结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentUnicodeForNextTextOut。
cGlyphIndex 指定此结构后面的数组的大小。 此数组实现一个字形索引表,该表将实际文本中的 Unicode 码位映射到 EMF 中的相应字形。 数组的每个元素对应于文本中的一个代码点。 该元素的值指定用于在 EMF 中呈现该代码点的第一个字形。 两个或多个相邻码位在数组中可能具有相同的值,这意味着它们都解析为同一字形。
cwchActualText 指定字形索引表后面的 Unicode 码位序列的大小。 这是文档使用者可用于搜索、复制/粘贴和辅助功能的文本。
DocExComment_EPSColor
DocExComment_EPSColor 结构指定嵌入在 EMF 中的封装 PostScript (EPS) 文件的颜色信息。 有关此结构的详细信息,请参阅扩展颜色支持部分。
typedef struct
{
DWORD ident {};
DWORD iComment {};
BYTE colorInfo[];
} DocExComment_EPSColor;
DocExComment_EPSColor 结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentEPSColor。
colorInfo[] 指定 EPS 文件的颜色信息。 外接程序应使用 IMsoDocExporterSite::SetEPSInfo 方法将此信息传递给 Publisher。
DocExComment_EPSColorCMYKJPEG
DocExComment_EPSColorCMYKJPEG 结构在 EMF 中指定作为 CMYKJPEG 文件流的二进制对象的开始。 有关此结构的详细信息,请参阅扩展颜色支持部分。
typedef struct
{
DWORD ident {};
DWORD iComment {};
} DocExComment_EPSColorCMYKJPEG;
DocExComment_EPSColorCMYKJPEG 结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentEPSCMYKJPEG;
DocExComment_EPSColorSpotImage
DocExComment_EPSColorSpotImage结构为后续 RGB 图像提供专色信息。 有关此结构的详细信息,请参阅扩展颜色支持部分。
typedef struct
{
DWORD ident {};
DWORD iComment {};
COLORREF cmykAlt { 0 };
COLORREF rgbAlt { 0 };
float flTintMin {};
float flTintMax {};
char szSpotName[1];
} DocExComment_EPSColorSpotImage;
DocExComment_EPSColorSpotImage结构的成员如下所示:
ident 指定常量值 msodocexsignature,它将此 EMF 注释标识为包含语义信息。
iComment 指定 MSODOCEXCOMMENT 值 msodocexcommentEPSSpotImage。
cmykAlt 指定 CMYK 颜色 ID。
rgbAlt 指定 RGB 颜色 ID。
flTintMin 指定最小色调。
flTintMax 指定最大色调。
szSpotName[1] 指定一个长度可变的、以零结尾的字符串,其中包含现成名称。
扩展的颜色支持
若要在 Publisher 中支持扩展的颜色空间,需要额外的 EMF 语义记录和接口,因为 EMF 仅支持 RGB (红绿黑) 颜色。 扩展的颜色空间包括 CMYK (青色-品红色-黄色-黑色) 和专色空间,这些空间通常用于商业打印。
Publisher 使用颜色映射来表示文档 EMF 中的扩展颜色。 Publisher 为文档中使用的所有颜色生成颜色表,并将实际颜色替换为 EMF 中的颜色 ID。 颜色 ID 的类型是 COLORREF,它是用于 RGB 颜色的同一类型。 有关 COLORREF 结构的信息,请参阅 COLORREF。
若要将 EMF 中的颜色 ID 解析回扩展颜色空间,外接程序通过 IMsoDocExporterSite 接口的 HrResolveColor 方法调用回 Publisher。 加载项将 Publisher 指向 IDOCEXCOLOR 接口的接口指针作为参数之一传递给 HrResolveColor。 Publisher 获取在 对 HrResolveColor 的调用中也指定的颜色 ID,将它们转换为扩展颜色 (RGB、CMYK 或专色) ,并通过 IDOCEXCOLOR 接口中的方法将它们传递回外接程序。
矢量颜色和着色图像
矢量颜色是外接程序从 Publisher 接收的任何 COLORREF 值。 例如,文本颜色、线条笔划颜色和图元文件重新着色的颜色。 启用颜色映射后,Publisher 使用 COLORREF 的颜色 ID,而不是真正的 RGB 颜色值。 如果 Publisher 通过调用 IMsoDocExporter 接口的 SetDocExporterSite 方法为外接程序提供了 IMsoDocExporterSite 接口指针,则外接程序应始终调用 IMsoDocExporterSite::HrResolveColor 方法,以便将 COLORREF 转换为扩展颜色,外接程序通过 IDOCEXCOLOR 接口中的方法接收该颜色。
若要支持矢量颜色映射,外接程序需要执行以下作:
实现 对 IDOCEXCOLOR 接口的类支持。 此接口中的方法使 Publisher 能够将扩展颜色传递回外接程序。
缓存 EMF 中的语义记录中的以下颜色状态值。
设置用于重新着色的前景色。 这是通过 DocExComment_ColorInfo 结构设置 的 。
设置重新着色的背景色。 这是通过 DocExComment_ColorInfo 结构设置 的 。
确定何时启用颜色映射。 这是通过 DocExComment_ColorEnable 结构设置的。
对于矢量颜色,请使用颜色 ID 创建 IDOCEXCOLOR 接口,以便 IDOCEXCOLOR::GetUnresolvedRGB 返回颜色 ID。 外接程序应使用 IDOCEXCOLOR 接口和缓存的颜色状态调用 IMsoDocExporterSite::HrResolveColor 方法。 Publisher 使用最终颜色(可以是 RGB、CMYK、现成或注册色调)调用 IDOCEXCOLOR 接口方法。
当从 EMF 语义记录指定用于重新着色的前景色或背景色时,外接程序应重新着色外接程序中的图像 (例如图元文件或光栅图片) 。
非着色图像
EMF 支持使用 GDI+ 的 CMYK 映像 。 因此,EMF 中的图像可以是 RGB 或 CMYK。 如果图像是 CMYK 图像,则外接程序需要将图像转换为目标颜色空间。
Publisher 维护文档的目标颜色空间。 加载项可以通过使用图像的颜色空间调用 IMsoDocExporterSite::HrConvertImageColorSpace 方法来使用此目标颜色空间。
EPS 文件中的颜色
封装的 Postscript (EPS) 是一种支持扩展颜色空间的图元文件类型。 在 Publisher 文档中嵌入 EPS 图像的用户希望在固定格式输出中使用颜色信息。 在发布服务器中,EPS 转换为具有 EPS 相关语义记录的 EMF。 然后,此 EMF 嵌入到应用程序传递给加载项的页面 EMF 文件中。
若要支持 EPS 文件中的颜色,加载项需要执行以下作:
为 EMF 中遇到的DocExComment_EPSColor记录调用 IMsoDocExporterSite::SetEPSInfo 方法。
从 EMF 中的 DocExComment_EPSColorCMYKJPEG 记录中提取 CMYK 映像。 此记录包含一个二进制对象,该对象是实际的 CMYK JPEG 文件流。 使用它替换后续调用 StretchDIBits 函数中指定的 RGB 图像。
DocExComment_EPSColorSpotImage记录为后续 RGB 图像提供专色信息,该图像始终是索引图像。 加载项需要将专色图像转换为目标颜色空间。
加载项可以选择调用 IMsoDocExporterSite:: HrGetSpotRecolorInfo 方法,以便从 Publisher 获取文档的目标颜色。 然后,加载项可以通过将 RGB 图像调色板中的颜色映射到 DoxExComment_EPSColorSpotImage 记录中指定的 flTintMin 和 flTintMax 调色来重新着色后续 RGB 图像。 调色板每种颜色的亮度用于映射。
请注意, DocExComment_EPSStart 记录只是信息性的。 加载项可以忽略此记录。
SetDocExporterSite
发布服务器调用 SetDocExporterSite ,为加载项提供指向 IMsoDocExporterSite 接口的 指针。 IMsoDocExporterSite 接口公开了启用扩展颜色支持的方法。
void SetDocExporterSite(
IMsoDocExporterSite* pDocExporterSite
);
pDocExporterSite 参数指定指向 IMsoDocExporterSite 接口的接口指针。
HrSetPageHeightForPagination
应用程序可以调用 HrSetPageHeightForPagination 方法来指定页面高度(以磅为单位)。
HRESULT HrSetPageHeightForPagination(
float dytfPageHeight
);
某些应用程序以未分页格式维护用户的文档。 在这些情况下,外接程序使用应用程序在 调用 HrSetPageHeightForPagination 时指定的页面高度对文档进行分页。 dytfPageHeight 参数指定页面高度(以磅为单位)。
指定页面高度信息后,应用程序在调用 HrAddPageFromEmf 时将整个文档的外接程序作为单个内存中 EMF 文件传递。 然后,加载项使用页面高度和 EMF 文件对文档进行分页。
在对 HrGetPageBreaks 方法的后续调用中,外接程序将分页信息返回给应用程序。
HrGetPageBreaks
应用程序可以调用 HrGetPageBreaks 方法,以获取加载项分页的文档的分页符数量和位置。
HRESULT HrGetPageBreaks(
float* rgdytfPageBreaks,
int* pcchPageBreaks,
BOOL* pfCanTrustLastBreakIsEndOfDocument
);
外接程序使用 HrSetPageHeightForPagination 方法指定的页面高度对文档进行分页后,它会在应用程序对 HrGetPageBreaks 方法进行的后续调用中返回分页信息。
rgdytfPageBreaks 参数是指向浮点值数组的指针,这些值以磅为单位指定分页符的位置。 数组中的第一个元素 (索引 0) 是第一个分页符的位置,第二个元素是第二个分页符的位置,依类而行。 因此,这些元素的值会连续增加。
pcchPageBreaks 参数是指向指定文档中分页符数的整数值的指针。
pfCanTrustLastBreakIsEndOfDocument 参数指定最后一个分页符的位置是文档的末尾还是文档最后一页的开头。 true 值指示最后一个分页符是文档的末尾。
应用程序调用 HrGetPageBreak两 次以获取分页信息。 在第一次调用时,应用程序调用 HrGetPageBreaks 以获取分页符的数量。
HrGetPageBreaks(NULL, &nPageBreaks, NULL);
然后,应用程序再次调用 HrGetPageBreaks 以获取实际位置。 第二次调用时,应用程序传递一个足够大小的缓冲区来保存分页符位置的数组。
HrGetPageBreaks(rgPageBreaks, &nPageBreaks, fCanStopAtLastPageBreak);
从外接程序接收分页符信息后,应用程序会重新启动固定格式的导出过程,从调用 HrCreateDoc 方法开始,然后针对分页符信息提供的每个页面调用 HrAddPageFromEmf 。
HrAddOutlineNode
Publisher 调用 HrAddOutlineNode 方法,向外接程序传递一个结构,该结构描述导出文档的用户可导航大纲中的节点。
HRESULT HrAddOutlineNode(
int idNodeParent
const MSODOCEXOUTLINENODE* pNode
);
固定格式的导出代码可以使用 HrAddOutlineNode 方法传递的信息来构造导出文档的用户可导航大纲。 从用户的角度来看,大纲中的每个节点都由一些映射到文档中特定位置的标题文本表示。
每次调用 HrAddOutlineNode 都会在此大纲中指定单个节点的信息。 每个节点由在大纲中唯一的节点 ID 标识。 为根节点保留 ID 0 。 大纲是分层的,也就是说,它具有树结构,其中每个节点都有一个父节点和零个或多个子节点。
HrAddOutlineNode 的第一个参数提供作为传入节点的父节点的 ID。
Publisher 始终为父节点调用 HrAddOutlineNode ,然后再为父节点的任何子节点调用 方法。 换句话说,导出代码可确保已具有 idNodeParent 参数标识的节点的节点信息。 唯一的例外是对 HrAddOutlineNode 的初始调用,它指定根节点。 对于此调用, idNodeParent 的值为 0。
HrAddOutlineNode 在 pNode 参数指向的 MSODOCEXOUTLINENODE 结构中传递每个节点所需的导出代码的其他信息。
typedef struct _MsoDocexOutlineNode
{
int idNode {};
WCHAR rgwchNodeText[cwchMaxNodeText];
int iDestPage {};
float dytfvDestPage {};
float dxtfvDestOffset {};
float dytfvDestOffset {};
} MSODOCEXOUTLINENODE;
MSODOCEXOUTLINENODE 的成员描述如下:
idNode 节点的 ID。 值为 -1 表示此节点在大纲中不能有子节点。 否则,此成员具有在文档中唯一的值。
rgwchNodeText 一个 Unicode 字符串,表示每个节点的标题文本。 此文本在大纲中不一定是唯一的。
iDestPage 包含文档中的目标位置的页面的页码。
dytfvDestPage 目标页的高度(以磅为单位)。 dytfvDestOffset 成员指定的偏移量相对于页面左上角。 但是,某些固定格式类型使用相对于页面左下角的坐标系。 对于这些类型的文档,需要页面高度才能转换偏移量。
dxtfvDestOffset 目标页上目标位置的水平偏移量。
dytfvDestOffset 目标页上目标位置的垂直偏移量。
HrAddDocumentMetadataString
Publisher 调用 HrAddDocumentMetadataString 方法以 Unicode 字符串的形式指定文档元数据。
HRESULT HrAddDocumentMetadataString(
MSODOCEXMETADATA metadataType,
const WCHAR* pwchValue
);
metadatatype 参数指定字符串表示的元数据的类型。 metadatatype 参数必须是 MSODOCEXMETADATA 枚举类型中的以下值之一。
表 8. MSODOCEXMETADATA 的枚举值
值 |
说明 |
---|---|
msodocexMetadataTitle |
文档的标题。 |
msodocexMetadataAuthor |
文档的作者 |
msodocexMetadataSubject |
描述文档主题的字符串, (例如商业或科学) 。 |
msodocexMetadataKeywords |
与文档内容相关的关键字。 |
msodocexMetadataCreator |
文档的创建者,可能与作者不同。 |
msodocexMetadataProducer |
文档的生成者,可能与作者或创建者不同。 |
msodocexMetadataCategory |
描述文档类型的字符串, (例如备注、文章或书籍) 。 |
msodocexMetadataStatus |
文档的状态。 此字段可以反映文档在发布过程中的位置, (例如草稿或最终) 。 |
msodocexMetadataComments |
与文档相关的其他注释。 |
对于给定文档,每个元数据类型只能有一个与之关联的字符串。 因此,例如,如果文档有多个关键字,它们将作为一个串联字符串传递给外接程序。
pwchValue 参数指定包含元数据本身的 Unicode 字符串。
外接程序如何将文本字符串元数据合并到导出的文档中取决于导出代码的实现详细信息以及导出文档中使用的固定格式的类型。
HrAddDocumentMetadataDate
Publisher 调用 HrAddDocumentMetadataDate 方法以 FILETIME 结构的形式指定文档元数据。
HRESULT HrAddDocumentMetadataDate(
MSODOCEXMETADATA metadataType,
const FILETIME* pftLocalTime
);
metadatatype 参数指定 FILETIME 结构表示的元数据的类型。 metadatatype 参数必须是 MSODOCEXMETADATA 枚举类型中的以下值之一。
表 9. MSODOCEXMETADATA 的枚举值
值 |
说明 |
---|---|
msodocexMetadataCreationDate |
文档的创建日期。 |
msodocexMetadataModDate |
文档的上次修改日期。 |
pftLocalTime 参数指定指向 FILETIME 结构的指针,该结构包含元数据的日期和时间信息。 以下代码片段演示如何从 结构中提取此信息。
SYSTEMTIME st = { 0 };
WCHAR s[100];
FileTimeToSystemTime(pfiletime, &st);
swprintf(s, 99, L" %04d-%02d-%02dT%02d:%02d:%02dZ", st.wYear % 10000,
st.wMonth % 100, st.wDay % 100, st.wHour % 100, st.wMinute % 100,
st.wSecond % 100);
加载项如何将日期和时间元数据合并到导出文档中取决于导出代码的实现详细信息以及导出文档中使用的固定格式的类型。
HrFinalize
Publisher 在文档导出过程结束时调用 HrFinalize 方法。
HRESULT HrFinalize();
实现固定格式导出的代码应使用 HrFinalize 来执行刷新数据缓冲区、将剩余数据写入磁盘以及释放内存和其他资源等任务。
总结
可以通过实现 IMsoDocExporter 接口来扩展 Office 应用程序的固定格式导出功能。 此接口的方法为 Office 应用程序提供了一个通道,用于向外接程序传达要导出的文档中的视觉内容和语义信息。 文档的可视内容作为一个或多个内存中增强型图元文件提供给加载项。 语义信息在此 EMF 中作为特殊格式的注释记录提供。 接口中的其他方法使 Office 应用程序能够传达有关文档的元数据和结构信息。
其他资源
有关详细信息,请参阅以下资源: