首先须要说明的是,我所说的字符串的长度,不是string的length,也不是string的size。我指的是显示的长度。即物理长度。

缘由:

之所以要提到这个。是由于遇到了一些问题。

再使用duilib进行开发时。发现label控件不能自适应宽度。

思考:

这显示是这个库的一个不足,可是我们能够试图去改动一下这个库。

可是本着开源的精神。也许这个库的设计初衷就是label不能自适应字符串的宽度呢?

全部仅仅有走第二条路,我们首先获得要显示字符串的宽度width值。然后把这个label的宽度设置为width。

实现:

如今的问题就是在windows上。怎样获得一个字符串的宽度呢?

这个时候一定想到了使用设备描写叙述表,HDC。

怎样获得DC以及怎样释放DC。这里就不再赘述了。之前的博客有过解说。

这个时候你又会问,我怎么确定一个字符串的显示长度呢?

对于同一个字符串。不同大小的字体。显示也是不一样的啊。

所以,我们肯定也须要用到字体。

这里有个函数:

HFONT hFont = CreateFont(27, 0, 0, 0, FW_DONTCARE, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL);

看看这个函数,參数非常多:

cHeight是字体的高度。

cWidth是字体的宽度。

cEscapement是字体的倾斜角。

cOrientation是字体的倾斜角。

cWeight是字体的粗细。

bItalic是字体是否斜体。

bUnderline是字体是否有下划线。

bStrikeOut是字体是否有删除线。

iCharSet是字体使用的字符集。

iOutPrecision是指定怎样选择合适的字体。

iClipPrecision是用来确定裁剪的精度。

iQuality是怎么样跟选择的字体相符合。

iPitchAndFamily是间距标志和属性标志。

pszFaceName是字体的名称。

函数功能:该函数创建一种有特殊性的逻辑字体,此逻辑字体能够在后面被不论什么设备选择。

函数原型:HFONT CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwltalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD

fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace)。

參数:

nHeight:指定字体的字符单元或字符的逻辑单位高度,字符的高度值(也被称为em高度)是指字符单元高度值减去内部标头值。字体映射器以例如以下方式解释nHeight指定的值。各值含义

为:

0:字体映射器转换这个值以设备单位,并和已有字体的单元高度相匹配。

0:字体映射器转换在选择匹配时用一个缺省的高度值。

<0:字体映射器转换这个值到设备单位,并将它的绝对值和已有字体的字符高度相匹配。

比較全部的高度,字体映射器选择不超过要求大小的最大字体。

此映射当字体第一次被使用时发生。

对于MM_TEXT映射方式,能够用以下的公式为一种指定了点大小的字体确定高度:

nHeight=-MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY),72)

nWidth:指定所要求字体的字符的逻辑单位的平均宽度。假设此值为0,字体映射器选择一个closest match值,closest match值是由比較当前设备的特征系数与可使用字体的数字化特征系数之差的绝对值而确定的。

nEscapement:指定移位向量和设备X轴之间的一个角度,以十分之中的一个度为单位。移位向量平行于正文行的基线。

Windows NT:当图形设备设置为GM_ADVANCED时,能够不依赖字符串的字符的定位角而指定字符串的移位角。

当图形模式被设置为GM_COMPATIBLE时,nEscapement同一时候指定移位角和定位角,能够设置nEscapement和nOrientation为同样的值。

Windows 95:nEscapement同一时候指定移位角和定位角,可设置nEscapement和nOrientation为同样的值。

nOrientation:指定每一个字符的基线和设备X轴之间的角度。

FnWeight:在0到1000之间指定字体的权值,如400表示标准体,700表示黑(粗)体,假设此值为0,则使用缺省的权值。

为方便定义。可使用例如以下值:

FW_DONTCARE:0;FW_THIN;100。FW_EXTRALIGHT;200;FW_ULTRALIGHT。200;FW_LIGHT。300;

FW_NORMAL:400;FW_REGULAR;400;FW_MEDIUM;500。FW_SEMIBOLD;600;FW_DEMIBOLD;600;

FW_BOLD:700;FW_EXTRABOLD。800。FW_ULTRABOLD;800;FW_HEAVY;900;FW_BLACK。900。

fdwItalic:假设设置为TRUE则指定斜体。

fdwUnderline:假设设置为TRUE,则指定加下划线的字全。

fdwStrikeOut:假设设置为TRUE,则strikeout指定字体。

fdwCharSet:指定字符集,下列值是提前定义的:

ANSI_CHARSET; BALTIC_CHARSET; CHINESEBIG5_CHARSET; DEFAULT_CHARSET;

EASTEUROPE_CHARSET; GB2312_CHARSET; GREEK_CHARSET; HANGUL_CHARSET; MAC_CHARSET; OEM_CHARSET; RUSSIAN_CHARSET; SHIFTJIS_CHARSET;

SYMBOL_CHARSET; TURKISH_CHARSET。

韩国Windows:JOHAB_CHARSET。

中东地区Windows:HEBREW_CHARSSET; ARABIC_CHARSET

泰国Windows:THAI_CHARSET

OEM_CHARSET指定的字符集与操作系统有关。

能够使用DEFAULT_CHARSET值来同意字体的名字和大小来充分描写叙述逻辑字体。假设指定的字体名不存在。不论什么字符集的字体都能够替代指定的字体,所以应该小心地用DEFAULT_CHARSET来避免不期望的结果出现。

操作系统中存在其它字符集的字体。假设一个应用程序用一种未知字符集的字体,则应用程序不会试图去翻译或解释用那种字体写出来的字符串。

在字体映射过程中此參数非常重要。

为确保获得一致的结果,指定一个特殊的字符集。

假设在lpszFace參数中指定了一个字体名,确定fdwCharSet值与由lpszFace指定的字体字符集是否匹配。

fdwOutputPrecision:指定输出精度,输出精度义输出与要求的字体高度、宽度、字符定位、移位、字符间距和字符类型的匹配程序。它可取下列值之中的一个:

OUT_CHARACTER_PRECIS;未用。

OUT_DEFAULT_PRECIS:指定缺省的字体映射器状态。

OUT_DEVICE_PRECIS:指示字体映射器在当系统里有多种字体使用同一个字体使用同一个名字时选择一种设备字体。

OUT_OUTLINE_PRCIS:在Windows NT中此值指示字体映射器从TrueType和其它基于边框的字体中选择。

OUT_RASTER_PRECIS:指示字体映射器在当系统里有多种字体使用同一个名字时选择一种光栅字体。

OUT_STRING_PRECIS:此值没有被字全映射器使用,可是当扫描字体被列举时作为返回值。

OUT_STROKE_PRECIS:在Windows NT中此值没有被字体映射器使用,可是当TrueType字体、其它基于边框的字体和向量字体被列举时,作为返回值。

Windows 95:此值没有被字体映射器使用。可是当TrueType字体或向量字体被列举时。作为返回值。

OUT_TT_ONLY_PRECIS:指示字体映射器仅从TrueType字体中选择,假设系统中没有安装TrueType字体,则字体映射返回缺省状态。、

OUT_TT_PRECIS:指示字体映射器在当系统里有多种同名的字体时选择一种TrueType字体。

当操作系统含有多种与指定名字同名的字体时,应用程序能够使用OUT_DEVICE_PRECIS,OUT_RASTER_PRECIS和OUT_TT_PRECIS值来控制字体映射器怎样选择一种字体。比如。假设操作系统含有名字Symbol的光栅和TrueType两种字体,指定OUT_TT_PRECIS使字体映射器选择TrueType方式。指定OUT_TT_ONLY_PRECIS使字体映射器选择一种TrueType字体,虽然这会给TrueType字体换一个名字。

fdwClipPrecision。指定裁剪精度。裁剪精度定义怎样裁剪部分超出裁剪区的字符,它可取一个或多个下列值:

CLIP_DEFAULT_PRECIS:指定缺省裁剪状态。

