这是字符串超出显示范围的一个情况。其中,蓝色方框的区域是显示的区域,绿色方框是应该显示的字符,而红色则是省略号占据的空间。对于我们来说,只需要知道绿色方框能包含多少个字符即可。
而GetTextExtentPoint函数能够计算输入的字符串占据的空间范围,所以通过它进行运算,就能获知我们需要显示多少个字符。现在的问题是,我们如何去调用这个函数?难道先从"你"开始,依次递进,以"你"、"你好"、"你好,"、"你好,这"等等这样的方式一个一个作为形参去进行测试?不用想,这效率,肯定奇差,甚至可能成为拖慢程序的一个禁锢。
所以,简单点,我们就用二分法吧。声明一个函数,它可以接收当前的hdc,显示范围的大小,以及测试的字符串,返回的是该显示范围能容纳下的字符。
故此,函数实现如下:
DWORD GetComfortSize(HDC hdc,DWORD dwWidth,const TSTRING &strText)
{
//二分法查找
DWORD dwComfortSize = 0;
DWORD dwBeginSize = 0;
DWORD dwEndSize = strText.size();
while(TRUE)
{
DWORD dwMiddleSize = (dwEndSize + dwBeginSize) / 2;
if(dwMiddleSize == dwBeginSize || dwMiddleSize == dwEndSize)
{
//两个点之间已经没有数值可以检测,退出循环
dwComfortSize = dwBeginSize;
break;
}
SIZE sizeChk = {0};
::GetTextExtentPoint(hdc,strText.c_str(),dwMiddleSize,&sizeChk);
if(sizeChk.cx == dwWidth)
{
//数值刚好合适,跳出循环
dwComfortSize = dwMiddleSize;
break;
}
else if(static_cast<DWORD>(sizeChk.cx) > dwWidth)
{
//重新设置边界
dwEndSize = dwMiddleSize;
}
else
{
//重新设置边界
dwBeginSize = dwMiddleSize;
}
}
return dwComfortSize;
}
-
- static const TSTRING FLAG_ELLIPSIS = TEXT("...");
- SIZE sizeEllipsis = {0};
- GetTextExtentPoint(hdc,FLAG_ELLIPSIS.c_str(),FLAG_ELLIPSIS.size(),&sizeEllipsis);
-
- DWORD dwMaxDisp = GetComfortSize(hdc,sizeExtent.cx - sizeEllipsis.cx,strChk);
|