网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

截断过长字符串为省略号算法

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

在实际的开发当中,我们经常会遇到要字符串比显示的区域要长的情况,从而导致显示不全。最合适的方法自然是跑马灯的滚动显示,不过这个可能稍微复杂了点,并不是所有的情况下都能适用;也许最最简易的,可能就是直接将超出范围的字符串用省略号替代了。

    好像不是很难,不是么?但实际并非如此。比如,有一个字符串"你好,我们可以聊聊么?",你是决定只显示哪部分,而哪部分是被替代的呢?这个字符串所要显示的文字,如何确定?大部分菜鸟的第一反应,估计就是固定要只是显示多少个字符,超过的,就一律以省略号替代。实际上,这是不行的。如果字符全部为中文,或是全部为英文还行,如果又有中文和英文,那么由于互相字符宽度不同,显示就很死翘翘了。

  假设我默认的显示文字为九个,那么在我的平台上显示的就是这样:
  
  
  很明显看到,这两串字符的宽度完全是不同的,而下面的英文字符其实可以容纳更多。所以,以固定数目来做截取的标准,是完全不可取的。
  
  有的朋友或许对GetTextMetrics比较熟悉,想到调用该函数返回字体的平均宽度,然后再与范围宽度相除。但毕竟平均不是实际,有时候用平均值来计算,误差也是很大的。
  
  不过,微软毕竟还是微软,并没有将路给堵绝。它还给我们留了一个GetTextExtentPoint函数,用它来获取字符串所占的空间范围。
  
  在具体说这个函数之前,我们先来看一副图:
  
  
  这是字符串超出显示范围的一个情况。其中,蓝色方框的区域是显示的区域,绿色方框是应该显示的字符,而红色则是省略号占据的空间。对于我们来说,只需要知道绿色方框能包含多少个字符即可。
  
  而GetTextExtentPoint函数能够计算输入的字符串占据的空间范围,所以通过它进行运算,就能获知我们需要显示多少个字符。现在的问题是,我们如何去调用这个函数?难道先从"你"开始,依次递进,以"你"、"你好"、"你好,"、"你好,这"等等这样的方式一个一个作为形参去进行测试?不用想,这效率,肯定奇差,甚至可能成为拖慢程序的一个禁锢。
  
  所以,简单点,我们就用二分法吧。声明一个函数,它可以接收当前的hdc,显示范围的大小,以及测试的字符串,返回的是该显示范围能容纳下的字符。
  
  故此,函数实现如下:

  1. DWORD GetComfortSize(HDC hdc,DWORD dwWidth,const TSTRING &strText) 
  2.  //二分法查找 
  3.  
  4.  DWORD dwComfortSize = 0; 
  5.  DWORD dwBeginSize = 0; 
  6.  DWORD dwEndSize = strText.size(); 
  7.   
  8.  while(TRUE) 
  9.  { 
  10.   DWORD dwMiddleSize = (dwEndSize + dwBeginSize) / 2; 
  11.   if(dwMiddleSize == dwBeginSize || dwMiddleSize == dwEndSize) 
  12.   { 
  13.    //两个点之间已经没有数值可以检测,退出循环 
  14.    dwComfortSize = dwBeginSize; 
  15.    break
  16.   } 
  17.  
  18.   SIZE sizeChk = {0}; 
  19.   ::GetTextExtentPoint(hdc,strText.c_str(),dwMiddleSize,&sizeChk); 
  20.  
  21.   if(sizeChk.cx == dwWidth) 
  22.   { 
  23.    //数值刚好合适,跳出循环 
  24.    dwComfortSize = dwMiddleSize; 
  25.    break
  26.   } 
  27.   else if(static_cast<DWORD>(sizeChk.cx) > dwWidth) 
  28.   { 
  29.    //重新设置边界 
  30.    dwEndSize = dwMiddleSize; 
  31.   } 
  32.   else 
  33.   { 
  34.    //重新设置边界 
  35.    dwBeginSize = dwMiddleSize; 
  36.   } 
  37.  
  38.  } 
  39.  
  40.  return dwComfortSize; 
  41.      } 
  42.    

函数的调用其实也很简单,但我们要注意,调用前先将省略号的空间给去掉。故实际的调用代码简单如下:

  1. //获取省略号的占据范围 
  2.      static const TSTRING FLAG_ELLIPSIS = TEXT(""); 
  3.  SIZE sizeEllipsis = {0}; 
  4.      GetTextExtentPoint(hdc,FLAG_ELLIPSIS.c_str(),FLAG_ELLIPSIS.size(),&sizeEllipsis); 
  5.    
  6.      DWORD dwMaxDisp = GetComfortSize(hdc,sizeExtent.cx - sizeEllipsis.cx,strChk); 

那么,看看我们这函数的实际显示成果吧:

设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师