找回密码
 加入
搜索
查看: 11254|回复: 28

[系统综合] 一个困扰已久的问题:如何计算文本宽度?

 火.. [复制链接]
发表于 2016-4-15 19:19:33 | 显示全部楼层 |阅读模式
在类似于table、grid、redit之类的控件中常常涉及到文本换行,大多可以用控件自身的wrap自动换行方法,但有时需要计算文本总宽度,然后让文本按指定宽度自动折行。因为涉及到字体、字符宽度、字符间距、屏幕分辨率等等元素,需要很懂API才行。小白如我常常对api望而生畏,不明觉厉。度娘之,多是C/C++、.net语言等之类的有所涉及,也是一头雾水。最近又想起这个问题,所以发此贴,希望路过的万能的ACN大神们顺手给破了吧

记事本比较通用,就拿记事本来测试

如何达到下图效果:

这是样本:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2016-4-15 20:27:40 | 显示全部楼层
什么意思,让记事本自动换行?
 楼主| 发表于 2016-4-15 21:58:58 | 显示全部楼层
本帖最后由 cashiba 于 2016-4-15 22:07 编辑
什么意思,让记事本自动换行?
haijie1223 发表于 2016-4-15 20:27
不是记事本本身的自动换行,而是想实现 按若干个字符宽度的文本 来换行,最主要的就是如何获得单个字符宽度(包括英文字符、标点符号等)...不知道我的意思表述得清不清楚
换个简单的说法,
假定记事本是最大化,宽度固定等于屏幕宽度。
以前呢,文本到记事本右边缘就自动换行;
现在呢,希望文本到记事本中间(也就是半屏幕宽度)时就自动换行
如何实现呢?
发表于 2016-4-15 22:09:16 | 显示全部楼层
哟嚯哦 这个厉害了 需要高手来帮忙了
呵呵 我等只能帮顶 顺便看看学习一下
发表于 2016-4-15 22:28:15 | 显示全部楼层
回复 3# cashiba


    答非所问的感觉,谁看懂楼主的意思了?楼主是要在记事本换行吗?还是在word换行?还是在dos下换行?还是要在美国换行?还是在日本换行?
 楼主| 发表于 2016-4-15 22:44:26 | 显示全部楼层
本帖最后由 cashiba 于 2016-4-15 22:47 编辑
回复  cashiba


    答非所问的感觉,谁看懂楼主的意思了?楼主是要在记事本换行吗?还是在word换行? ...
haijie1223 发表于 2016-4-15 22:28
版主不用冷嘲热讽吧?
记事本换行,还是word换行,还是表格里换行....都可以,只是以记事本为例子罢了。就是想知道某分辨率下某种字体的字符怎么计算其字符宽度(不是占用的位宽或字节长度)而已。
或者给定的宽度能容纳下多少个字符。我觉得自己已经表述清楚了.....
发表于 2016-4-15 23:24:38 | 显示全部楼层
回复 6# cashiba


    既然认为我在冷嘲热讽,那就当我没回复过,帮你顶帖了。
发表于 2016-4-16 10:44:54 | 显示全部楼层
提供一个思路。
首先获取得记事本的宽度A,宽度A/2就是换行的位置;
宽度A/2可以使用定时监控光标的在记事本里的坐标,横坐标>=A/2时换行。

以上思路仅适用记事本宽度一定时才有效。如果多行文本输入后,此时拉大或拉小记事本宽度,再实现换行,这种情况暂未有思路。
发表于 2016-4-16 11:38:19 | 显示全部楼层
回复 6# cashiba

不同大小字体在不同分辨率下所容纳字符数是一个未知变量,
发表于 2016-4-16 11:51:53 | 显示全部楼层
#include <WinAPI.au3>
_WinAPI_GetTextExtentPoint32($hDC, $sText)
 楼主| 发表于 2016-4-16 12:20:11 | 显示全部楼层
本帖最后由 cashiba 于 2016-4-16 12:28 编辑
提供一个思路。
首先获取得记事本的宽度A,宽度A/2就是换行的位置;
宽度A/2可以使用定时监控光标的在记事 ...
chamlien 发表于 2016-4-16 10:44
这种方法也想到过,只是觉得通用性不强。以前曾经在网络上搜到一段代码,可惜再找不到了。好像有几个文本或字符串API函数组合在一起,能够根据当前字体、分辨率等自动计算出字符宽度和高度。记得其中有个 getFontMetrics 什么的。
AU3通过dllcall引用API的方法刚刚知道,一时还没熟悉,所以不知道在AU3里是怎么引用API来计算字符宽和高的。故有此一问。
之所以要计算字符宽或高,主要是因为,有时数千字的文本要分段输入一个文本框里,每段之前有个固定的标题或引子截断,需要按标题或引子定位输入。或者文字排版时也需要精确计算字符宽高。通常的记事本或word自动换行都是靠近边框时才触发换行,不像是按字符宽度来折行的。
 楼主| 发表于 2016-4-16 12:34:11 | 显示全部楼层
本帖最后由 cashiba 于 2016-4-16 12:37 编辑

下面是网上搜到的一些
 如何获得一个字符的宽度和高度?
  
   可以利用FontMetrics对象所提供的getHeight(), charWidth()或者是stringWidth()
   方法来获得显示某个字符或者是字符串所需要的高度和宽度。例如,在Graphics g中:
  
   String Info = "Test String".
   FontMetrics metrics = getFontMetrics(g.getFont());
   int height = metrics.getHeight();
   int width = metrics.stringWidth(Info);
  
   关于这些方法的具体情况,请参考FontMetrics类的API文档。
另一个,flash脚本中
  经过自己的一番研究,可以从flex的as3帮助文档中找到答案,flash.text.TextLineMetrics类负责测量字符串所占的实际宽度。   

有关详细信息请自己参考API.
measureText(字符串)方法返回TextLineMetrics的实例,TextLineMetrics类的width返回字符串所占的实际宽度,Flex的显示组件一般都继承自UIComponent组件,UIComponent类含有measureText方法,因此可以直接使用this.measureText(字符串).
引自:http://yunzhongxia.iteye.com/blog/856982

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2016-4-16 12:48:43 | 显示全部楼层
水木子 发表于 2016-4-16 11:51
谢谢水版!原来AU3里已经有这样的自定义函数了
_WinAPI_GetTextExtentPoint32 (设备环境标识,文本字符串)
Func GetStringDimensions($hWnd, $sText)
    Local $hDC = _WinAPI_GetDC($hWnd) ; 获取当前窗口的设备环境句柄.
    Local $hFont = _SendMessage($hWnd, $WM_GETFONT) ; 检索控件目前正在绘制文本的字体.
    Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont) ; 选择设备环境对象.
    Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText) ; 检索字符串的高度和宽度.

    _WinAPI_SelectObject($hDC, $hSelectObject)
    _WinAPI_ReleaseDC($hWnd, $hDC) ; 释放设备环境.
    Local $aReturn[2] = [DllStructGetData($tSIZE, 1), DllStructGetData($tSIZE, 2)] ; 设置字符串宽度和高度的数组.
    Return $aReturn
EndFunc   ;==>GetStringDimensions
不懂API的看起来很高大上似的,怎么用还得好好学学....以前用的那个VB还是啥语言写的函数忘了,代码比较多,但是用起来很不错,估计原理都是一样的.....
再次感谢
 楼主| 发表于 2016-4-16 12:55:05 | 显示全部楼层
回复  cashiba
不同大小字体在不同分辨率下所容纳字符数是一个未知变量,
fuldho 发表于 2016-4-16 11:38
所以希望有一个通用性比较强的函数,只要给定一段文本,就能根据当前编辑控件宽度计算出该文本可以折多少行,然后就可以任意按行数分段截取文本,而不用考虑分辨率、字体、中西文、标点符号之类的具体设定。
 楼主| 发表于 2016-4-16 13:00:58 | 显示全部楼层
学会用这个自定义函数后,再向大家汇报心得,感谢各位大侠和大神路过并驻足提点!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-22 16:22 , Processed in 0.251774 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表