Sounds simple :) 1.Get the rect of the rectangle area,then get the text length of the text using DrawText (not really draw but only get the width)with DT_CALCRECT. 2.Break up the string to be displayed into an array of sub strings,and Appending each substring with one "\r\n" when calling TextOut.If neccessary,You could also use a list or similar structure to keep track of of the inserted "\r\n" 's position ,so that you could tell the "inserted" from original "\r\n" later!!! Okey.That is all.I am so lazy so no snippets supplied:)
int nLine = CountLinesInText(strScr, nWidth ,pDC) int pos =0l for(int i =0;i<nLine;i++) { strLine = ExtractLine(strScr, &pos, nWidth , pDC); DrawText(...)} CString ExtractLine(CString &source, int &pos, int width, CDC *pDC) { CString line ; CSize size ; bool pBreak = false ; // first skip any whitepace (you may need to remove this if user formatting is required while (pos < source.GetLength()) { if (source.GetAt(pos) == ' ') ++pos ; else break ; } if (pos < source.GetLength()) { // there is more data that could be printed do { if (source.GetAt(pos) == '\r') { // end of a line, we need to break it here if (pos < source.GetLength() - 1 && source.GetAt(pos + 1) == '\n') { // skip \r\n pair pos += 2 ; pBreak = true ; // its a page break break ; // got the line } else { // just break the line here // skip the \r ++pos ; pBreak = true ; // its a page break break ; } } if (source.GetAt(pos) == '\n') { // just break the line here // skip the \n pBreak = true ; // its a page break ++pos ; break ; } // add the character to the line to print if((source.GetAt(pos) &0x80) ==0x80) { line += source.GetAt(pos) ; ++pos ; line += source.GetAt(pos) ; ++pos ; } else { line += source.GetAt(pos) ; ++pos ; } // measure the new text to see if it will fit on the page size = pDC->GetTextExtent(line) ; } while (size.cx < width && pos < source.GetLength()) ; } return line ;
} int CountLinesInText(CString &text, int width, CDC *pDC) { int count = 0 ; int pos = 0 ; while (pos < text.GetLength()) { ExtractLine(text, pos, width, pDC) ; count++ ; } return count ; }
to jag1976(明天) : 如果GetTextExtent得到的宽度大于width怎么办,字符串强制换行好象并没有实现呀!
CPaintDC dc(this); // device context for painting TEXTMETRIC tm; dc.GetTextMetrics(&tm); CFont *pFont = m_pParentWnd->GetFont(); // use same font as ctrl CFont *pFontDC = dc.SelectObject( pFont ); int nHeight=0; CRect rect = m_rectDisplay; ScreenToClient(rect); dc.SetBkMode( TRANSPARENT ); nHeight = dc.DrawText(m_strTitle, rect, 0 | DT_LEFT | DT_EDITCONTROL | DT_NOPREFIX | DT_WORDBREAK ); dc.SelectObject( pFontDC ); DT_EDITCONTROL这个标记就是复杂多行显示的,不果你至少要先计算一下你显示文本需要多高。 看看MSDN的解释: DT_EDITCONTROL :Duplicates the text-displaying characteristics of a multiline edit control. Specifically, the average character width is calculated in the same manner as for an edit control, and the function does not display a partially visible last line.
zhujianping_es(DavidRipple) 星星也可以给吗?渴望啊~~~~~~~
使用DrawText就可以自动换行了。 不需要加回车或者换行符的
int DrawMultLineText(HDC hDC , int nXStart , int nYStart , int nWidth , int nRowHeight , LPCTSTR pBuff) { TEXTMETRIC tm;
或者用多个TextOut
1.Get the rect of the rectangle area,then get the text length of the text using DrawText
(not really draw but only get the width)with DT_CALCRECT.
2.Break up the string to be displayed into an array of sub strings,and Appending each substring with one "\r\n" when calling TextOut.If neccessary,You could also use a list or similar structure to keep track of
of the inserted "\r\n" 's position ,so that you could tell the "inserted" from original
"\r\n" later!!! Okey.That is all.I am so lazy so no snippets supplied:)
或者用多个TextOut
完全同意
大哥,俺的星星只要一个,就不给内了!
可是还是不能换行啊!
int nLine = CountLinesInText(strScr, nWidth ,pDC)
int pos =0l
for(int i =0;i<nLine;i++)
{
strLine = ExtractLine(strScr, &pos, nWidth , pDC);
DrawText(...)}
CString ExtractLine(CString &source, int &pos, int width, CDC *pDC)
{
CString line ;
CSize size ;
bool pBreak = false ;
// first skip any whitepace (you may need to remove this if user formatting is required
while (pos < source.GetLength())
{
if (source.GetAt(pos) == ' ')
++pos ;
else
break ;
} if (pos < source.GetLength())
{
// there is more data that could be printed
do {
if (source.GetAt(pos) == '\r')
{
// end of a line, we need to break it here
if (pos < source.GetLength() - 1 && source.GetAt(pos + 1) == '\n')
{
// skip \r\n pair
pos += 2 ;
pBreak = true ; // its a page break
break ; // got the line
}
else
{
// just break the line here
// skip the \r
++pos ;
pBreak = true ; // its a page break
break ;
}
}
if (source.GetAt(pos) == '\n')
{
// just break the line here
// skip the \n
pBreak = true ; // its a page break
++pos ;
break ;
}
// add the character to the line to print
if((source.GetAt(pos) &0x80) ==0x80)
{
line += source.GetAt(pos) ;
++pos ;
line += source.GetAt(pos) ;
++pos ;
}
else
{
line += source.GetAt(pos) ;
++pos ;
}
// measure the new text to see if it will fit on the page
size = pDC->GetTextExtent(line) ;
} while (size.cx < width && pos < source.GetLength()) ;
} return line ;
}
int CountLinesInText(CString &text, int width, CDC *pDC)
{ int count = 0 ;
int pos = 0 ; while (pos < text.GetLength())
{
ExtractLine(text, pos, width, pDC) ;
count++ ;
}
return count ;
}
如果GetTextExtent得到的宽度大于width怎么办,字符串强制换行好象并没有实现呀!
dc.GetTextMetrics(&tm); CFont *pFont = m_pParentWnd->GetFont(); // use same font as ctrl
CFont *pFontDC = dc.SelectObject( pFont );
int nHeight=0; CRect rect = m_rectDisplay;
ScreenToClient(rect); dc.SetBkMode( TRANSPARENT ); nHeight = dc.DrawText(m_strTitle, rect, 0
| DT_LEFT
| DT_EDITCONTROL
| DT_NOPREFIX
| DT_WORDBREAK
);
dc.SelectObject( pFontDC );
DT_EDITCONTROL这个标记就是复杂多行显示的,不果你至少要先计算一下你显示文本需要多高。
看看MSDN的解释:
DT_EDITCONTROL :Duplicates the text-displaying characteristics of a multiline edit control. Specifically, the average character width is calculated in the same manner as for an edit control, and the function does not display a partially visible last line.
星星也可以给吗?渴望啊~~~~~~~
不需要加回车或者换行符的
{
TEXTMETRIC tm;
LPCTSTR pChar; if(!GetTextMetrics(hDC , &tm))
return 0;
CPoint posStart , posCurr;
int nRowCount = 0;
pChar = pBuff;
posStart.SetPoint(nXStart , nYStart);
for(; *pChar ; pChar++)
{
if(*pChar == '\t')
{
MovePos(posStart , posCurr , nWidth ,nRowHeight , tm.tmAveCharWidth , 4);
}
else
{
if(*pChar == '\r')
{
posCurr.y += nRowHeight;
posCurr.x = posStart.x;
if( *(pChar + 1) == '\n')
pChar++;
}
else
if(*pChar == '\n')
{
posCurr.y += nRowHeight;
posCurr.x = posStart.x;
}
else
if( IsChineseChar(pChar))
{
TextOut(hDC , posCurr.x , posCurr.y ,pChar , 2);
MovePos(posStart , posCurr , nWidth ,nRowHeight , tm.tmMaxCharWidth , 1) ;
pChar ++;
}
else
{
TextOut(hDC , posCurr.x , posCurr.y ,pChar , 1);
MovePos(posStart , posCurr , nWidth ,nRowHeight , tm.tmAveCharWidth , 1);
}
}
}
return (posCurr.y + posStart.y) / nRowHeight;
}void MovePos(const POINT &posStart , POINT &posCurr , int nColWidth , int nRowHeight , int nCharWidth , int nCount)
{
int i;
if(nColWidth < nCharWidth)
return;
if(posStart.x > posCurr.x)
posCurr.x = posStart.x;
if(posStart.y > posCurr.y)
posCurr.y = posStart.y; for(i = 0 ; i < nCount ; i++)
{
posCurr.x += nCharWidth;
if(posCurr.x > nColWidth)
{
posCurr.x = posStart.x;
posCurr.y += nRowHeight;
}
}
}
{
return *str < 0 && (*(str + 1)) < 0;
}
http://blog.csdn.net/ggg82/archive/2004/11/10/175403.aspx