📄 vertialrolltext.cpp
字号:
// VertialRollText.cpp : implementation file
//
#include "stdafx.h"
#include "VertialRollText.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DISPLAY_TIMER_ID 150
/////////////////////////////////////////////////////////////////////////////
// CVertialRollText
// 初始化变量
CVertialRollText::CVertialRollText()
{
m_arColors[0] = RGB(255,255,255); // 颜色1
m_arColors[1] = RGB(230,230,0); // 颜色2
m_arColors[2] = RGB(255,255,0); // 颜色3
m_arColors[3] = RGB(0,255,255); // 颜色4
m_arColors[4] = RGB(255,255,255); // 颜色5
m_arTextHeight[0] = 26; // 文本高度1
m_arTextHeight[1] = 16; // 文本高度2
m_arTextHeight[2] = 16; // 文本高度3
m_arTextHeight[3] = 16; // 文本高度4
m_nCurrentFontHeight = m_arTextHeight[NORMAL_TEXT_HEIGHT];
m_arEscape[0] = '\t'; // 制表符
m_arEscape[1] = '\n'; // 换行
m_arEscape[2] = '\r'; // 回车
m_arEscape[3] = '^';
m_arDisplaySpeed[0] = 70;
m_arDisplaySpeed[1] = 40;
m_arDisplaySpeed[2] = 10;
m_nCurrentSpeed = 1;
m_nScrollAmount = -1;
m_bProcessingBitmap = FALSE;
m_ArrIndex = NULL;
m_nCounter = 1;
m_nClip = 0;
m_bFirstTime = TRUE;
m_bDrawText = FALSE;
m_bFirstTurn = TRUE;
m_nGradient = GRADIENT_NONE; // 倾斜度
m_bTransparent = FALSE; // 透明
m_nMaxWidth = 0;
m_nTimerOn = 0;
}
CVertialRollText::~CVertialRollText()
{
}
// 消息映射
BEGIN_MESSAGE_MAP(CVertialRollText, CStatic)
//{{AFX_MSG_MAP(CVertialRollText)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_WM_TIMER()
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVertialRollText message handlers
// 滚动文本
BOOL CVertialRollText::StartScrolling()
{
if (m_csList.IsEmpty()) // 列表为空
{
return FALSE;
}
if (m_BmpMain.m_hObject != NULL)
{
m_BmpMain.DeleteObject();
m_BmpMain.m_hObject = NULL;
}
m_nTimerOn = SetTimer(DISPLAY_TIMER_ID,
m_arDisplaySpeed[m_nCurrentSpeed],
NULL); // 设置定时器
ASSERT(m_nTimerOn != 0);
m_ArrIndex = m_csList.GetHeadPosition(); // 取得顶部位置
m_nCounter = 0;
m_nClip = 0;
m_bFirstTime = TRUE;
m_bDrawText = FALSE;
return TRUE;
}
// 停止滚动
void CVertialRollText::EndScrolling()
{
KillTimer( DISPLAY_TIMER_ID );
m_nTimerOn = 0;
if ( m_BmpMain.m_hObject != NULL )
{
m_BmpMain.DeleteObject(); // 删除不为空的对象
m_BmpMain.m_hObject = NULL;
}
return;
}
// 设定滚动文本
void CVertialRollText::SetRollText( LPCTSTR lpRollText,char delimiter )
{
char *str,*ptr1,*ptr2;
ASSERT(lpRollText);
if ( NULL == (str = strdup(lpRollText)) ) // 没有设置文本
{
return;
}
m_csList.RemoveAll(); // 清空列表
ptr1 = str;
while ((ptr2 = strchr(ptr1,delimiter)) != NULL)
{
*ptr2 = '\0';
m_csList.AddTail(ptr1); // 添加到列表最后
ptr1 = ptr2 + 1;
}
m_csList.AddTail(ptr1);
free(str); // 释放资源
m_ArrIndex = m_csList.GetHeadPosition(); // 取得顶部位置
m_nCounter = 1;
m_nClip = 0;
m_bFirstTime = TRUE;
m_bDrawText = FALSE;
return;
}
// 设定滚动文本
void CVertialRollText::SetRollText( UINT nID,char delimiter )
{
CString csRollText = _T("");
if ( !csRollText.LoadString(nID) ) // 上载字符串失败
{
return;
}
SetRollText( (LPCTSTR)csRollText, delimiter ); // 设置文本
return;
}
// 设定滚动速度
void CVertialRollText::SetSpeed( UINT nIndex, int nSpeed )
{
ASSERT( nIndex <= DISPLAY_FAST );
if ( nSpeed )
{
m_arDisplaySpeed[nIndex] = nSpeed; // 将速度值存入数组
}
m_nCurrentSpeed = nIndex; // 设置速度
return;
}
// 设定颜色
void CVertialRollText::SetColor(UINT nIndex, COLORREF col)
{
ASSERT(nIndex <= NORMAL_TEXT_COLOR);
m_arColors[nIndex] = col; // 将颜色存入数组
return;
}
// 设定文字的高度
void CVertialRollText::SetTextHeight( UINT nIndex, int nHeight )
{
ASSERT(nIndex <= NORMAL_TEXT_HEIGHT);
m_arTextHeight[nIndex] = nHeight; // 将文字的高度存入数组
return;
}
// 设定“溢出”
void CVertialRollText::SetEscape(UINT nIndex, char cEscape)
{
ASSERT(nIndex <= DISPLAY_BITMAP);
m_arEscape[nIndex] = cEscape; // 设置溢出
return;
}
// 设定倾斜度
void CVertialRollText::SetGradient(UINT nValue)
{
ASSERT(nValue <= GRADIENT_LEFT_LIGHT);
m_nGradient = nValue; // 设置倾斜度
return;
}
// 设定透明
void CVertialRollText::SetTransparent( BOOL bTransparent )
{
m_bTransparent = bTransparent; // 设置透明
return;
}
// 定时器
void CVertialRollText::OnTimer(UINT nIDEvent)
{
if ( nIDEvent != DISPLAY_TIMER_ID )
{
CStatic::OnTimer(nIDEvent);
return;
}
BOOL bCheck = FALSE;
if ( !m_bProcessingBitmap ) // 还没有处理位图
{
if ( 0 == m_nCounter++ % m_nCurrentFontHeight )
{
m_nCounter = 1;
m_csWork = m_csList.GetNext(m_ArrIndex); // 列表中获取
if (m_bFirstTurn)
{
bCheck = TRUE;
}
if (m_ArrIndex == NULL)
{
m_bFirstTurn = FALSE;
m_ArrIndex = m_csList.GetHeadPosition(); // 取得顶部位置
}
m_nClip = 0;
m_bDrawText = TRUE;
}
}
CClientDC dc( this ); // 设备上下文,即DC
CRect m_ScrollRect;
GetClientRect( &m_ScrollRect ); // 获得客户区
CRect m_ClientRect( m_ScrollRect );
m_ClientRect.left = ( m_ClientRect.Width() - m_nMaxWidth )/2;
m_ClientRect.right = m_ClientRect.left + m_nMaxWidth;
MoveInfo( &dc, m_ScrollRect, m_ClientRect, bCheck ); // 移动信息
AddBackGround( &dc, m_ScrollRect, m_ClientRect ); // 添加背景
CStatic::OnTimer(nIDEvent);
}
// 添加背景
void CVertialRollText::AddBackGround( CDC* pDC,
CRect& m_ScrollRect,
CRect& m_ClientRect )
{
CDC memDC;
memDC.CreateCompatibleDC( pDC ); // 创建内存DC
if ( m_bitmap.m_hObject == NULL )
{
CBitmap* pOldBitmap = memDC.SelectObject( &m_BmpMain );
pDC->BitBlt(0,
0,
m_ScrollRect.Width(), // 滚动区域的宽度
m_ScrollRect.Height(), // 滚动区域的高度
&memDC,
0,
0,
SRCCOPY // 拷贝方式
); // 将一幅位图从一个设备场景复制到另一个
memDC.SelectObject(pOldBitmap); // 替换旧位图
return;
}
CBitmap bitmap; // 位图实例
bitmap.CreateCompatibleBitmap( pDC, m_ClientRect.Width(), m_ClientRect.Height() );
CBitmap* pOldMemDCBitmap = memDC.SelectObject( &bitmap );
CDC tempDC; // 中间用的临时DC
tempDC.CreateCompatibleDC( pDC );
CBitmap* pOldTempDCBitmap = tempDC.SelectObject( &m_BmpMain );
memDC.BitBlt(0,
0,
m_ClientRect.Width(), // 客户区的宽度
m_ClientRect.Height(), // 客户区的高度
&tempDC,
m_ClientRect.left, // 客户区的左边
m_ClientRect.top, // 客户区的顶部
SRCCOPY // 拷贝方式
);
CDC maskDC; // 遮盖DC
maskDC.CreateCompatibleDC(pDC);
CBitmap maskBitmap; // 遮盖位图实例
// 创建单色位图
maskBitmap.CreateBitmap( m_ClientRect.Width(), m_ClientRect.Height(), 1, 1, NULL );
CBitmap* pOldMaskDCBitmap = maskDC.SelectObject( &maskBitmap );
memDC.SetBkColor(m_bTransparent? RGB(192,192,192): m_arColors[BACKGROUND_COLOR]);
maskDC.BitBlt(0,
0,
m_ClientRect.Width(), // 客户区的宽度
m_ClientRect.Height(), // 客户区的高度
&memDC,
0,
0,
SRCCOPY // 拷贝方式
); // 将一幅位图从一个设备场景复制到另一个
tempDC.SelectObject(pOldTempDCBitmap); // 替换旧位图
pOldTempDCBitmap = tempDC.SelectObject( &m_bitmap );
CDC imageDC; // 图像DC
CBitmap bmpImage; // 位图实例
imageDC.CreateCompatibleDC( pDC );
bmpImage.CreateCompatibleBitmap( pDC, m_ScrollRect.Width(), m_ScrollRect.Height() );
CBitmap* pOldImageDCBitmap = imageDC.SelectObject( &bmpImage );
if ( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
{
pDC->SelectPalette( &m_pal, FALSE );
pDC->RealizePalette();
imageDC.SelectPalette( &m_pal, FALSE ); // 选择调色板
}
for ( int i = 0; i < m_ScrollRect.right; i += m_cxBitmap )
{
for ( int j = 0; j < m_ScrollRect.bottom; j += m_cyBitmap )
{
imageDC.BitBlt(i,
j,
m_cxBitmap,
m_cyBitmap,
&tempDC,
0,
0,
SRCCOPY
); // 将一幅位图从一个设备场景复制到另一个
}
}
// 创建背景色为黑色,文本颜色为白色
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(0,
0,
m_ClientRect.Width(),
m_ClientRect.Height(),
&maskDC,
0,
0,
SRCAND
); // 将一幅位图从一个设备场景复制到另一个
// 创建背景色为白色,文本颜色为黑色
imageDC.SetBkColor(RGB(255,255,255));
imageDC.SetTextColor(RGB(0,0,0));
imageDC.BitBlt(m_ClientRect.left,
m_ClientRect.top,
m_ClientRect.Width(),
m_ClientRect.Height(),
&maskDC,
0,
0,
SRCAND
); // 将一幅位图从一个设备场景复制到另一个
// 合并背景和前景
imageDC.BitBlt(m_ClientRect.left,
m_ClientRect.top,
m_ClientRect.Width(),
m_ClientRect.Height(),
&memDC,
0,
0,
SRCPAINT
); // 将一幅位图从一个设备场景复制到另一个
// 画出最终的图像
pDC->BitBlt(0,
0,
m_ScrollRect.Width(),
m_ScrollRect.Height(),
&imageDC,
0,
0,
SRCCOPY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -