字体控件
为了简化需要字处理和文本编辑功能的应用程序中字体支持的集成和配置,Windows 功能区框架提供了一个专门的字体控件,用于公开各种字体属性,如字样名称、样式、点大小和效果。
介绍
字体控件是一个复合控件,由按钮、切换按钮、下拉列表框和组合框组成,所有这些控件都用于指定特定的字体属性或格式选项。
以下屏幕截图显示了 Windows 7 的 WordPad 中的功能区字体控件。
一致的体验
作为内置功能区控件,字体控件可改进整体字体管理、选择和格式设置功能,并在所有功能区应用程序中提供丰富的、一致的用户体验。
这种一致的体验包括
跨功能区应用程序的标准化格式和字体选择。
跨功能区应用程序的标准化字体表示形式。
在 Windows 7 中自动激活基于 显示 或 隐藏 设置 字体 控制面板中的每个字体。 字体控件仅显示设置为 显示的字体。
注意
在 Windows Vista 中,字体 控制面板不提供 显示 或 隐藏 功能,因此将激活所有字体。
可直接从控件获取的字体管理。
以下屏幕截图显示可以直接从字体控件访问 字体 控制面板。
windows 7 的字板中字体系列列表的
支持自动预览。
与用户最相关的字体的公开,例如
- 面向国际用户的本地化字体列表。
- 基于输入设备的字体列表。
注意
在 Windows 7 以外的任何平台上都不支持此功能。
轻松集成和配置
通过提供标准、可重用且易于使用的功能,功能区字体控制可减轻将字体支持集成到应用程序中的负担。
字体选择和格式的详细信息包装在一个自包含逻辑元素中
- 消除字体控制实现的典型控制相互依赖性的复杂管理。
- 对于字体控件子控件公开的所有功能,需要单个命令处理程序。
此单个命令处理程序允许字体控件在内部管理各种子控件的功能;子控件从不直接与应用程序交互,而不考虑其功能。
字体控件的其他功能包括
字体系列 菜单中每个字体的位图表示形式(你看到的是所见内容)的自动 DPI 感知生成。
本地化字体系列位图和工具提示。
用于管理和呈现字体的字体枚举、分组和元数据。
注意
对此功能的支持在 Windows 7 以外的任何平台上都不可用。
文本颜色 和 文本突出显示颜色 下拉颜色选取器,这些颜色选取器 Drop-Down 颜色选取器 行为。
支持所有基于字体控件库的子控件自动预览:字体系列、字号、文本颜色和 文本突出显示颜色。
与通用 GDI 文本结构对齐
Windows 图形设备界面(GDI) 文本堆栈组件用于通过功能区字体控件公开字体选择和格式设置功能。 LOGFONT 结构、CHOOSEFONT 结构支持的各种字体功能,CHARFORMAT2 结构 通过字体控件中包含的子控件公开。
字体控件中显示的子控件取决于功能区标记中声明的 FontType 模板。 FontType 模板(在下一部分中进一步详细讨论)旨在与常见的 windows 图形设备界面(GDI) 文本结构保持一致。
添加 FontControl
本部分概述了向功能区应用程序添加字体控件的基本步骤。
在标记中声明 FontControl
与其他功能区控件一样,字体控件使用 FontControl 元素在标记中声明,并通过命令 ID 与命令声明相关联。 编译应用程序时,命令 ID 用于将命令绑定到主机应用程序中的命令处理程序。
注意
如果未使用标记中的 FontControl 声明命令 ID,则框架将生成一个命令 ID。
由于字体控件的子控件未直接公开,因此字体控件的自定义限制为框架定义的三个 FontType 布局模板。
通过将布局模板与 FontControl 属性(如 IsHighlightButtonVisible、IsStrikethroughButtonVisible和 IsUnderlineButtonVisible)结合使用,可以进一步自定义字体控件。
注意
超出标准字体控件模板和属性公开的字体功能需要一个不在本文范围内的自定义字体控件实现。
下表列出了每个模板都与之对齐的字体控件模板和编辑控件类型。
模板 | 支持 |
---|---|
FontOnly | LOGFONT 结构 |
FontWithColor | CHOOSEFONT 结构 |
RichFont | CHARFORMAT2 结构 |
下表列出了与每个模板关联的控件,并标识关联模板的可选控件。
控制
模板
RichFont
FontWithColor
FontOnly
违约
自选
违约
自选
违约
自选
字体大小 组合框
是的
不
是的
不
是的
不
字体系列 组合框
是的
不
是的
不
是的
不
“放大缩小字体”按钮
是的
是的
是的
是的
-
-
收缩字体 按钮
是的
是的
是的
是的
-
-
粗体 按钮
是的
不
是的
不
是的
不
斜体 按钮
是的
不
是的
不
是的
不
下划线 按钮
是的
不
是的
是的
是的
是的
删除线 按钮
是的
不
是的
是的
是的
是的
下标 按钮
是的
不
-
-
-
-
上标 按钮
是的
不
-
-
-
-
文本突出显示颜色 按钮
是的
不
是的
是的
-
-
文本颜色 按钮
是的
不
是的
不
-
-
声明字体控件的布局行为时,功能区框架提供了可选的 SizeDefinition 布局模板,OneFontControl
,该模板根据功能区的大小和字体控件可用的空间定义两个子控件配置。 有关详细信息,请参阅 通过大小定义和缩放策略自定义功能区。
将 FontControl 添加到功能区
以下代码示例演示向功能区添加字体控件的基本标记要求:
此代码部分显示 FontControl 命令声明标记,包括用于在 功能区中显示控件所需的 选项卡 和 组 命令。
<Command Name="cmdTab1"
Comment="These comments are optional and are inserted into the header file."
Symbol="cmdTab1" Id="10000" >
<Command.LabelTitle>Tab 1</Command.LabelTitle>
</Command>
<Command Name="cmdGroup1" Comment="Group #1" Symbol="cmdGroup1" Id="20000">
<!-- This image is used when the group scales to a pop-up. -->
<Command.SmallImages>
<Image>res/Button_Image.bmp</Image>
</Command.SmallImages>
</Command>
<Command Name="cmdFontControl" Symbol="cmdFontControl" Comment="FontControl" Id="25001" Keytip="F" />
此代码部分显示通过命令 ID 声明和关联 FontControl 与 Command 所需的标记。 此特定示例包括具有缩放首选项的 Tab 和 组 声明。
<Ribbon.Tabs>
<Tab CommandName="cmdTab1">
<Tab.ScalingPolicy>
<ScalingPolicy>
<ScalingPolicy.IdealSizes>
<Scale Group="cmdGroup1" Size="Large" />
</ScalingPolicy.IdealSizes>
<!-- Describe how the FontControl group scales. -->
<Scale Group="cmdGroup1" Size="Medium" />
<Scale Group="cmdGroup1" Size="Popup" />
</ScalingPolicy>
<Group CommandName="cmdGroup1" SizeDefinition="OneFontControl">
<FontControl CommandName="cmdFontControl" FontType="RichFont" />
</Group>
</Tab>
</Ribbon.Tabs>
将 FontControl 添加到 ContextPopup
将字体控件添加到 上下文弹出窗口 需要类似于向功能区添加字体控件的过程。 但是,MiniToolbar 中的字体控件仅限于所有字体控件模板通用的默认子控件集:字体系列、字号、粗体和 斜体。
以下代码示例演示了将字体控件添加到 上下文弹出窗口的基本标记要求:
此代码部分显示了在 ContextPopup中显示 FontControl 所需的 FontControl 命令声明标记。
<Command Name="cmdFontControl" Symbol="cmdFontControl" Comment="FontControl" Id="25001" />
此代码部分显示通过命令 ID 声明和关联 FontControl 所需的标记。
<ContextPopup.MiniToolbars>
<MiniToolBar Name="MiniToolbar1">
<MenuCategory Class="StandardItems">
<FontControl CommandName="cmdFontControl" />
</MenuCategory>
</MiniToolBar>
</ContextPopup.MiniToolbars>
密钥提示
功能区字体控件中的每个子控件都可以通过键盘快捷方式或键提示进行访问。 此键提示是预定义的,由框架分配给每个子控件。
如果将 Keytip 属性值分配给标记中的 FontControl 元素,则此值将作为前缀添加到框架定义的键提示中。
注意
应用程序应为此前缀强制实施单字符规则。
下表列出了框架定义的关键提示。
子控件 | Keytip |
---|---|
字体系列 | F |
字形 | T |
字号 | S |
放大缩小字体功能 | G |
收缩字体 | K |
大胆 | B |
斜体的 | 我 |
下划线 | U |
删除线 | X |
上标 | Y 或 Z 注意: 如果未在标记中声明 键提示 属性,则默认键提示为 Y;否则,默认键提示 键提示 + Z。 |
下标 | 一个 |
字体颜色 | C |
字体突出显示 | H |
多语言用户界面(MUI)EN-US 功能区的建议前缀为“F”,如以下示例所示。
<Command Name="cmdFontControl" Symbol="cmdFontControl" Comment="FontControl" Id="25001" Keytip="F" />
以下屏幕截图演示了上一示例中定义的字体控件键提示。
功能区资源文件
编译标记文件时,将生成包含功能区应用程序的所有资源引用的资源文件。
简单资源文件的示例:
// ******************************************************************************
// * This is an automatically generated file containing the ribbon resource for *
// * your application. *
// ******************************************************************************
#include ".\ids.h"
STRINGTABLE
BEGIN
cmdTab1_LabelTitle_RESID L"Tab 1"
/* LabelTitle cmdTab1_LabelTitle_RESID: These comments are optional and are
inserted into the header file. */
END
cmdGroup1_SmallImages_RESID BITMAP "res\\Button_Image.bmp"
/* SmallImages cmdGroup1_SmallImages_RESID: Group #1 */
STRINGTABLE
BEGIN
cmdFontControl_Keytip_RESID L"F" /* Keytip cmdFontControl_Keytip_RESID: FontControl */
END
FCSAMPLE_RIBBON UIFILE "Debug\\FCSample.bml"
字体控件属性
通常,通过调用 IUIFramework::InvalidateUICommand 方法使与控件关联的命令失效,在功能区 UI 中更新字体控件属性。 无效事件由 IUICommandHandler::UpdateProperty 回调方法处理并定义属性更新。
不会执行 IUICommandHandler::UpdateProperty 回调方法,并且应用程序会查询更新的属性值,直到框架需要该属性。 例如,当选项卡被激活,并在功能区 UI 中显示控件或显示工具提示时。
注意
在某些情况下,可以通过 IUIFramework::GetUICommandProperty 方法检索属性,并使用 IUIFramework::SetUICommandProperty 方法进行设置。
下表列出了与字体控件关联的属性键。
属性键 | 笔记 |
---|---|
UI_PKEY_FontProperties | 以 IPropertyStore 对象的形式公开所有字体控件子控件属性。 当 UI_INVALIDATIONS_VALUE 作为调用 IUIFramework::InvalidateUICommand调用中 标志的值时,框架将查询此属性。 |
UI_PKEY_FontProperties_ChangedProperties | 以 IUISimplePropertySet 对象的形式公开,仅显示已更改的字体控件子控件属性。 |
UI_PKEY_Keytip | 只能通过无效更新。 |
UI_PKEY_Enabled | 支持 IUIFramework::GetUICommandProperty 和 IUIFramework::SetUICommandProperty。 |
除了字体控件本身支持的属性外,功能区框架还为每个字体控件子控件定义 属性键。 这些属性键及其值由框架通过 IPropertyStore 接口实现公开,该接口实现定义了管理集合的方法(也称为属性包)的名称和值对。
应用程序将字体结构转换为可通过 IPropertyStore 接口方法访问的属性。 此模型强调字体控件与 Windows 图形设备界面(GDI)文本堆栈组件(LOGFONT 结构、CHOOSEFONT 结构和框架支持的 CHARFORMAT2 结构)之间的区别。
下表列出了各个控件及其关联的属性键。
定义 FontControl 命令处理程序
本部分介绍将字体控件绑定到命令处理程序所需的步骤。
警告
如果没有任何命令处理程序与控件关联的命令处理程序,任何从字体控件的颜色选取器中选择颜色监视都可能导致访问冲突。
下面的代码示例演示如何将标记中声明的命令绑定到命令处理程序。
//
// FUNCTION: OnCreateUICommand(UINT, UI_COMMANDTYPE, IUICommandHandler)
//
// PURPOSE: Called by the Ribbon framework for each command specified in markup, to allow
// the host application to bind a command handler to that command.
//
STDMETHODIMP CApplication::OnCreateUICommand(
UINT nCmdID,
__in UI_COMMANDTYPE typeID,
__deref_out IUICommandHandler** ppCommandHandler)
{
UNREFERENCED_PARAMETER(typeID);
UNREFERENCED_PARAMETER(nCmdID);
if (NULL == m_pCommandHandler)
{
HRESULT hr = CCommandHandler::CreateInstance(&m_pCommandHandler);
if (FAILED(hr))
{
return hr;
}
}
return m_pCommandHandler->QueryInterface(IID_PPV_ARGS(ppCommandHandler));
}
下面的代码示例演示如何实现字体控件的 IUICommandHandler::Execute 方法。
//
// FUNCTION: Execute()
//
// PURPOSE: Called by the Ribbon framework when a command is executed
// by the user. For example, when a button is pressed.
//
STDMETHODIMP CCommandHandler::Execute(
UINT nCmdID,
UI_EXECUTIONVERB verb,
__in_opt const PROPERTYKEY* key,
__in_opt const PROPVARIANT* ppropvarValue,
__in_opt IUISimplePropertySet* pCommandExecutionProperties)
{
UNREFERENCED_PARAMETER(nCmdID);
HRESULT hr = E_NOTIMPL;
if ((key) && (*key == UI_PKEY_FontProperties))
{
// Font properties have changed.
switch (verb)
{
case UI_EXECUTIONVERB_EXECUTE:
{
hr = E_POINTER;
if (pCommandExecutionProperties != NULL)
{
// Get the changed properties.
PROPVARIANT varChanges;
hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &varChanges);
if (SUCCEEDED(hr))
{
IPropertyStore *pChanges;
hr = UIPropertyToInterface(UI_PKEY_FontProperties, varChanges, &pChanges);
if (SUCCEEDED(hr))
{
// Using the changed properties, set the new font on the selection on RichEdit control.
g_pFCSampleAppManager->SetValues(pChanges);
pChanges->Release();
}
PropVariantClear(&varChanges);
}
}
break;
}
case UI_EXECUTIONVERB_PREVIEW:
{
hr = E_POINTER;
if (pCommandExecutionProperties != NULL)
{
// Get the changed properties for the preview event.
PROPVARIANT varChanges;
hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &varChanges);
if (SUCCEEDED(hr))
{
IPropertyStore *pChanges;
hr = UIPropertyToInterface(UI_PKEY_FontProperties, varChanges, &pChanges);
if (SUCCEEDED(hr))
{
// Set the previewed values on the RichEdit control.
g_pFCSampleAppManager->SetPreviewValues(pChanges);
pChanges->Release();
}
PropVariantClear(&varChanges);
}
}
break;
}
case UI_EXECUTIONVERB_CANCELPREVIEW:
{
hr = E_POINTER;
if (ppropvarValue != NULL)
{
// Cancel the preview.
IPropertyStore *pValues;
hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pValues);
if (SUCCEEDED(hr))
{
g_pFCSampleAppManager->CancelPreview(pValues);
pValues->Release();
}
}
break;
}
}
}
return hr;
}
下面的代码示例演示如何实现字体控件的 IUICommandHandler::UpdateProperty 方法。
//
// FUNCTION: UpdateProperty()
//
// PURPOSE: Called by the Ribbon framework when a command property (PKEY) needs to be updated.
//
// COMMENTS:
//
// This function is used to provide new command property values, such as labels, icons, or
// tooltip information, when requested by the Ribbon framework.
//
//
STDMETHODIMP CCommandHandler::UpdateProperty(
UINT nCmdID,
__in REFPROPERTYKEY key,
__in_opt const PROPVARIANT* ppropvarCurrentValue,
__out PROPVARIANT* ppropvarNewValue)
{
UNREFERENCED_PARAMETER(nCmdID);
HRESULT hr = E_NOTIMPL;
if (key == UI_PKEY_FontProperties)
{
hr = E_POINTER;
if (ppropvarCurrentValue != NULL)
{
// Get the font values for the selected text in the font control.
IPropertyStore *pValues;
hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarCurrentValue, &pValues);
if (SUCCEEDED(hr))
{
g_pFCSampleAppManager->GetValues(pValues);
// Provide the new values to the font control.
hr = UIInitPropertyFromInterface(UI_PKEY_FontProperties, pValues, ppropvarNewValue);
pValues->Release();
}
}
}
return hr;
}