CLIP_CHARACTER_PRECIS:未用。

CLIP_STROKE_PRECIS:未被字体映射器使用。可是当光栅字体、向量字体或TrueType字体被列举时作为返回值。

在Windows环境下,为保证兼容性,当列举字体时这个值总被返回。

CLIP_MASK:未用。CLIP_EMBEDDED:要使用嵌入式仅仅读字体必须使用此标志。

CLIP_LH_ANGLES:当此值被使用时。全部字体的旋转依赖于坐标系统的定位是朝左的还是朝右的。

假设未使用此值,设备字体总是逆时针方向旋转,但其它字体的旋转依赖于坐标系统的定向。

要得到很多其它关于坐标系统定向的信息,參见參数orientation。

CLIP_TT_ALWAYS:未用。

fdwQuality:指向输出质量,输出质量定义GDI怎样细致地将逻辑字体属性与实际物理字体属性相匹配。它可取下列值之中的一个:

DEFAULT_QUALITY:字体的外观不重要。

DRAFT_QUALITY:字体外观的重要性次于使用PROOF_QUALITY时,对GDI光栅字体,缩放比例是活动的,这意味着多种字体大小可供选择,但质量可能不高,假设有必要。粗体、斜体、下划线、strikeout字体可被综合起来使用。

PROOF_QUALITY:字符质量比精确匹配逻辑字体字体属性更重要。对GDI扫描字体,缩放比例是活动的。并选择最接近的大小。虽然当使用PROOF_QUALITY时,选择字体大小并不完

全匹配,但字体的质量非常高,并没有外观上的变形。假设有必要,粗体、斜体、下划线、strikeout字体可被综合起来使用。

fdwPitchAndFamily:指定字体间距和字体族,低端二位指定字体的字符间距。它可取下列值之中的一个:

DEFAULT_PITCH。FIXED_PITCH; VARIABLE_PITCH

高端四位指定字体族。可取下列值之中的一个:

FF_DECORATIVE:新鲜的字体。如老式英语(Old English)。

FF_DONTCARE:不关心或不知道。

FF_MDERN:笔划宽度固定的字体,有或者无衬线。如Pica、Elite和Courier New。

FF_ROMAN:笔划宽度变动的字体,有衬线。

如MS Serif。

FF_SCRIPT:设计成看上去象手写体的字体。如Script和Cursive。

FF_SWISS:笔划宽度变动的字体,无斜线。如MS Sans Serif。

应用程序能够用运算符OR将字符间距和字体族组合起来给fdwPitchAndFamily赋值。

字体族描写叙述一种字体的普通外观,当全部的精确字样都不能使用时。可用它们来指定字体。

lpszface:指向指定字体的字样名的、以/0结束的字符串指针,字符串的长度不能超过32个字符(包括字符/0)。函数EnumFontFamilies可用来列举全部当前可用字体的字样名。

假设lpszFace为NULL或指向一个空串,GDI使用能匹配其它属性的第一种字体。

返回值:假设函数调用成功,返回值是一种逻辑字体句柄。假设函数调用失败。返回值为NULL。

Windows NT:若想获得很多其它错误信息。请调用GetLastError函数。

备注:当一种字体不再使用时。可用DeleteObject来删除。

为保护那些提供字体给Windows和Windows NT的卖主的版权。基于Win32的应用程序总是列出所选择字体的准确名字。由于不同的系统会使用不同的字体。不要觉得所选择字体就是要

求的字体。比如,假设要求名叫Palatino的字体。但系统没提供那样一种字体。则字体映射器将会以一种不同名但有类似属性的字体取而代之。

系统总是将用户选择的字体名报告出来。

接下来就是利用SelectObject()函数。选入hdc和字体,这里SelectObject函数也不做过多介绍。

以下就要開始总体了。我们有两种方法。

1使用函数GetTextExtentPoint32

函数功能:该函数计算指定的正文字符串的高度和宽度。

