字体控件

为了简化需要字处理和文本编辑功能的应用程序中字体支持的集成和配置,Windows 功能区框架提供了一个专用的字体控件,该控件公开各种字体属性,例如字样名称、样式、点大小和效果。

简介

字体控件是由按钮、切换按钮、下拉列表框和组合框组成的复合控件,所有这些控件都用于指定特定的字体属性或格式设置选项。

以下屏幕截图显示了 Windows 7 写字板中的功能区字体控件。

将 richfont 属性设置为 true 的 fontcontrol 元素的屏幕截图。

一致的体验

作为内置的功能区控件,字体控件改进了整体字体管理、选择和格式设置功能,并跨所有功能区应用程序提供丰富、一致的用户体验。

这种一致的体验包括

  • 跨功能区应用程序的字体标准化格式和字体选择。

  • 跨功能区应用程序的标准化字体表示形式。

  • 在 Windows 7 中,基于“字体”控制面板中每种字体的 “显示 ”或 “隐藏” 设置自动激活 字体 。 字体控件仅显示设置为 “显示”的字体。

    注意

    在 Windows Vista 中, “字体 ”控制面板不提供 “显示 ”或 “隐藏” 功能,因此会激活所有字体。

  • 可直接从 控件获取的字体管理。

    以下屏幕截图显示可以直接从 字体 控件访问“字体”控制面板。

    windows 7 的写字板中字体系列列表的屏幕截图。

  • 支持自动预览。

  • 公开与用户最相关的字体,例如

    • 面向国际用户的本地化字体列表。
    • 基于输入设备的字体列表。

    注意

    对此功能的支持在早于 Windows 7 的任何平台上都不可用。

轻松集成和配置

通过提供标准、可重用且易于使用的功能,功能区字体控件减轻了将字体支持集成到应用程序中的负担。

字体选择和格式设置的详细信息包装在一个独立逻辑元素中,

  • 消除了字体控件实现的典型控制相互依赖关系的复杂管理。
  • 对于字体控件子控件公开的所有功能,需要单个命令处理程序。

此单个命令处理程序允许字体控件在内部管理各种子控件的功能;子控件从不直接与应用程序交互,无论其功能如何。

字体控件的其他功能包括

  • 自动生成 DPI 感知的 WYSIWYG (你所看到的是“ 字体系列 ”菜单中每种字体) 位图表示形式。

  • Windows 图形设备接口 (GDI) 集成。

  • 本地化字体系列位图和工具提示。

  • 用于管理和显示字体的字体枚举、分组和元数据。

    注意

    对此功能的支持在早于 Windows 7 的任何平台上都不可用。

  • 文本颜色文本突出显示颜色下拉颜色选取器,镜像功能区下拉颜色选取器行为。

  • 支持所有基于字体控件库的子控件自动预览: 字体系列字号文本颜色文本突出显示颜色

与通用 GDI 文本结构对齐

Windows 图形设备接口 (GDI) 文本堆栈组件用于通过功能区字体控件公开字体选择和格式设置功能。 LOGFONT 结构CHOOSEFONT 结构和CHARFORMAT2 结构支持的各种字体功能通过字体控件中包含的子控件公开。

字体控件中显示的子控件取决于功能区标记中声明的 FontType 模板。 以下部分 (进一步详细讨论 FontType 模板) 旨在与通用 Windows 图形设备接口 (GDI) 文本结构保持一致。

添加 FontControl

本部分概述了将字体控件添加到功能区应用程序的基本步骤。

在标记中声明 FontControl

与其他功能区控件一样,字体控件在带有 FontControl 元素的标记中声明,并通过命令 ID 与命令声明相关联。 编译应用程序时,命令 ID 用于将命令绑定到主机应用程序中的命令处理程序。

注意

如果没有在标记中使用 FontControl 声明命令 ID,则框架会生成一个命令 ID。

由于字体控件的子控件不直接公开,因此字体控件的自定义仅限于框架定义的三个 FontType 布局模板。

通过将布局模板与 FontControl 属性(如 IsHighlightButtonVisibleIsStrikethroughButtonVisibleIsUnderlineButtonVisible)相结合,可以进一步自定义字体控件。

注意

超出标准字体控件模板和属性公开的字体功能需要一个不在本文讨论范围的自定义字体控件实现。

下表列出了字体控件模板以及每个模板与之对齐的编辑控件类型。

模板 支持
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 并将其与 命令 关联所需的标记。 此特定示例包括具有缩放首选项的 TabGroup 声明。

<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 元素,则此值将作为前缀添加到框架定义的键提示。

注意

应用程序应为此前缀强制实施单字符规则。

下表列出了框架定义的关键提示。

子控件 键提示
字体系列 F
字形 T
字体大小 S
增大字体 G
收缩字体 K
加粗 B
斜体 I
下划线 U
删除线 X
上标 Y 或 Z 注意: 如果未在标记中声明 键提示 属性,则默认键提示为 Y;否则,默认键提示为 键提示 + Z。
下标 A
字体颜色 C
字体突出显示 H

建议的多语言用户界面 (MUI) EN-US 功能区前缀为“F”,如以下示例所示。

<Command Name="cmdFontControl" Symbol="cmdFontControl" Comment="FontControl" Id="25001" Keytip="F" />

以下屏幕截图演示了上一示例中定义的字体控件键提示。

windows 7 的写字板中字体控制键提示的屏幕截图。

功能区资源文件

编译标记文件时,将生成一个包含功能区应用程序的所有资源引用的资源文件。

简单资源文件的示例:

// ******************************************************************************
// * 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 中更新 Font Control 属性。 无效事件由 IUICommandHandler::UpdateProperty 回调方法处理,并更新定义的属性。

IUICommandHandler::UpdateProperty 回调方法不会执行,应用程序会查询更新的属性值,直到框架需要该属性。 例如,在功能区 UI 中激活选项卡和显示控件时,或显示工具提示时。

注意

在某些情况下,可以通过 IUIFramework::GetUICommandProperty 方法检索属性,并使用 IUIFramework::SetUICommandProperty 方法进行设置。

下表列出了与字体控件关联的属性键。

属性键 注释
UI_PKEY_FontProperties IPropertyStore 对象的形式聚合公开所有 Font Control 子控件属性。
当 在调用 IUIFramework::InvalidateUICommand 中将 作为标志的值传递时UI_INVALIDATIONS_VALUE,框架将查询此属性。
UI_PKEY_FontProperties_ChangedProperties IUISimplePropertySet 对象的形式聚合公开,仅公开已更改的 Font Control 子控件属性。
UI_PKEY_Keytip 只能通过失效进行更新。
UI_PKEY_Enabled 支持 IUIFramework::GetUICommandPropertyIUIFramework::SetUICommandProperty

除了字体控件本身支持的属性外,功能区框架还为每个字体控件子控件定义一个 属性键 。 框架通过 IPropertyStore 接口实现公开这些属性键及其值,该接口实现定义用于管理名称和值对集合(也称为属性包)的方法。

应用程序将字体结构转换为可通过 IPropertyStore 接口方法访问的属性。 此模型强调字体控件与 Windows 图形设备接口 (GDI) 框架支持的文本堆栈组件 (LOGFONT 结构CHOOSEFONT 结构和CHARFORMAT2 结构) 之间的区别。

下表列出了各个控件及其关联的属性键。

控件 属性键 注释
字号 UI_PKEY_FontProperties_Size 当突出显示异类大小文本时,功能区框架会将 “字体大小” 控件设置为空白,将 “UI_PKEY_FontProperties_Size ”的值设置为 0。 单击“ 放大字体 ”或“ 缩小字体 ”按钮时,将调整所有突出显示的文本的大小,但会保留文本大小的相对差异。
字体系列 UI_PKEY_FontProperties_Family GDI 字体系列名称因系统区域设置而异。 因此,如果跨应用程序会话保留 UI_PKEY_FontProperties_Family 的值,则应在每个新会话上检索该值。
放大字体功能 放大缩小字体功能 UI_PKEY_FontProperties_Size 请参阅 字号
放大缩小字体功能 放大缩小字体功能 UI_PKEY_FontProperties_Size 请参阅 字号
加粗 UI_PKEY_FontProperties_Bold
斜体 UI_PKEY_FontProperties_Italic
下划线 UI_PKEY_FontProperties_Underline
删除线 UI_PKEY_FontProperties_Strikethrough
下标 UI_PKEY_FontProperties_VerticalPositioning 如果设置了 “下标 ”按钮,则不能同时设置 上标
上标 UI_PKEY_FontProperties_VerticalPositioning 如果设置了 “上标 ”按钮,则不能也设置 下标
文本突出显示颜色 UI_PKEY_FontProperties_BackgroundColorUI_PKEY_FontProperties_BackgroundColorType 提供与 DropDownColorPicker 元素的模板相同的功能HighlightColors
强烈建议应用程序仅设置初始 文本突出显示颜色 值。 在文档中重新定位光标时,应保留最后一个选定值,并且不设置该值。 这允许快速访问用户的最后一个选择,并且无需重新打开颜色选取器。
无法自定义颜色样本。
文本颜色 UI_PKEY_FontProperties_ForegroundColorUI_PKEY_FontProperties_ForegroundColorType 提供与 DropDownColorPicker 元素的模板相同的功能StandardColors
强烈建议应用程序仅设置初始 文本颜色 值。 在文档中重新定位光标时,应保留最后一个选定值,并且不设置该值。 这允许快速访问用户的最后一个选择,并且无需重新打开颜色选取器。
无法自定义颜色样本。

定义 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;
}

Windows 功能区框架控件库

FontControl 元素

字体控件属性

FontControl 示例