64,635
社区成员
发帖
与我相关
我的任务
分享
/**************************************************************************************************
** 函数名: IsAlphabet
**
** 功 能: 判断当前字符串是否全部由英文组成
**
** 参 数: CString txt : 当前行内容
**
** 返 回: TRUE : 是
** FALSE : 否
**
**************************************************************************************************/
BOOL CDrawTextExex::IsAlphabet(CString txt)
{
int idx=0;
for (idx=0; idx<txt.GetLength(); idx++)
{
if (((txt.GetAt(idx) >= _T('a')) && ((txt.GetAt(idx) <= _T('z'))))||
((txt.GetAt(idx) >= _T('A')) && ((txt.GetAt(idx) <= _T('Z'))))
)
{
continue;
}
else
{
return FALSE;
}
}
return TRUE;
}
/**************************************************************************************************
** 函数名: IsTailHaveAlphabet
**
** 功 能: 判断当前字符串末尾是否由英文组成
**
** 参 数: CString txt : 当前行内容
** int count : 末尾英文字母个数
**
** 返 回: TRUE : 是
** FALSE : 否
**
**************************************************************************************************/
BOOL CDrawTextExex::IsTailHaveAlphabet(CString txt, int &count)
{
int idx=0;
for (idx=txt.GetLength()-1; idx>=0; idx--)
{
if (((txt.GetAt(idx) >= _T('a')) && ((txt.GetAt(idx) <= _T('z'))))||
((txt.GetAt(idx) >= _T('A')) && ((txt.GetAt(idx) <= _T('Z'))))
)
{
count++;
continue;
}
else
{
break;
}
}
return (count>0)? TRUE:FALSE;
}
/**************************************************************************************************
** 函数名: IsTailHaveArabicNumbers
**
** 功 能: 判断当前字符串末尾是否存在阿拉伯数字
**
** 参 数: CString txt : 当前行内容
**
** 返 回: TRUE : 是
** FALSE : 否
**
**************************************************************************************************/
BOOL CDrawTextExex::IsTailHaveArabicNumbers(CString txt)
{
int idx=0;
int iCount=0;
for (idx=txt.GetLength()-1; idx>=0; idx--)
{
if ((txt.GetAt(idx) >= _T('0')) && ((txt.GetAt(idx) <= _T('9'))))
{
iCount++;
continue;
}
else
{
break;
}
}
return (iCount>0? TRUE:FALSE);
}
/**************************************************************************************************
** 函数名: IsArabicNumbers
**
** 功 能: 判断当前字符串是否全部阿拉伯数字
**
** 参 数: CString txt : 当前行内容
**
** 返 回: TRUE : 是
** FALSE : 否
**
**************************************************************************************************/
BOOL CDrawTextExex::IsArabicNumbers(CString txt)
{
int idx=0;
for (idx=0; idx<txt.GetLength(); idx++)
{
if ((txt.GetAt(idx) >= _T('0')) && ((txt.GetAt(idx) <= _T('9'))))
{
continue;
}
else
{
return FALSE;
}
}
return TRUE;
}
/**************************************************************************************************
** 函数名: GetLinesOfPage
**
** 功 能: 获取每页可显示多少行内容
**
** 参 数: 无
**
** 返 回: m_drawInfo.curPage : 当前页
**
**************************************************************************************************/
int CDrawTextExex::GetLinesOfPage()
{
return m_drawInfo.linePerPage;
}
/**************************************************************************************************
** 函数名: GetCurrPage
**
** 功 能: 获取当前所处页
**
** 参 数: 无
**
** 返 回: m_drawInfo.curPage : 当前页
**
**************************************************************************************************/
int CDrawTextExex::GetCurrPage()
{
return m_drawInfo.curPage;
}
/*-------------------------------------------------------------------------------------------
函数名: GetMaxPages
功 能: 获取文本总页数
说 明: 无
参 数: 无
返 回: 返回文本总页数
-------------------------------------------------------------------------------------------*/
int CDrawTextExex::GetMaxPages()
{
return m_drawInfo.maxPages;
}
/**************************************************************************************************
** 函数名: UpPage
**
** 功 能: 上一页
**
** 参 数: 无
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::UpPage()
{
m_drawInfo.curPage--;
if (m_drawInfo.curPage <= 0)
{
m_drawInfo.curPage = 0;
}
}
/**************************************************************************************************
** 函数名: DownPage
**
** 功 能: 下一页
**
** 参 数: 无
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::DownPage()
{
m_drawInfo.curPage++;
if (m_drawInfo.curPage >= (m_drawInfo.maxPages-1))
{
m_drawInfo.curPage = m_drawInfo.maxPages-1;
}
}
/**************************************************************************************************
** 函数名: SetOverlapLines
**
** 功 能: 设置重叠行的行数。下一页需要显示上一页多少行。
** 可通过调试调用GetLinesOfPage函数,count不能超过每页能显示的行数
**
** 参 数: int count : 下一页需要显示上一页的行数(根据实际设置,否则越界)
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::SetOverlapLines(int count)
{
if (count < 0)
{
count = 0;
}
//else if (count >= m_drawInfo.linePerPage)
//{
// count = m_drawInfo.linePerPage;
//}
m_drawInfo.overlapLines = count;
}
/**************************************************************************************************
** 函数名: CalMaxPage
**
** 功 能: 根据设置显示方式,计算总页数。
**
** 参 数: maxLines : 总行数
**
** 返 回: 总页数
**
**************************************************************************************************/
int CDrawTextExex::CalMaxPage(int maxLines /* = 0 */)
{
int temp = 0;
m_drawInfo.remainder = maxLines % m_drawInfo.linePerPage; //
temp = maxLines / m_drawInfo.linePerPage + (m_drawInfo.remainder == 0 ? 0 : 1);
m_drawInfo.maxPages += temp;
if (temp > 1)
{
//
if (m_drawInfo.remainder == 0)
{
CalMaxPage((temp - 1) * m_drawInfo.overlapLines);
}
else
{
m_drawInfo.maxPages -= 1;
CalMaxPage((temp - 1) * m_drawInfo.overlapLines + m_drawInfo.remainder);
}
}
return m_drawInfo.maxPages;
}
//
#include "stdafx.h"
#include "DrawTextExex.h"
// CDrawTextExex
IMPLEMENT_DYNAMIC(CDrawTextExex, CWnd)
CDrawTextExex::CDrawTextExex()
{
InitDrawInfo();
m_font.CreateFont(FONT_HEIGHT,
0,
0,
0,
500,
FALSE,
FALSE,
0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS,
_T("微软雅黑"));
}
CDrawTextExex::~CDrawTextExex()
{
InitDrawInfo();
}
/**************************************************************************************************
** 函数名: Draws
**
** 功 能: 初始化文本信息
**
** 参 数: CDC &dc : 设备上下文
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::Draws(CDC &dc)
{
CBitmap bmp;
CBitmap *pOldBmp=NULL;
CFont* pOldFont=NULL;
bmp.CreateCompatibleBitmap(&dc, m_rc.Width(), m_rc.Height());
CDC memDC;
memDC.CreateCompatibleDC(&dc);
pOldBmp = memDC.SelectObject(&bmp);
pOldFont = memDC.SelectObject(&m_font);
memDC.SetBkMode(TRANSPARENT);
memDC.SetBkColor(RGB(0, 0, 0));
memDC.SetTextColor(RGB(255, 255, 255));
//memDC.FillSolidRect(&m_rc, RGB(0, 0, 0));
DrawTexts(&memDC);
dc.BitBlt(m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.SelectObject(pOldFont);
bmp.DeleteObject();
memDC.DeleteDC();
}
/**************************************************************************************************
** 函数名: DrawTexts
**
** 功 能: 初始化文本信息
**
** 参 数: CDC* pDC : 设备上下文
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::DrawTexts(CDC* pDC)
{
if (m_drawInfo.maxPages < 1)
{
return;
}
CString strCurrTxt;
strCurrTxt.Empty();
if (m_drawInfo.curPage > (m_drawInfo.maxPages-1))
{
m_drawInfo.curPage = m_drawInfo.maxPages-1;
}
CString strTmp;
int idx=0;
int icurLine=0;
int iTotalLines;
if (0 == m_drawInfo.curPage)
{
icurLine = m_drawInfo.curPage * m_drawInfo.linePerPage;
iTotalLines = (m_drawInfo.curPage+1) * m_drawInfo.linePerPage;
}
else
{
icurLine = m_drawInfo.curPage * m_drawInfo.linePerPage - (m_drawInfo.overlapLines * m_drawInfo.curPage);
iTotalLines = (m_drawInfo.curPage+1) * m_drawInfo.linePerPage - (m_drawInfo.overlapLines * m_drawInfo.curPage);
}
if (iTotalLines >= m_drawInfo.maxLines)
{
iTotalLines = m_drawInfo.maxLines;
}
for (; icurLine<iTotalLines; icurLine++)
{
strTmp = m_drawInfo.rowTxt.GetAt(icurLine);
pDC->DrawText(strTmp,
CRect(m_rc.left, m_rc.top+idx*FONT_HEIGHT, m_rc.Width(), m_rc.Height()),
DT_LEFT | DT_WORDBREAK);
if (icurLine < (m_drawInfo.maxLines-1))
{
idx++;
}
}
}
/**************************************************************************************************
** 函数名: InitDrawInfo
**
** 功 能: 初始化文本信息
**
** 参 数: CString txt : 需要显示的文本内容
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::InitDrawInfo(CString txt)
{
if (m_drawInfo.rowTxt.GetCount() > 0)
{
m_drawInfo.rowTxt.RemoveAll();
}
m_drawInfo.maxPages = 0;
m_drawInfo.linePerPage = 0;
m_drawInfo.curPage = 0;
m_drawInfo.maxLines = 0;
m_drawInfo.remainder = 0;
m_drawInfo.overlapLines = 0;//初始化为0,默认整页整页翻
m_drawInfo.text = txt;
}
/**************************************************************************************************
** 函数名: CalDrawInfo
**
** 功 能: 计算需要显示的文本,得到信息保存到m_drawInfo中
**
** 参 数: CDC *pDC : 设备上下文
** CRect rc : 显示矩形区
** CString text : 文本内容
**
** 返 回: 无
**
**************************************************************************************************/
void CDrawTextExex::CalDrawInfo(CDC *pDC, CRect rc, CString text)
{
int iTxtCount=0;
int iCurrPos=0;
int iLastLinePos = 0;
BOOL bFirstTime=TRUE;
BOOL bAllIsAlpha=FALSE;//是否正行内容为英文字母
int iAlphaCnt=0;//该行末尾所含英文字母个数
CString strCurrContent;
CSize sz(0, 0);
InitDrawInfo(text);
m_rc = rc;
pDC->SelectObject(&m_font);
iTxtCount = m_drawInfo.text.GetLength();
for (iCurrPos=0; iCurrPos<iTxtCount; iCurrPos++)
{
if ((((text.GetAt(iCurrPos) == _T('\r'))) && (text.GetAt(iCurrPos+1) == _T('\n')))||//回车+换行
((text.GetAt(iCurrPos) == _T('\n')) && (text.GetAt(iCurrPos-1) != _T('\r')))//只有换行符
)
{
}
else
{
if (0 == iLastLinePos)
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos, iCurrPos+1-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos+1-iLastLinePos);
}
else
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos+1, iCurrPos-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos-iLastLinePos);
}
if (sz.cx < rc.Width())
{
if (iCurrPos < (iTxtCount-1))
continue;
}
else if (sz.cx > rc.Width())
{
do
{
iCurrPos--;
if (0 == iLastLinePos)
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos, iCurrPos+1-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos+1-iLastLinePos);
}
else
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos+1, iCurrPos-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos-iLastLinePos);
}
bAllIsAlpha = IsAlphabet(strCurrContent);//检查是否正行内容为英文字母
if (FALSE == bAllIsAlpha)
{
IsTailHaveAlphabet(strCurrContent, iAlphaCnt);
}
} while ((sz.cx > rc.Width())||
(
(text.GetAt(iCurrPos) >= _T('a')) && ((text.GetAt(iCurrPos) <= _T('z')))&&//一个英文单词(小写)在该行未显示完
(FALSE == bAllIsAlpha)&&//并且整行内容不全部为字母组成
(WORD_MAX_LEN > iAlphaCnt)&&//字母个数不超过最长英文单词所包含字母个数
(iCurrPos-iLastLinePos > 1)//该行最少显示1-2个字符
)||//则换行
(
(text.GetAt(iCurrPos) >= _T('A')) && ((text.GetAt(iCurrPos) <= _T('Z')))&&//一个英文单词(大写)在该行未显示完
(FALSE == bAllIsAlpha)&&//并且整行内容不全部为字母组成
(WORD_MAX_LEN > iAlphaCnt)&&//字母个数不超过最长英文单词所包含字母个数
(iCurrPos-iLastLinePos > 1)//该行最少显示1-2个字符
)//则换行
);
}
else if (sz.cx == rc.Width())
{
while (((text.GetAt(iCurrPos) >= _T('a')) && ((text.GetAt(iCurrPos) <= _T('z')))&&//一个英文单词(小写)在该行未显示完
(FALSE == bAllIsAlpha)&&//并且整行内容不全部为字母组成
(WORD_MAX_LEN > iAlphaCnt)&&//字母个数不超过最长英文单词所包含字母个数
(iCurrPos-iLastLinePos > 1)//该行最少显示1-2个字符
)||//则换行
((text.GetAt(iCurrPos) >= _T('A')) && ((text.GetAt(iCurrPos) <= _T('Z')))&&//一个英文单词(大写)在该行未显示完
(FALSE == bAllIsAlpha)&&//并且整行内容不全部为字母组成
(WORD_MAX_LEN > iAlphaCnt)&&//字母个数不超过最长英文单词所包含字母个数
(iCurrPos-iLastLinePos > 1)//该行最少显示1-2个字符
)//则换行
)
{
iCurrPos--;
if (0 == iLastLinePos)
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos, iCurrPos+1-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos+1-iLastLinePos);
}
else
{
strCurrContent = m_drawInfo.text.Mid(iLastLinePos+1, iCurrPos-iLastLinePos);
sz = pDC->GetTextExtent(strCurrContent, iCurrPos-iLastLinePos);
}
bAllIsAlpha = IsAlphabet(strCurrContent);//检查是否正行内容为英文字母
if (FALSE == bAllIsAlpha)
{
IsTailHaveAlphabet(strCurrContent, iAlphaCnt);
}
}
}
}
//MessageBox(strCurrContent);
m_drawInfo.maxLines++;
m_drawInfo.rowTxt.Add(strCurrContent);
iLastLinePos = iCurrPos;
bAllIsAlpha = FALSE;
bFirstTime = TRUE;
iAlphaCnt = 0;
}
m_drawInfo.linePerPage = rc.Height()/FONT_HEIGHT;
CalMaxPage(m_drawInfo.maxLines);
//CString str;
//str.Format(L"linePerPage : %d, maxlines: %d, maxPages: %d", m_drawInfo.linePerPage, m_drawInfo.maxLines, m_drawInfo.maxPages);
//AfxMessageBox(str);
}
#pragma once
#define FONT_HEIGHT 30
#define WORD_MAX_LEN 29//最长英文单词长度
typedef struct _DrawInfo_
{
int maxPages; //总页数
int maxLines; //总行数
int linePerPage; //每页行数
int curPage; //当前页
int remainder; //最后一页的行数
int overlapLines; //重叠行数
CArray<CString> rowTxt; //每行内容
CString text; //文本内容
}DrawInfo, *PDrawInfo;
// CDrawTextExex
class CDrawTextExex
{
DECLARE_DYNAMIC(CDrawTextExex)
public:
CDrawTextExex();
virtual ~CDrawTextExex();
int GetMaxPages();
int GetLinesOfPage();
int GetCurrPage();
void UpPage();
void DownPage();
void SetOverlapLines(int count=0);
void CalDrawInfo(CDC *pDC, CRect rc, CString text); //计算总页数
void Draws(CDC &dc);
protected:
void DrawTexts(CDC* pDC);
int CalMaxPage(int maxLines = 0); //计算总页数
void InitDrawInfo(CString txt=L"");
BOOL IsAlphabet(CString txt);
BOOL IsTailHaveAlphabet(CString txt, int &count);
BOOL IsArabicNumbers(CString txt);
BOOL IsTailHaveArabicNumbers(CString txt);
private:
CRect m_rc;
CFont m_font; //字体
DrawInfo m_drawInfo;
};