函数原型:BOOL GetTextExtentPoint32(HDC hdc, LPCTSTR lpString, int cbString, LPSIZE lpSize)。

參数:

hdc:设备环境句柄。

lpString:指向正文字符串的指针。此字符串不必以\0结束,由于cbString指定了字符串的长度。

cbString:指向字符串中的字符数。

lpSize:指向SIZE结构的指针,该结构中字符串的尺寸将被返回。

返回值:假设函数调用成功,返回值是非零值。假设函数调用失败。返回值是0。

2使用函数DrawText

函数原型

int DrawText(

HDC hDC, // 设备描写叙述表句柄

LPCTSTR lpString, // 将要绘制的字符串

int nCount, // 字符串的长度

LPRECT lpRect, // 指向矩形结构RECT的指针

UINT uFormat // 正文的绘制选项

);

參数

hdc:

[输入]设备环境句柄。

lpString:

[输入]指向将被写入的字符串的指针。假设參数nCount是-1,则字符串必须是以\0结束的。 假设uFormat包括DT_MODIFYSTRING,则函数可为此字符串添加4个字符,存放字符串的缓冲区必须足够大,能容纳附加的字符。

nCount:

[输入]指向字符串中的字符数。假设nCount为-1,则lpString指向的字符串被觉得是以\0结束的,DrawText会自己主动计算字符数。

lpRect:

[输入/输出]指向结构RECT的指针,当中包括文本将被置于当中的矩形的信息(按逻辑坐标)。

uFormat:

[输入]指定格式化文本的方法。它能够下列值的随意组合。各值描写叙述例如以下:

DT_CALCRECT:这个參数比較重要,能够使DrawText函数计算出输出文本的尺寸。假设输出文本有多行,DrawText函数使用lpRect定义的矩形的宽度,并扩展矩形的底部以容纳输出文本的最后一行。假设输出文本仅仅有一行,则DrawText函数改变矩形的右边界。以容纳下正文行的最后一个字符。出现上述不论什么一种情况。DrawText函数将返回格式化文本的高度。而不是绘制文本。

DT_CENTER:指定文本水平居中显示。

DT_VCENTER:指定文本垂直居中显示。

该标记仅仅在单行文本输出时有效。所以它必须与DT_SINGLELINE结合使用。

DT_SINGLELINE:单行显示文本。回车和换行符都不断行。

最后,献上代码:

int CalWstringWidth(const std::wstring & name)
{
HDC hDC = ::GetDC(NULL);
HFONT hFont = CreateFont(27, 0, 0, 0, FW_DONTCARE, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL);
SelectObject(hDC, hFont);
LPCTSTR string = name.c_str();
SIZE size = { 0 };
GetTextExtentPoint32(hDC, string, _tcslen(string), &size);
RECT rect = { 0 };
//::DrawText(hDC, string, _tcslen(string), &rect, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
DeleteDC(hDC);
//int str_width = std::abs(rect.right - rect.left);
return size.cx;
}

