最近刚好做了一个文本滚动的功能,怕忘记,就先记下来了。
当你需要把一大段文本显示在一个固定的区域的时候,就需要实现滚动,才能将文本全部显示出来。首先,我们需要计算出一次性画出文本所需要的区域大小,怎么样计算呢?我们要用到一个win32 api
BOOL GetTextExtentPoint( HDC hdc, LPCTSTR lpString, int cbString, LPSIZE lpSize );
那我们开始写代码,
SIZE size;
GetTextExtentPoint( hdc, string,lstrlen( string ),&size);
size返回的是文本string 在hdc上显示的尺寸,size.cx是长度,size.cy是高度,这里的话,高度其实就是一个字符显示在hdc上的高度。
我的文本滚动的主要实现是,先将所有的文本全部画进一个内存DC,然后再设置一个timer定时刷新需要显示文本的区域,再将内存DC中的文本一点点画到目标hdc上。
关键在于创建的内存DC的大小,这里就要用到了刚刚得到的size 结构体。
比如你需要将文本画到hdc上的一个rect里,由于我实现的是向上滚动,所以内存DC的宽度就是rect.right-rect.left,下面就是计算高度,下面是代码,
int nTextLine = size.cx/( rect.right-rect.left );// 这里是计算相对于rect的宽度,文本一共需要多少行,因为文本显示到边缘处,是要换行的。
不过不要忘记,除了这种情况会换行,文本里面还有很多\n,也是换行,这个行数也是要计算上,
int iCountLine = 0;
TCHAR *pFind = string;//定义一个指针指向文本开头。
while(1)
{
pFind = _tcsstr( pFind,_T("\n"));\\在文本中寻找"\n"
if( pFind!=NULL )
{
pFind+=1;
iCountLine ++;
}
else
{
break;
}
}
那种既是"\n"又刚好到边缘换行处的情况,就忽略不计了。
int nTextHight = ( nTextLine +iCountLine )*size.cy;//计算整个文本显示需要的高度。
在这里,我们可以加上一个判断,如果nTextHight 小于或者等于rect.bottom-rect.top,就不用继续下去了。
下面创建内存DC,
HDC memTextHdc = CreateCompatibleDC(hdc);
HBITMAP memTextBitmap = CreateCompatibleBitmap( hdc,rect.right-rect.left,nTextHight);
int nOldMode = SetBkMode(memTextHdc,TRANSPARENT );
SelectObject(memTextHdc,memTextBitmap);
RECT memRect = {0,0,rect.right-rect.left,nTextHight};
HBRUSH hbrSEL = CreateSolidBrush (RGB(30,144,255 ));//为什么要填充背景?下面解释。
FillRect(memTextHdc, &memRect,hbrSEL);
DeleteObject( hbrSEL );
DrawText(memTextHdc, string, -1 ,&memRect, DT_EDITCONTROL|DT_WORDBREAK );
SetBkMode(memTextHdc,nOldMode);
DeleteObject( memTextBitmap );
DeleteDC( memTextHdc );
上面就是创建了一个memRect 大小的内存DC,并将文本string全部画进去,中途我填充了背景颜色,这个是为了在画到目标hdc 的时候考虑的,因为如果目标hdc上有背景,直接画上去的画,你会发现内存DC的背景挡住了目标hdc的背景,这里我们需要做的就是,用
BOOL TransparentBlt( HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int hHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, UINT crTransparent //此处填你填充内存DC的颜色。 );
在画到目标hdc 上的时候,将我们在内存DC上填充的背景过滤掉。这样就只有文本显示在背景上,而没有填充的颜色了,至于设置计时器,然后每次滚动大小,就看自己喜好了,记住一点,每次滚动的越少,滚动的间隔越小,滚动的效果就越好,不过我在windows mobile手机上做过测试,每次滚动字体高度的1/10,每0.1秒滚动一次,有些闪的厉害,不知道是我的问题,还是处理器不行,呵呵。
好了,就写到这里。
浙公网安备 33010602011771号