在指定区域内绘制文本

来源:互联网 发布:ipcam监控软件 编辑:程序博客网 时间:2024/04/28 14:11

在某些情况下,显示文本的区域比较小,而显示的文本比较长,这时就需要截取部分文本,并以省略号的代替的形式来显示文本,下面这个函数是一个比较笨拙的处理方式:

int DrawTextInRect(HDC hDC, CString& strText,RECT& rect,UINT nFormat,CSize sizeMargin = CSize(0,0))
{
    //在指定区域以指定格式绘制文本
    //HDC hDC                绘制文本的DC句柄
    //CString& strText        绘制的文本
    //RECT& rect            绘制文本的区域
    //UINT nFormat            绘制文本的格式,与DT相同的设置
    //CSize sizeMargin        文本距离区域的边距
    //
    CString strTemp = strText;
    CRect rcTemp = 0;
    CRect rcDraw = rect;
    rcDraw.DeflateRect(sizeMargin.cx,sizeMargin.cy);//绘制文本的区域
    CDC* pDC = CDC::FromHandle(hDC);

    //是否垂直居中
    UINT nVCenter = DT_VCENTER & nFormat;
    if (nVCenter)
    {
        //计算当前设备字体高度
        TEXTMETRIC   tm;
        pDC->GetTextMetrics(&tm);
        int nFontHeight = tm.tmHeight + tm.tmExternalLeading;
        int nMargin = (rcDraw.Height() - nFontHeight) / 2;

        rcDraw.DeflateRect(0,nMargin);       
    }   

    //计算文本需要的区域
    pDC->DrawText(strTemp,&rcTemp,DT_CALCRECT);

    //处理文本字符串
    if (rcTemp.Width() <= rect.right - rect.left)
    {
        pDC->DrawText(strTemp,&rcDraw,nFormat);
    }
    else
    {
        int nVWidth = rcDraw.Width() - sizeMargin.cx * 2;

        strTemp = L"...";
        pDC->DrawText(strTemp,&rcTemp,DT_CALCRECT);
        nVWidth -= rcTemp.Width();

        strTemp = strText;
        int nLen = strTemp.GetLength();

        //计算截取后的字符串
        while (nLen > 0)
        {
            pDC->DrawText(strTemp,&rcTemp,DT_CALCRECT);
            if (rcTemp.Width() > nVWidth)
            {
                strTemp.Delete(nLen - 1);
                nLen --;
            }
            else
            {
                break;
            }
        }

        strTemp += L"...";
        pDC->DrawText(strTemp,&rcDraw,nFormat);
    }

    return 0;
}