windowsclient开发--怎样測量一个字符串显示的物理长度的更多相关文章

  1. 【LeetCode】1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 Check If a String Contains All Binary Codes of Size K

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计长度为 K 的子串个数 日期 题目地址:https ...

  2. windowsclient开发--为你clientsign一个签名证书

    郑重声明:该方法自娱自乐,尽管写入了签名,可是在微软系统免签证书不是合格的. 什么是签名? 话不多说,上图(没图说个xx): 微信windowsclient.exe安装文件: 再看还有一个.exe文件 ...

  3. Android如何用一个TextView显示不同颜色得字符

    最近做一个项目,需要一个字符串显示不同的颜色.当时直接想到的就是用多个TextView来拼接,但是如果字符数量多的话,这样写是非常麻烦得.而且还要增加很多控件. 后来发现一个非常方便得方法.直接看代码 ...

  4. C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素

    转自原文 C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素 有时候,我们要对图层上的地物进行有选择性的显示,以此来满足实际的功能要求. 按下面介绍的方法可轻松实现图层属性 ...

  5. 设在起始地址为STRING的存储空间存放了一个字符串(该串已存放在内存中,无需输入,且串长不超过99),统计字符串中字符“A”的个数,并将结果显示在屏幕上。

    问题 设在起始地址为STRING的存储空间存放了一个字符串(该串已存放在内存中,无需输入,且串长不超过99),统计字符串中字符"A"的个数,并将结果显示在屏幕上. 代码 data ...

  6. 从键盘输入一个字符串(长度不超过30),统计字符串中非数字的个数,并将统计的结果显示在屏幕上,用EXE格式实现。

    问题 从键盘输入一个字符串(长度不超过30),统计字符串中非数字的个数,并将统计的结果显示在屏幕上,用EXE格式实现. 源程序 data segment hintinput db "plea ...

  7. C语言考题:输入一个字符串,将此字符串中特定的字符删去后, 显示新的字符串,要求用函数来完成删去字符的操作。

    #include <stdio.h> #include <string.h> /*此题只需要删除单个字符,比较简单.相信大家也能做出来的.我这个也是可以实现的.只是加了两个判断 ...

  8. 开发你的第一个NCS(Zephyr)应用程序

    Nordic有2套并存的SDK:老的nRF5 SDK和新的NCS SDK,两套SDK相互独立,大家选择其中一套进行开发即可.一般而言,如果你选择的芯片是nRF51或者nRF52系列,那么推荐使用nRF ...

  9. 【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词

    一. 字符串 API 1. NSString 用法简介 (1) NSString API 介绍 NSString 功能 : -- 创建字符串 : 使用 init 开头的实例方法, 也可以使用 Stri ...

随机推荐

  1. [BZOJ2109][NOI2010]航空管制(贪心+拓扑)

    2109: [Noi2010]Plane 航空管制 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1227  Solved: 510[Submit][ ...

  2. JZYZOJ1390【noi2001】炮兵阵地 状压DP

    http://172.20.6.3/Problem_Show.asp?id=1390 需要储存该行和上一行两个状态.通过观察规则可以发现条件允许的状态很少(相邻两个至少空两格),据此可以减少状态数量, ...

  3. MySQL v5.7.18 版本解压安装

    下载MySQL https://dev.mysql.com/downloads/mysql/5.1.html#downloads 个人机子是64位的,所以选择下载:Windows (x86, 64-b ...

  4. Java字节码文件结构---概述

    一.Class文件的结构概述: 是一连串的字节流(以自节为基本单位划分),里面包含的数据项按照固定的次序依次排列组成Class文件,文件内部不含分割符 当数据项的长度大于1B时候,按照高位在前的方式存 ...

  5. Codeforces Round #345 (Div. 2) D. Image Preview 暴力 二分

    D. Image Preview 题目连接: http://www.codeforces.com/contest/651/problem/D Description Vasya's telephone ...

  6. Codeforces Gym 100269F Flight Boarding Optimization 树状数组维护dp

    Flight Boarding Optimization 题目连接: http://codeforces.com/gym/100269/attachments Description Peter is ...

  7. (Mark=转)ehcache memcache redis

    Ehcache 在java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS中取出来的高花费.高延迟采取的一种缓存方案.正因为Ehcache具有健壮性(基于java开发).被认证(具有apa ...

  8. NHibernate官方文档中文版——批量插入(Batch inserts)

    A naive approach t7o inserting 100 000 rows in the database using NHibernate might look like this: 一 ...

  9. openGl 基础

    最近由于手机项目中需要用到OpenGL ES的知识,所以这段时间正在研究OpenGL的相关知识.因为OpenGL ES是OpenGL的剪裁版本,所以我直接从OpenGL入手,然后再去看OpenGL E ...

  10. 靠谱助手 http://www.kpzs.com/

    靠谱助手 http://www.kpzs.com/ 靠谱助手是于2013年5月18日推出的一个专为第三方智能安卓引擎提供管理的免费应用程序,是国内最完美的PC端管理软件. 安卓引擎支持微信.陌陌等日常 ...