GetCharacterPlacementW 函数 (wingdi.h)

GetCharacterPlacement 函数检索有关字符串的信息,例如字符宽度、插入符号定位、字符串内排序和字形呈现。 返回的信息类型取决于 dwFlags 参数,并且基于指定显示上下文中当前选定的字体。 该函数将信息复制到指定的 GCP_RESULTS 结构或结构指定的一个或多个数组。

尽管此函数曾经足以处理字符串,但需要使用越来越多的语言和脚本使它过时。 它已被 Uniscribe 模块的功能取代。 有关详细信息,请参阅 Uniscribe

建议应用程序使用 GetFontLanguageInfo 函数来确定GCP_DIACRITIC、GCP_DBCS、GCP_USEKERNING、GCP_LIGATE、GCP_REORDER、GCP_GLYPHSHAPE和GCP_KASHIDA值是否对当前所选字体有效。 如果无效,GetCharacterPlacement 将忽略该值。

GCP_NODIACRITICS值不再定义,不应使用。

语法

DWORD GetCharacterPlacementW(
  [in]      HDC            hdc,
  [in]      LPCWSTR        lpString,
  [in]      int            nCount,
  [in]      int            nMexExtent,
  [in, out] LPGCP_RESULTSW lpResults,
  [in]      DWORD          dwFlags
);

参数

[in] hdc

设备上下文的句柄。

[in] lpString

指向要处理的字符串的指针。 该字符串不需要为零终止,因为 nCount 指定字符串的长度。

[in] nCount

lpString指向的字符串 长度。

[in] nMexExtent

将字符串处理到的最大范围(以逻辑单元为单位)。 如果已处理,则会忽略超出此范围的字符。 任何必需的排序或字形数组的计算仅适用于包含的字符。 仅当在 dwFlags 参数中指定了GCP_MAXEXTENT值时,才使用此参数。 当函数处理输入字符串时,仅当总盘区尚未超过最大值时,才会将每个字符及其区添加到输出、盘区和其他数组中。 达到限制后,处理将停止。

[in, out] lpResults

指向接收函数结果的 GCP_RESULTS 结构的指针。

[in] dwFlags

指定如何将字符串处理到所需的数组中。 此参数可以是以下一个或多个值。

价值 意义
GCP_CLASSIN
指定 lpClass 数组包含字符的预设分类。 分类可能与输出时相同。 如果字符的特定分类未知,则必须将数组中的相应位置设置为零。 有关分类的详细信息,请参阅GCP_RESULTS。 仅当 GetFontLanguageInfo 返回GCP_REORDER标志时,此功能才有用。
GCP_DIACRITIC
确定如何处理字符串中的音调符号。 如果未设置此值,则音调符号将被视为零宽度字符。 例如,希伯来语字符串可能包含音调符号,但你可能不想显示它们。

使用 GetFontLanguageInfo 来确定字体是否支持音调符号。 如果这样做,可以根据应用程序的需求,在调用 GetCharacterPlacement中使用或不使用GCP_DIACRITIC标志。

GCP_DISPLAYZWG
对于需要重新排序或不同的字形形状的语言,具体取决于单词中字符的位置,不可显示字符通常显示在代码页中。 例如,在希伯来语代码页中,有左To-Right 和向右To-Left 标记,以帮助确定输出字符串中字符的最终位置。 通常不会显示这些值,并且会从 lpGlyphslpDx 数组中删除。 可以使用GCP_DISPLAYZWG标志来显示这些字符。
GCP_GLYPHSHAPE
指定字符串中的某些或所有字符将使用当前代码页当前所选字体中定义的标准形状以外的形状来显示。 某些语言(如阿拉伯语)不支持创建字形,除非指定了此值。 一般情况下,如果 GetFontLanguageInfo 返回字符串的此值,则此值必须与 getCharacterPlacement一起使用。
GCP_JUSTIFY
调整 lpDx 数组中的盘区,使字符串长度与 nMaxExtent 相同。 GCP_JUSTIFY只能与GCP_MAXEXTENT结合使用。
GCP_KASHIDA
使用 Kashidas 以及调整后的盘区来修改字符串的长度,使其等于 nMaxExtent指定的值。 在 lpDx 数组中,Kashida 由负对齐索引指示。 GCP_KASHIDA只能与GCP_JUSTIFY结合使用,并且仅当字体(和语言)支持 Kashidas 时才使用。 使用 GetFontLanguageInfo 来确定当前字体是否支持 Kashidas。

使用 Kashidas 证明字符串的合理性可能会导致所需的字形数大于输入字符串中的字符数。 因此,使用 Kashidas 时,应用程序不能假定将数组设置为输入字符串的大小将足够。 (可能的最大可能为 dxPageWidth/dxAveCharWidth,其中 dxPageWidth 是文档的宽度,dxAveCharWidth 是从 GetTextMetrics 调用返回的平均字符宽度)。

请注意,仅仅因为 GetFontLanguageInfo 返回GCP_KASHIDA标志并不意味着它必须在调用 getCharacterPlacement中使用,只是选项可用。

GCP_LIGATE
无论字符在何处都使用连字。 出现连字,其中一个字形用于两个或多个字符。 例如,字母 a 和 e 可以对 ?进行诉讼。 但是,若要使用它,语言支持和字体必须支持所需的字形(本示例默认不会用英语处理)。

使用 GetFontLanguageInfo 来确定当前字体是否支持连字。 如果这样做并且需要对要进行诉讼的字符数进行指定最大值,请设置 lpGlyphs 数组的第一个元素中的数字。 如果需要正常连线,请将此值设置为零。 如果未指定GCP_LIGATE,则不会进行连字。 有关详细信息,请参阅GCP_RESULTS。

如果字符集通常需要GCP_REORDER值,但未指定,则输出将毫无意义,除非传入的字符串已采用视觉顺序(也就是说,在一次调用 GetCharacterPlacement 中放入 lpGcpResults->lpOutString 的结果是第二次调用的输入字符串)。

请注意,仅仅因为 GetFontLanguageInfo 返回GCP_LIGATE标志并不意味着它必须在调用 getCharacterPlacement中使用,只是该选项可用。

GCP_MAXEXTENT
仅当生成的盘区(以逻辑单元为单位)不会超过 nMaxExtent 参数指定的值时,字符串的计算区。
GCP_NEUTRALOVERRIDE
仅某些语言。 重写中性对象的正常处理,并将其视为与字符串读取顺序匹配的强字符。 仅适用于GCP_REORDER标志。
GCP_NUMERICOVERRIDE
仅某些语言。 重写数字的正常处理,并将其视为与字符串读取顺序匹配的强字符。 仅适用于GCP_REORDER标志。
GCP_NUMERICSLATIN
仅阿拉伯语/泰文。 对数字使用标准拉丁文字形并重写系统默认值。 若要确定此选项是否在字体语言中可用,请使用 GetStringTypeEx 查看该语言是否支持多个数字格式。
GCP_NUMERICSLOCAL
仅阿拉伯语/泰文。 对数字字符使用本地字形并替代系统默认值。 若要确定此选项是否在字体语言中可用,请使用 GetStringTypeEx 查看该语言是否支持多个数字格式。
GCP_REORDER
对字符串重新排序。 用于非 SBCS 和从左到右阅读顺序的语言。 如果未指定此值,则假定字符串已按显示顺序排列。

如果为 Semitic 语言设置了此标志,并且使用了 lpClass 数组,则数组的前两个元素用于指定超出字符串边界的读取顺序。 GCP_CLASS_PREBOUNDRTL和GCP_CLASS_PREBOUNDLTR可用于设置订单。 如果不需要预设顺序,请将值设置为零。 如果设置了 GCPCLASSIN 标志,则可以将这些值与其他值组合在一起。

如果未指定GCP_REORDER值,则会将 lpString 参数设置为视觉排序,用于使用此值的语言,并忽略 lpOutStringlpOrder 字段。

使用 GetFontLanguageInfo 来确定当前字体是否支持重新排序。

GCP_SYMSWAPOFF
仅半语言。 指定不重置可交换字符。 例如,在从右到左的字符串中,“(”和“)”不会反转。
GCP_USEKERNING
创建宽度数组时,在字体中使用字距对(如果有)。 使用 GetFontLanguageInfo 来确定当前字体是否支持字距对。

请注意,仅仅因为 GetFontLanguageInfo 返回GCP_USEKERNING标志并不意味着它必须在调用 getCharacterPlacement中使用,只是该选项可用。 大多数 TrueType 字体都有字距表,但不必使用它。

 

建议应用程序使用 GetFontLanguageInfo 函数来确定GCP_DIACRITIC、GCP_DBCS、GCP_USEKERNING、GCP_LIGATE、GCP_REORDER、GCP_GLYPHSHAPE和GCP_KASHIDA值是否对当前所选字体有效。 如果无效,GetCharacterPlacement 将忽略该值。

GCP_NODIACRITICS值不再定义,不应使用。

返回值

如果函数成功,则返回值为逻辑单元中字符串的宽度和高度。 宽度为低序单词,高度为高序单词。

如果函数失败,则返回值为零。

言论

GetCharacterPlacement 可确保应用程序能够正确处理文本,而不考虑可用的国际设置和字体类型。 应用程序在使用 ExtTextOut 函数之前使用此函数,并代替 GetTextExtentPoint32 函数(偶尔代替 GetCharWidth32GetCharABCWidths 函数)。

使用 GetCharacterPlacement 检索字符间距和索引数组并非总是必要的,除非需要对齐或刻度。 对于非拉丁文字体,应用程序可以使用 GetCharacterPlacement调用 extTextOut之前使用 GetCharacterPlacement 来检索字符间距和索引数组,从而提高 ExtTextOut 函数呈现文本的速度。 当重复呈现相同的文本或使用字符间间距定位插入点时,这尤其有用。 如果在 调用 extTextOut中使用 lpGlyphs 输出数组,则必须设置ETO_GLYPH_INDEX标志。

GetCharacterPlacement 检查 lpOrderlpDXlpCaretPos1lpOutStringlpGlyphsGCP_RESULTS 结构的成员,如果这些成员未设置为 NULL,则填充相应的数组。 如果 GetCharacterPlacement 无法填充数组,则将相应的成员设置为 NULL。 为了确保检索有效信息,应用程序负责在调用函数之前将成员设置为有效地址,并在调用后检查成员的值。 如果指定了GCP_JUSTIFY或GCP_USEKERNING值,则 lpDX 和/或 lpCaretPos 成员必须具有有效的地址。

请注意,GCP_RESULTS.lpGlyphs 中返回的字形索引特定于设备上下文中的当前字体,并且仅当该字体保持选中状态时,才应该用于在设备上下文中绘制文本。

计算理由时,如果字符串中的尾随字符为空格,函数将减少字符串的长度,并在计算理由之前删除空格。 如果数组仅包含空格,该函数将返回错误。

ExtTextOut 需要 DBCS 字符串的每个字节 lpDX 条目,而 GetCharacterPlacement 为每个字形分配 lpDX 条目。 若要在使用此函数组合时更正此不匹配,请使用 GetGlyphIndices,或展开 lpDX 数组,该数组的宽度为 DBCS 字节对的相应第二个字节的零宽度条目。

如果逻辑宽度小于输入字符串中前导字符的宽度,GCP_RESULTS.nMaxFit 返回错误值。 对于这种情况,请为字形索引和 lpDX 数组调用 GetCharacterPlacement。 然后使用 lpDX 数组使用每个字符的前进宽度执行盘区计算,其中 nMaxFit 是字形索引前进宽度小于前导字符宽度的字符数。

注意

wingdi.h 标头将 GetCharacterPlacement 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的 约定。

要求

要求 价值
最低支持的客户端 Windows 2000 Professional [仅限桌面应用]
支持的最低服务器 Windows 2000 Server [仅限桌面应用]
目标平台 窗户
标头 wingdi.h (包括 Windows.h)
Gdi32.lib
DLL Gdi32.dll

另请参阅

ExtTextOut

字体和文本功能

字体和文本概述

GCP_RESULTS

GetCharABCWidths

GetCharWidth32

GetFontLanguageInfo

GetStringTypeEx

GetTextExtentPoint32

GetTextMetrics