一、按段落显示,末尾省略
int DrawMultiLine(CDC *pDC, const CString& text, CRect rcText, int lineHeight, BOOL isCalCrect)
{
int textHeight(0);
if (!pDC)
{
return textHeight;
}
CDC dcMem;
CBitmap bmp;
dcMem.CreateCompatibleDC(pDC);
CRect rect;
GetClientRect(rect);
bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
dcMem.SelectObject(&bmp);
if (isCalCrect)
{
pDC = &dcMem;
}
int lastStartPos = 0;
int textLen = text.GetLength();
int lineCount = rcText.Height() / lineHeight;
CRect rcSubText(rcText);
for (int i(0); i < lineCount; ++i)
{
rcSubText.top = rcText.top + lineHeight*(i);
rcSubText.bottom = rcSubText.top + lineHeight;
CString subText = text.Mid(lastStartPos);
if (i < lineCount - 1)
{
DRAWTEXTPARAMS drawParams;
ZeroMemory(&drawParams, sizeof(DRAWTEXTPARAMS));
drawParams.cbSize = sizeof(DRAWTEXTPARAMS);
UINT nFormat = DT_LEFT | DT_EDITCONTROL | DT_WORDBREAK | DT_EXTERNALLEADING | DT_NOPREFIX;
int height = pDC->DrawTextEx(subText, rcSubText, nFormat, &drawParams);
textHeight += lineHeight;
if (drawParams.uiLengthDrawn > 0)
{
lastStartPos += drawParams.uiLengthDrawn;
}
// 文本绘制已经完成
if (lastStartPos >= textLen)
{
break;
}
}
// 最后一行
else
{
UINT nFormat = DT_LEFT | DT_END_ELLIPSIS | DT_EDITCONTROL | DT_EXTERNALLEADING | DT_NOPREFIX;
if (isCalCrect)
{
nFormat |= DT_CALCRECT;
}
int height = pDC->DrawText(subText, rcSubText, nFormat);
if (lineHeight < height)
{
textHeight += lineHeight;
}
// 认为最后一行,不需要空白
else
{
textHeight += height;
}
}
}
dcMem.DeleteDC();
bmp.DeleteObject();
return textHeight;
}
void CDlg***::OnPaint()
{
CPaintDC dc(this);
dc.SelectObject(&m_font);
CRect rect(12,36,240,126);
if (m_text.Find('\n') < 0)
{
CSize size = dc.GetTextExtent(m_text);
if (size.cx < 240 -12)
{
dc.DrawText(m_text, rect, DT_SINGLELINE | DT_CENTER |DT_VCENTER | DT_WORDBREAK| DT_EDITCONTROL);
return;
}
}
CRect rc(12,37,240,120);
int height = DrawMultiLine(&dc, m_text,rc, 18, TRUE);
if(rect.Height() > height)
{
rect.top += (rect.Height() - height)/2;
}
DrawMultiLine(&dc, m_text, rect, 18);
}
二、按行显示并省略(没有优化)
int DrawMultiLine(CDC *pDC, const CString& text, CRect rcText, int lineHeight, BOOL isCalCrect)
{
int textHeight(0);
if (!pDC)
{
return textHeight;
}
CDC dcMem;
CBitmap bmp;
dcMem.CreateCompatibleDC(pDC);
CRect rect;
GetClientRect(rect);
bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
dcMem.SelectObject(&bmp);
if (isCalCrect)
{
pDC = &dcMem;
}
int lastStartPos = 0;
int textLen = text.GetLength();
int lineCount = rcText.Height() / lineHeight;
CRect rcSubText(rcText);
int isFindLineEnd(-1);
CString textTemp(text);
isFindLineEnd = textTemp.Find('\n');
int i(0);
while (isFindLineEnd > -1)
{
rcSubText.top = rcText.top + lineHeight*(i);
rcSubText.bottom = rcSubText.top + lineHeight;
CString subText = textTemp.Left(isFindLineEnd);
textTemp = textTemp.Mid(isFindLineEnd + 1);
DRAWTEXTPARAMS drawParams;
ZeroMemory(&drawParams, sizeof(DRAWTEXTPARAMS));
drawParams.cbSize = sizeof(DRAWTEXTPARAMS);
UINT nFormat = DT_LEFT | DT_END_ELLIPSIS | DT_EDITCONTROL | DT_WORDBREAK;
int height = pDC->DrawTextEx(subText, rcSubText, nFormat, &drawParams);
textHeight += lineHeight;
isFindLineEnd = textTemp.Find('\n');
++i;
}
// 最后一行
{
UINT nFormat = DT_LEFT | DT_END_ELLIPSIS | DT_EDITCONTROL;
if (isCalCrect)
{
nFormat |= DT_CALCRECT;
}
int height = pDC->DrawText(textTemp, rcSubText, nFormat);
if (lineHeight < height)
{
textHeight += lineHeight;
}
// 认为最后一行,不需要空白
else
{
textHeight += height;
}
}
dcMem.DeleteDC();
bmp.DeleteObject();
return textHeight;
}