注释
自联机文档中首次包含此说明以来,尚未更新以下技术说明。 因此,某些过程和主题可能过期或不正确。 有关最新信息,建议在在线文档索引中搜索您感兴趣的主题。
此说明将讨论与就地编辑相关的问题,以及服务器如何完成正确的缩放和就地调整大小。 通过就地激活,WYSIWYG 概念在容器和服务器之间进一步合作,特别是以完全相同的方式解释 OLE 规范。
由于容器与支持就地激活的服务器之间的密切交互,因此应维护最终用户的一些期望:
演示文稿显示(覆盖中
COleServerItem::OnDraw
绘制的图元文件)应与绘制编辑时完全相同(只是编辑工具不可见)。当容器缩放时,服务器窗口也应该!
容器和服务器应显示使用相同指标进行编辑的对象。 这意味着在显示设备上呈现时,使用基于每英寸 逻辑 像素数(而不是每英寸的物理像素数)的映射模式。
注释
由于就地激活仅适用于嵌入(未链接)的项目,因此缩放仅适用于嵌入的对象。 你将在两者COleServerDoc
COleServerItem
中看到用于缩放的 API。 此二分法的原因是,只有对链接项和嵌入项 COleServerItem
都有效的函数(这允许您具有通用实现),并且仅对嵌入对象有效的函数位于类中 COleServerDoc
(从服务器的角度来看,它是嵌入 的文档 )。
大多数负担都放在服务器实现者身上,因为服务器必须了解容器的缩放因子,并根据需要修改其编辑界面。 但是服务器如何确定容器正在使用的缩放因子
MFC 对缩放的支持
当前缩放因子可以通过调用 COleServerDoc::GetZoomFactor
来确定。 当文档未就地活动时调用此方法将始终产生 100% 缩放因子(或 1:1 比率)。 在就地活动期间调用它可能会返回 100 个%以外的内容。
有关正确缩放的示例,请参阅 MFC OLE 示例 HIERSVR。 放大 HIERSVR 是复杂的,因为它通常显示文本,文本通常不会以线性方式缩放(提示、版式约定、设计宽度和高度都使此事复杂化)。 不过,HIERSVR 是正确实现缩放的合理参考,MFC 教程 SCRIBBLE (步骤 7) 也是如此。
COleServerDoc::GetZoomFactor
根据容器或类实现COleServerItem
COleServerDoc
中可用的多种不同指标来确定缩放因子。 简言之,当前缩放因子由以下公式决定:
Position Rectangle (PR) / Container Extent (CE)
POSITION RECTANGLE 由容器确定。 调用服务器时 COleClientItem::OnGetItemPosition
,在就地激活期间,它会返回到服务器,并在容器调用服务器 COleServerDoc::OnSetItemRects
时更新(调用服务器 COleClientItem::SetItemRects
)。
容器盘区要计算稍微复杂一些。 如果容器已调用 COleServerItem::OnSetExtent
(调用该 COleClientItem::SetExtent
容器),则 CONTAINER EXTENT 将根据每个逻辑英寸的像素数转换为像素。 如果容器未调用 SetExtent(通常是这种情况),则 CONTAINER EXTENT 是从中 COleServerItem::OnGetExtent
返回的大小。 因此,如果容器尚未调用 SetExtent,则框架假定如果容器使用自然范围的 100%(从 COleServerItem::GetExtent
中返回的值)调用该容器。 另一种方式是,框架假定容器显示项的 100%(不再显示,不再少)。
请务必注意,虽然 COleServerItem::OnSetExtent
具有 COleServerItem::OnGetExtent
类似的名称,但它们不会作项的相同属性。
OnSetExtent
调用 可让服务器知道容器中有多少对象可见(无论缩放因子如何),并由 OnGetExtent
容器调用以确定对象的理想大小。
通过查看涉及的每个 API,可以更清晰地了解:
COleServerItem::OnGetExtent
此函数应返回项的 HIMETRIC 单位中的“自然大小”。 考虑“自然大小”的最佳方式是将其定义为打印时可能显示的大小。 此处返回的大小是特定项内容的常量(非常类似于图元文件,它是特定项的常量)。 当缩放应用于项时,此大小不会更改。 当容器通过调用 OnSetExtent
为项提供更多或更少的空间时,它通常不会更改。 更改的一个示例可能是,简单文本编辑器没有“边距”功能,该功能基于容器发送的最后一个盘区包装文本。 如果服务器确实发生更改,则服务器可能应在系统注册表中设置OLEMISC_RECOMPOSEONRESIZE位(请参阅 OLE SDK 文档,了解有关此选项的详细信息)。
COleServerItem::OnSetExtent
当容器显示对象的“或多或少”时,将调用此函数。 大多数容器根本不会调用此调用。 默认实现将从容器接收的最后一个值存储在“m_sizeExtent”中,用于 COleServerDoc::GetZoomFactor
计算上述 CONTAINER EXTENT 值。
COleServerDoc::OnSetItemRects
仅当文档处于就地活动状态时,才会调用此函数。 当容器更新项的位置或应用于该项的剪辑时,将调用它。 如上所述,POSITION RECTANGLE 提供缩放因子计算的分子。 服务器可以通过调用 COleServerDoc::RequestPositionChange
来请求更改项位置。 容器可以通过调用OnSetItemRects
(调用)来响应此请求(调用)。COleServerItem::SetItemRects
COleServerDoc::OnDraw
请务必认识到,无论当前缩放因子如何,重写生成所创建的 COleServerItem::OnDraw
图元文件都完全相同。 容器会根据需要缩放图元文件。 这是视图和 OnDraw
服务器项 OnDraw
之间的重要区别。 视图将处理缩放,该项只创建 可缩放 的图元文件,并将其留给容器以执行适当的缩放。
确保服务器的行为正确的最佳方式是使用文档就地处于活动状态的实现 COleServerDoc::GetZoomFactor
。
In-Place 调整大小的 MFC 支持
MFC 完全实现就地调整接口的大小,如 OLE 2 规范中所述。 类支持 COleResizeBar
用户界面、自定义消息WM_SIZECHILD,以及此消息的特殊 COleIPFrameWnd
处理。
你可能希望实现此消息的处理方式不同于框架提供的内容。 如上所述,框架保留就地调整到容器的结果 - 服务器响应缩放因子中的更改。 如果容器通过在处理容器盘区和位置矩形(调用时调用COleServerDoc::RequestPositionChange
)COleClientItem::OnChangeItemPosition
来做出反应,则就地调整大小将导致在编辑窗口中显示项的“更多或更少”。 如果容器通过在处理 COleClientItem::OnChangeItemPosition
过程中设置 POSITION RECTANGLE 做出反应,缩放因子将更改,并且项目将显示为“放大或缩小”。
服务器可以控制此协商期间发生的情况(在某种程度上)。 例如,当用户在就地编辑项目时调整窗口大小时,电子表格可能会选择显示更多或更少的单元格。 字处理器可能会选择更改“页边距”,以便它们与窗口相同,并将文本重新包装到新的页边距。 服务器通过在调整大小完成后更改自然范围(返回 COleServerItem::OnGetExtent
的大小)来实现此情况。 这将导致 POSITION RECTANGLE 和 CONTAINER EXTENT 更改相同的量,从而导致相同的缩放因子,但查看区域更大或更小。 此外,或多或少的文档将显示在由该 OnDraw
文档生成的图元文件中。 在这种情况下,当用户调整项目大小时,文档本身将发生变化,而不只是查看区域。
可以通过重写类中的COleIPFrameWnd
WM_SIZECHILD消息来实现COleResizeBar
自定义大小调整,但仍可以利用用户界面。 有关WM_SIZECHILD的详细信息,请参阅 技术说明 24。