📄 horizontalrolltext.cpp
字号:
// HorizontalRollText.cpp : implementation file
//
#include "stdafx.h"
#include "DoubleColorBall.h"
#include "HorizontalRollText.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHorizontalRollText
CHorizontalRollText::CHorizontalRollText()
{
}
// 释放资源
CHorizontalRollText::~CHorizontalRollText()
{
m_MemDC.DeleteDC();
m_Bmp.DeleteObject();
m_Font.DeleteObject();
}
BEGIN_MESSAGE_MAP(CHorizontalRollText, CStatic)
//{{AFX_MSG_MAP(CHorizontalRollText)
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHorizontalRollText message handlers
void CHorizontalRollText::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
Paint(&dc);
// Do not call CStatic::OnPaint() for painting messages
}
// 设置滚动效果
void CHorizontalRollText::SetRollMode(UINT nStyle)
{
m_nStyle = nStyle;
switch (m_nStyle)
{
case ML_NONE: // 没有滚动
m_nX = 0;
m_nY = 0;
m_nBBx = 0; m_nBBy = 0;
m_nBBWidth = m_nTextWidth > m_Rect.Width()?m_Rect.Width():m_nTextWidth;
m_nBBHeight = m_nTextHeight > m_Rect.Height()?m_Rect.Height():m_nTextHeight;
m_nBBxScr = 0;
m_nBByScr = 0;
SetTextAlign(m_nTextAlign); // 设置文本对齐方式
KillTimer((UINT)this); // 取消定时器
Invalidate();
break;
case ML_LHSCROLL: // 向左滚动
case ML_RHSCROLL: // 向右滚动
case ML_HSCROLLBOTH: // 向两边滚动
case ML_HSCROLLAUTO: // 自动滚动
m_nX = 0;
m_nY = 0;
m_nBBy = 0;
m_nBBHeight = m_nTextHeight > m_Rect.Height()?m_Rect.Height():m_nTextHeight;
m_nBByScr = 0;
SetTextAlign(m_nTextAlign);
SetTimer((UINT)this, m_nTick, NULL);
break;
}
}
// 计算字符串的宽度、高度,存于m_nTextWidth,m_nTextHeight
void CHorizontalRollText::GetTextSize()
{
CSize size = m_MemDC.GetOutputTextExtent(m_csText);
m_nTextWidth = size.cx; // 宽度
m_nTextHeight = size.cy; // 高度
}
// 根据m_csText重画m_Bmp
void CHorizontalRollText::Draw()
{
CDC *pDC = GetDC();
m_Bmp.DeleteObject();// 再次调用CreateCompatibleBitmap前必须先删除原来的
m_Bmp.CreateCompatibleBitmap(pDC,
m_nTextWidth,
m_nTextHeight);
m_MemDC.SelectObject(&m_Font);
m_MemDC.SelectObject(&m_Bmp);
m_MemDC.SetBkColor(m_BkColor); // 设置背景颜色
m_MemDC.SetTextColor(m_TextColor); // 设置文本颜色
m_MemDC.TextOut(0, 0, m_csText); // 输出文本
}
// 重写父类成员SetWindowText
void CHorizontalRollText::SetWindowText(LPCTSTR lpszString)
{
m_csText.Format(_T("%s"), lpszString);
m_nX = 0;
m_nY = 0;
SetTextAlign(m_nTextAlign); // 设置文本对齐方式
Draw();
Invalidate();
}
// 设置字体
void CHorizontalRollText::SetFont(CFont &f)
{
ASSERT_VALID(&f);
m_Font.DeleteObject();
m_Font.Attach(f.GetSafeHandle());
m_MemDC.SelectObject(&m_Font);
Draw();
Invalidate();
}
// 设置背景颜色
void CHorizontalRollText::SetBkColor(COLORREF crColor)
{
m_BkColor = crColor;
Draw();
Invalidate();
}
// 设置文本颜色
void CHorizontalRollText::SetTextColor(COLORREF crColor)
{
m_TextColor = crColor;
Draw();
Invalidate();
}
// 画图
void CHorizontalRollText::Paint(CDC *pDC)
{
int index = 3;
// 画背景
CDC memDC2;
CBitmap bmp, *oldbmp;
CBrush brush(m_BkColor), *oldbrush;
bmp.CreateCompatibleBitmap(pDC,
m_Rect.Width(),
m_Rect.Height());
memDC2.CreateCompatibleDC(pDC);
oldbmp = memDC2.SelectObject(&bmp);
oldbrush = memDC2.SelectObject(&brush);
memDC2.FillRect(&m_Rect, &brush);
switch (m_nStyle)
{
case ML_NONE: // 没有滚动
break;
case ML_LHSCROLL: // 向左滚动
if (m_nX < -m_nTextWidth)
{
m_nX = m_Rect.Width();
}
if (m_nX <= 0)
{
m_nBBx = 0;
m_nBBxScr = -m_nX;
if (m_Rect.Width() > m_nTextWidth + m_nX)
{
m_nBBWidth = m_nTextWidth + m_nX;
}
else
{
m_nBBWidth = m_Rect.Width();
}
}
else
{
m_nBBx = m_nX;
m_nBBxScr = 0;
if (m_Rect.Width() > m_nTextWidth + m_nX)
{
m_nBBWidth = m_nTextWidth;
}
else
{
m_nBBWidth = m_Rect.Width()-m_nX;
}
}
m_nX -= m_nStep;
break;
case ML_HSCROLLBOTH: // 向两边滚动
if (m_Rect.Width() > m_nTextWidth)
{
if (m_nX < 0)
{ m_nX = 0;
m_bLeft = false;
}
if (m_nX > m_Rect.Width() - m_nTextWidth)
{
m_nX = m_Rect.Width() - m_nTextWidth;
m_bLeft = true;
}
m_nBBx = m_nX;
m_nBBWidth = m_nTextWidth;
m_nBBxScr = 0;
}
else
{
if (m_nX < m_Rect.Width() - m_nTextWidth)
{ m_nX = m_Rect.Width() - m_nTextWidth;
m_bLeft = false;
}
if (m_nX > 0)
{ m_nX = 0;
m_bLeft = true;
}
m_nBBx = 0;
m_nBBWidth = m_Rect.Width();
m_nBBxScr = -m_nX;
}
if (m_bLeft)
{
m_nX -= m_nStep;
}
else
{
m_nX += m_nStep;
}
break;
case ML_HSCROLLAUTO: // 自动滚动
if (m_nX <= 0)
{
m_nBBx = 0;
m_nBBxScr = -m_nX;
if (m_Rect.Width() > m_nTextWidth + m_nX)
{
m_nBBWidth = m_nTextWidth + m_nX;
}
else
{
m_nBBWidth = m_Rect.Width();
}
}
else
{
m_nBBx = m_nX;
m_nBBxScr = 0;
if (m_Rect.Width() > m_nTextWidth + m_nX)
{
m_nBBWidth = m_nTextWidth;
}
else
{
m_nBBWidth = m_Rect.Width()-m_nX;
}
}
m_nX -= m_nStep;
if (m_nX < 0 &&
m_nTextWidth > m_Rect.Width()/index &&
m_nBBWidth < m_Rect.Width()/index)
{
if (m_nBBWidth <= 0)
{ m_nX = m_Rect.Width() - m_Rect.Width()/index-m_nStep;
m_nBBx = m_Rect.Width() - m_Rect.Width()/index;
m_nBBWidth = m_Rect.Width()/index;
m_nBBxScr = 0;
}
else
{
memDC2.BitBlt(m_Rect.Width()-m_Rect.Width()/index+m_nBBWidth,
m_nBBy,
m_Rect.Width()/index-m_nBBWidth,
m_nBBHeight,
&m_MemDC,
0,
m_nBByScr,
SRCPAINT
);
}
}
break;
default:
break;
}
// 将前景和背景进行组合
memDC2.BitBlt(m_nBBx,
m_nBBy,
m_nBBWidth,
m_nBBHeight,
&m_MemDC,
m_nBBxScr,
m_nBByScr,
SRCPAINT
);
// 画最终的图像到DC
pDC->BitBlt(0,
0,
m_Rect.Width(),
m_Rect.Height(),
&memDC2,
0,
0,
SRCCOPY
);
memDC2.SelectObject(oldbmp);
memDC2.SelectObject(oldbrush);
memDC2.DeleteDC();
}
// 重写父类成员GetWindowText
void CHorizontalRollText::GetWindowText(CString &csText) const
{
csText = m_csText;
}
// 设置文本对齐
void CHorizontalRollText::SetTextAlign(UINT nTextAlign)
{
m_nTextAlign = nTextAlign;
GetTextSize();
UINT nHAlign = m_nTextAlign & 0x0f;
UINT nVAlign = m_nTextAlign & 0xf0;
// 设置水平对齐
switch (nHAlign)
{
case ML_TA_RIGHT: // 右对齐
m_nX = 0;
m_nBBx = m_nTextWidth > m_Rect.Width()?0:(m_Rect.Width()-m_nTextWidth);
m_nBBWidth = m_nTextWidth > m_Rect.Width()?m_Rect.Width():m_nTextWidth;
m_nBBxScr = m_nTextWidth > m_Rect.Width()?(m_nTextWidth-m_Rect.Width()):0;
break;
case ML_TA_CENTER: // 居中对齐
m_nX = 0;
m_nBBx = m_nTextWidth > m_Rect.Width()?0:(m_Rect.Width()-m_nTextWidth)/2;
m_nBBWidth = m_nTextWidth > m_Rect.Width()?m_Rect.Width():m_nTextWidth;
m_nBBxScr = m_nTextWidth > m_Rect.Width()?(m_nTextWidth-m_Rect.Width())/2:0;
break;
default:
m_nX = 0;
m_nBBx = 0;
m_nBBWidth = m_nTextWidth>m_Rect.Width()?m_Rect.Width():m_nTextWidth;
m_nBBxScr = 0;
break;
}
// 设置垂直对齐
switch (nVAlign)
{
case ML_TA_BOTTOM: // 底部对齐
m_nY = 0;
m_nBBy = m_nTextHeight > m_Rect.Height()?0:(m_Rect.Height()-m_nTextHeight);
m_nBBHeight = m_nTextHeight > m_Rect.Height()?m_Rect.Height():m_nTextHeight;
m_nBByScr = m_nTextHeight > m_Rect.Height()?(m_nTextHeight-m_Rect.Height()):0;
break;
case ML_TA_VCENTER: // 居中对齐
m_nY = 0;
m_nBBy = m_nTextHeight > m_Rect.Height()?0:(m_Rect.Height()-m_nTextHeight)/2;
m_nBBHeight = m_nTextHeight > m_Rect.Height()?m_Rect.Height():m_nTextHeight;
m_nBByScr = m_nTextHeight > m_Rect.Height()?(m_nTextHeight-m_Rect.Height())/2:0;
break;
default:
m_nY = 0;
m_nBBy = 0;
m_nBBHeight = m_nTextHeight > m_Rect.Height()?m_Rect.Height():m_nTextHeight;
m_nBByScr = 0;
break;
}
// Invalidate();
}
// 初始化字体、步长、颜色等
void CHorizontalRollText::Initialize()
{
CDC *pDC = this->GetDC();
m_nStyle = ML_NONE;
m_nTextAlign = ML_TA_LEFT | ML_TA_TOP;
CStatic::GetWindowText(m_csText);
GetClientRect(&m_Rect);
m_nX = 0;
m_nY = 0;
m_nTextWidth = 0;
m_nTextHeight = 0;
m_Font.CreatePointFont(9*10, _T("宋体"));
m_MemDC.CreateCompatibleDC(pDC);
m_MemDC.SelectObject(&m_Font);
m_Bmp.CreateCompatibleBitmap(&m_MemDC,
m_nTextWidth,
m_nTextHeight);
m_MemDC.SelectObject(&m_Bmp);
SetTextAlign(m_nTextAlign); // 设置文本对齐方式
m_nStep = 4;
m_nTick = 200;
m_TextColor = RGB(255,255,255); // 文本为白色
m_BkColor = RGB(0,0,0); // 背景为黑色
Draw();
Invalidate();
}
// 定时器
void CHorizontalRollText::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
Invalidate();
CStatic::OnTimer(nIDEvent);
}
// 设置标号
void CHorizontalRollText::SetTick(UINT nTick)
{
if (nTick < 50 || nTick > 2000) // 有效范围是:50~200
{
return;
}
this->m_nTick = nTick;
if (this->m_nStyle != ML_NONE)
{
KillTimer((UINT)this);
SetTimer((UINT)this, m_nTick, NULL); // 设置定时器
}
}
// 设置步长
void CHorizontalRollText::SetStep(UINT nStep)
{
if (nStep < 1 || nStep > 10) // 有效范围是:1~10
{
return;
}
this->m_nStep = nStep;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -