实现文件
#include "Stdafx.h"
#include "SkinScroll.h"
#include "SkinRenderManager.h"
#include "SkinResourceManager.h"
#include "Resource.h"
#define FONT_HEIGHT 20 //字体高度
#define FONT_WIDTH 14 //字体宽度
#define IDC_TM_SPEED 101 //定时器标示
#define IDC_TM_SPACE 102 //间隔时间
#define IDC_TM_BREAK 103 //中断时间
#define TIME_BREAK 3000 //中断时间
//超链接定义
#define MOUSE_DOWN_LINK RGB(255,0,0) //鼠标弹起
#define MOUSE_MOVE_LINK RGB(0,255,0) //鼠标移动
#define MOUSE_NULL_LINK RGB(0,0,255) //鼠标无动作
BEGIN_MESSAGE_MAP(CSkinScroll, CWnd)
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_SIZE()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
CSkinScroll::CSkinScroll(void)
{
m_bLeftBTDown=false;
m_bSidewards=false;
m_bBreakScroll=false;
m_crFont=RGB(198,57,1);
m_crBack=RGB(241,197,126);
m_wNowScroll=0;
m_wRemoveTmp=-1;
m_pszResource=NULL;
m_hResInstance=NULL;
m_wDrawMode=DRAW_SPREAD;
m_bRenderImage=false;
m_wScrollSpeed=0;
}
CSkinScroll::~CSkinScroll(void)
{
}
//控件绑定
VOID CSkinScroll::PreSubclassWindow()
{
__super::PreSubclassWindow();
return;
}
//重画函数
void CSkinScroll::OnPaint()
{
CPaintDC dc(this);
//获取位置
CRect ClientRect;
GetClientRect(&ClientRect);
CSkinRenderManager * pSkinRenderManager=CSkinRenderManager::GetInstance();
COLORREF cREF;
if(pSkinRenderManager != NULL)
{
COLORHSB cHSB=pSkinRenderManager->RGBToHSB(m_crBack);
cREF=pSkinRenderManager->RenderColor(cHSB.S,cHSB.B,true);
if(cREF==RGB(0,0,0))
{
cREF=m_crBack;
}
}
else
{
cREF=m_crBack;
}
//建立缓冲图
CDC BackFaceDC;
CBitmap BufferBmp;
BufferBmp.CreateCompatibleBitmap(&dc,ClientRect.Width(),ClientRect.Height());
BackFaceDC.CreateCompatibleDC(&dc);
BackFaceDC.SelectObject(&BufferBmp);
BackFaceDC.FillSolidRect(ClientRect,cREF);
BackFaceDC.SelectObject(m_cDFontEx);
BackFaceDC.SetBkMode(TRANSPARENT);
BackFaceDC.SetTextColor(m_crFont);
//判断是否绘画背景
if(m_pszResource!=NULL && m_hResInstance!=NULL)
{
CBitImage ImageBack;
ImageBack.LoadFromResource(m_hResInstance,m_pszResource);
if(m_bRenderImage==true)
{
pSkinRenderManager->RenderImage(ImageBack);
}
DrawViewImage(&BackFaceDC,ImageBack,m_wDrawMode);
}
INT nFlags;
if(m_bSidewards==true)
{
nFlags=DT_VCENTER|DT_LEFT|DT_SINGLELINE;
}
else
{
nFlags=DT_LEFT|DT_TOP|DT_SINGLELINE;
}
//校验参数
if(m_tgScrollString.szString==NULL)
{
return ;
}
//绘画文字
BackFaceDC.DrawText(m_tgScrollString.szString,&m_tgScrollString.rcRect,nFlags);
//绘画URL
BackFaceDC.SelectObject(m_cDURLEx);
if(m_tcHyperLink.GetCount()>0)
{
for(WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
BackFaceDC.SetTextColor(m_tcHyperLink[i].crLink);
CRect rcRect=m_tcHyperLink[i].rcRect;
TCHAR szBuffer[255] = TEXT("");
_sntprintf(szBuffer,sizeof(szBuffer),TEXT("%s"),m_tcHyperLink[i].szLink);
BackFaceDC.DrawText(szBuffer,&m_tcHyperLink[i].rcRect,nFlags);
}
}
//绘画界面
dc.BitBlt(0,0,ClientRect.Width(),ClientRect.Height(),&BackFaceDC,0,0,SRCCOPY);
}
//设置光标
BOOL CSkinScroll::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
{
//获取鼠标
POINT point;
GetCursorPos(&point);
ScreenToClient(&point);
if(m_tgScrollString.rcRect.PtInRect(point)==TRUE)
{
//设置光标
HINSTANCE hResInstance=GetModuleHandle(SKIN_CONTROL_DLL_NAME);
SetCursor(LoadCursor(hResInstance,MAKEINTRESOURCE(IDC_SKIN_CURSOR)));
}
else
{
SetCursor(LoadCursor(NULL,IDC_ARROW));
}
return __super::OnSetCursor(pWnd, nHitTest, message);
}
int CSkinScroll::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//创建控件
SetWindowPos(this,0,0,lpCreateStruct->cx,lpCreateStruct->cy,NULL);
m_cDFontEx.CreateFont(-FONT_WIDTH,0,0,0,400,0,0,0,0,3,2,ANTIALIASED_QUALITY,2,TEXT("宋体") );
m_cDURLEx.CreateFont(-FONT_WIDTH,0,0,0,400,0,TRUE,0,0,3,2,ANTIALIASED_QUALITY,2,TEXT("宋体") );
return 0;
}
void CSkinScroll::OnTimer(UINT nIDEvent)
{
//关闭倒计时
if(IDC_TM_SPEED==nIDEvent && m_bBreakScroll==false)
{
//获取鼠标位置
CPoint point;
GetCursorPos(&point);
ScreenToClient(&point);
//竖向滚动
if(m_bSidewards==false)
{
CRect ClientRect;
GetClientRect(&ClientRect);
m_tgScrollString.rcRect.OffsetRect(0,1);
for(WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
m_tcHyperLink[i].rcRect.OffsetRect(0,1);
//检索位置恢复颜色
if(m_tcHyperLink[i].rcRect.PtInRect(point) == FALSE && m_tcHyperLink[i].crLink==MOUSE_MOVE_LINK)
{
m_tcHyperLink[i].crLink=MOUSE_NULL_LINK;
}
}
if(m_tgScrollString.rcRect.top>=ClientRect.Height())
{
//判断当前字符是否被删除
if(m_wRemoveTmp != m_wNowScroll)
{
m_wNowScroll++;
m_wRemoveTmp=-1;
}
if(m_wNowScroll>(m_tcFontInfo.GetCount()-1))
{
m_wNowScroll=0;
}
if(m_tcFontInfo.GetCount()==0)
{
PrepareScroll(NULL);
m_wNowScroll=-1;
}
else
{
PrepareScroll(m_tcFontInfo[m_wNowScroll]);
}
}
Invalidate(FALSE);
}
//横向滚动
else
{
m_tgScrollString.rcRect.OffsetRect(-1,0);
for(WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
//检索位置恢复颜色
if(m_tcHyperLink[i].rcRect.PtInRect(point) == FALSE && m_tcHyperLink[i].crLink==MOUSE_MOVE_LINK)
{
m_tcHyperLink[i].crLink=MOUSE_NULL_LINK;
}
m_tcHyperLink[i].rcRect.OffsetRect(-1,0);
}
CRect ClientRect;
GetClientRect(&ClientRect);
if(m_tgScrollString.rcRect.right<0)
{
//判断当前字符是否被删除
if(m_wRemoveTmp != m_wNowScroll)
{
m_wNowScroll++;
m_wRemoveTmp=-1;
}
if(m_wNowScroll>(m_tcFontInfo.GetCount()-1))
{
m_wNowScroll=0;
}
if(m_tcFontInfo.GetCount()==0)
{
PrepareScroll(NULL);
m_wNowScroll=0;
}
else
{
PrepareScroll(m_tcFontInfo[m_wNowScroll]);
}
}
Invalidate(FALSE);
}
}
if(IDC_TM_SPACE==nIDEvent)
{
}
if(IDC_TM_BREAK == nIDEvent)
{
m_bBreakScroll=false;
for (WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
m_tcHyperLink[i].crLink=MOUSE_NULL_LINK;
}
}
return;
}
//设置内容
void CSkinScroll::SetScrollString(TCHAR *szSourse)
{
m_tcFontInfo.Add(szSourse);
}
//移除内容
bool CSkinScroll::RemoveString(WORD nCount,bool bRightNow/*=false*/)
{
//校验参数
ASSERT(nCount >=0 && nCount < m_tcFontInfo.GetCount());
if(nCount <0 || nCount >= m_tcFontInfo.GetCount())
{
return false;
}
//判断参数
if(bRightNow==true)
{
if(nCount==m_wNowScroll)
{
m_tcFontInfo.RemoveAt(nCount);
if(m_wNowScroll>(m_tcFontInfo.GetCount()-1))
{
m_wNowScroll=0;
}
PrepareScroll(m_tcFontInfo[m_wNowScroll]);
}
else
{
m_tcFontInfo.RemoveAt(nCount);
}
}
else
{
if(nCount==m_wNowScroll)
{
m_wRemoveTmp=bRightNow;
}
else
{
m_tcFontInfo.RemoveAt(nCount);
}
}
return true;
}
//移除内容
void CSkinScroll::RemoveAll(bool bRightNow/*=false*/)
{
m_tcFontInfo.RemoveAll();
if(bRightNow == true)
{
PrepareScroll(NULL);
}
}
//开始滚动
void CSkinScroll::StartScroll(bool bSidwards/*=false*/,WORD wScrollSpeed/*=TIME_SPEED*/,WORD wStartPoistion/*=1000*/)
{
//滚动的方向
m_bSidewards=bSidwards;
//滚动字幕的位置
if(wStartPoistion>m_tcFontInfo.GetCount() || wStartPoistion<0)
{
m_wNowScroll=0;
}
else
{
m_wNowScroll=wStartPoistion;
}
//准备滚动
if(m_tcFontInfo.GetCount()<=0)
{
PrepareScroll(NULL);
}
else
{
PrepareScroll(m_tcFontInfo[m_wNowScroll]);
}
if(wScrollSpeed<0)
{
m_wScrollSpeed=TIME_SPEED;
}
else
{
m_wScrollSpeed=wScrollSpeed;
}
//开始滚动
SetTimer(IDC_TM_SPEED,m_wScrollSpeed,NULL);
}
BOOL CSkinScroll::PreCreateWindow(CREATESTRUCT& cs)
{
// 创建自己的窗口类,窗口不设置光标,以便根据需要进行设置
if (cs.lpszClass == NULL)
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS);
return CWnd::PreCreateWindow(cs);
}
//鼠标按下
void CSkinScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
__super::OnLButtonDown(nFlags,point);
//整个字符串
if(m_tgScrollString.rcRect.PtInRect(point))
{
m_bBreakScroll=true;
//超链接位置判断
for (WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
if(m_tcHyperLink[i].rcRect.PtInRect(point))
{
m_tcHyperLink[i].crLink=MOUSE_DOWN_LINK;
Invalidate(FALSE);
break;
}
}
SetTimer(IDC_TM_BREAK,TIME_BREAK,NULL);
}
}
//鼠标弹起
void CSkinScroll::OnLButtonUp(UINT nFlags, CPoint point)
{
__super::OnLButtonUp(nFlags, point);
m_bBreakScroll=false;
//超链接位置判断
for (WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
//进入链接
if(m_tcHyperLink[i].rcRect.PtInRect(point) && m_tcHyperLink[i].crLink==MOUSE_DOWN_LINK)
{
ShellExecute(NULL, NULL, m_tcHyperLink[i].szLink, NULL, NULL, SW_SHOWNORMAL);
}
m_tcHyperLink[i].crLink=MOUSE_NULL_LINK;
}
Invalidate(FALSE);
KillTimer(IDC_TM_BREAK);
}
//鼠标移动消息
void CSkinScroll::OnMouseMove(UINT nFlags,CPoint point)
{
__super::OnMouseMove(nFlags, point);
//定义变量
bool bIsInvaliDate=false;
if(m_tgScrollString.rcRect.PtInRect(point))
{
m_bBreakScroll=true;
SetTimer(IDC_TM_BREAK,TIME_BREAK,NULL);
}
else
{
KillTimer(IDC_TM_BREAK);
m_bBreakScroll=false;
}
for (WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
//恢复变量
if(m_tcHyperLink[i].crLink != MOUSE_NULL_LINK && m_tcHyperLink[i].crLink != MOUSE_DOWN_LINK)
{
m_tcHyperLink[i].crLink=MOUSE_NULL_LINK;
bIsInvaliDate=true;
}
if(m_tcHyperLink[i].rcRect.PtInRect(point) && m_tcHyperLink[i].crLink != MOUSE_DOWN_LINK)
{
m_tcHyperLink[i].crLink=MOUSE_MOVE_LINK;
bIsInvaliDate=true;
}
}
if(bIsInvaliDate == true)
{
Invalidate(FALSE);
}
}
//鼠标左键双击
void CSkinScroll::OnLButtonDblClk(UINT nFlags,CPoint point)
{
__super::OnLButtonDblClk(nFlags,point);
}
VOID CSkinScroll::OnSize(UINT nType, INT cx, INT cy)
{
__super::OnSize(nType, cx, cy);
//最小化时滚动字幕未出现时重设
if(m_tgScrollString.szString!=NULL && m_tgScrollString.rcRect.left>cx && m_tcFontInfo.GetCount()!=0)
{
PrepareScroll(m_tcFontInfo[m_wNowScroll]);
}
Invalidate(FALSE);
}
//获取字符长度
int CSkinScroll::GetCharLength(TCHAR chInfo, int nWidth)
{
if( chInfo >= 0xA0 )//全角 中文
{
return nWidth;
}
else //半角 英文
{
return nWidth/2;
}
}
//字符判断
bool CSkinScroll::EfficacyUrlChar(TCHAR chChar)
{
//特殊字符
if (chChar==TEXT('.')) return true;
if (chChar==TEXT('=')) return true;
if (chChar==TEXT('+')) return true;
if (chChar==TEXT('?')) return true;
if (chChar==TEXT('#')) return true;
if (chChar==TEXT('%')) return true;
if (chChar==TEXT('/')) return true;
if (chChar==TEXT(':')) return true;
if (chChar==TEXT('&')) return true;
//字符范围
if ((chChar>=TEXT('a'))&&(chChar<=TEXT('z'))) return true;
if ((chChar>=TEXT('A'))&&(chChar<=TEXT('Z'))) return true;
if ((chChar>=TEXT('0'))&&(chChar<=TEXT('9'))) return true;
return false;
}
//获取URL
WORD CSkinScroll::GetHypeLink(LPCTSTR pszString)
{
//搜索变量
LPCTSTR pszHttp=TEXT("http://");
const INT nHttpLength=lstrlen(pszHttp);
const INT nStringLength=lstrlen(pszString);
INT nLenth=0; //字符长度
//索引定义
INT nStringStart=0;
INT nStringPause=0;
INT nCount=0;
//字符解释
for (INT i=0;i<nStringLength;i++)
{
nLenth+=GetCharLength(pszString[i],FONT_WIDTH);
//变量定义
INT nUrlPause=i;
//地址判断
if (((i+nHttpLength)<nStringLength)&&(memcmp(&pszString[i],pszHttp,nHttpLength*sizeof(TCHAR))==0))
{
//设置索引
nUrlPause=i+nHttpLength;
//地址搜索
while (nUrlPause<nStringLength)
{
//字符判断
if (EfficacyUrlChar(pszString[nUrlPause])==true)
{
nUrlPause++;
continue;
}
break;
}
}
//终止字符
if (nUrlPause<=(i+nHttpLength)) nStringPause=(i+1);
//插入字符
if ((i==(nStringLength-1))||(nUrlPause>(i+nHttpLength)))
{
//普通字符
if (nStringPause>nStringStart)
{
//获取缓冲
CString strNormalString;
LPTSTR pszNormalString=strNormalString.GetBuffer(nStringPause-nStringStart+1);
//拷贝字符
pszNormalString[nStringPause-nStringStart]=0;
CopyMemory(pszNormalString,&pszString[nStringStart],(nStringPause-nStringStart)*sizeof(TCHAR));
//释放缓冲
strNormalString.ReleaseBuffer();
}
//连接地址
if (nUrlPause>(i+nHttpLength))
{
//获取缓冲
CString strUrlString;
LPTSTR pszUrlString=strUrlString.GetBuffer((nUrlPause-i)+1);
//拷贝字符
pszUrlString[nUrlPause-i]=0;
CopyMemory(pszUrlString,&pszString[i],(nUrlPause-i)*sizeof(TCHAR));
//释放缓冲
strUrlString.ReleaseBuffer();
//添加超链接
tagHyperLink tcHyperLink;
CopyMemory(tcHyperLink.szLink,pszUrlString,255);
tcHyperLink.crLink=MOUSE_NULL_LINK;
//设置位置
INT nHypeLink=0;
for(WORD j=0;j<_tcslen(tcHyperLink.szLink);j++)
{
nHypeLink+=GetCharLength(tcHyperLink.szLink[j],FONT_WIDTH);
}
tcHyperLink.rcRect=CRect(nLenth,0,nLenth+nHypeLink,0);
tcHyperLink.wNum=i;
m_tcHyperLink.Add(tcHyperLink);
//超链接数目
nCount++;
//矫正位置
nLenth=nLenth+nHypeLink+GetCharLength(TEXT('\0'),FONT_WIDTH);
}
//设置索引
nStringStart=__max(i,nUrlPause);
}
//设置索引
i+=(nUrlPause-i);
}
return nCount;
}
//滚动准备
WORD CSkinScroll::PrepareScroll(LPCTSTR pszString)
{
//获取位置
CRect ClientRect;
GetClientRect(&ClientRect);
//恢复变量
m_tcHyperLink.RemoveAll();
ZeroMemory(&m_tgScrollString,sizeof(m_tgScrollString));
if(pszString!=NULL)
{
CopyMemory(m_tgScrollString.szString,pszString,sizeof(m_tgScrollString.szString));
}
else
{
return TRUE;
}
//设定字符长度
INT nLenth=0;
for(WORD i=0;i<_tcslen(pszString);i++)
{
nLenth+= GetCharLength(pszString[i], FONT_WIDTH);
}
m_tgScrollString.nLenth=nLenth;
GetHypeLink(pszString);
if(m_bSidewards==false)
{
m_tgScrollString.rcRect=CRect((ClientRect.Width()-m_tgScrollString.nLenth)/2,-FONT_HEIGHT,ClientRect.Width(),0);
}
else
{
m_tgScrollString.rcRect=CRect(ClientRect.Width(),5,ClientRect.Width()+m_tgScrollString.nLenth,ClientRect.Height()-5);
}
//配置位置
for(WORD i=0;i<m_tcHyperLink.GetCount();i++)
{
m_tcHyperLink[i].rcRect.left+=(m_tgScrollString.rcRect.left-GetCharLength(TEXT('\0'),FONT_WIDTH));
m_tcHyperLink[i].rcRect.right+=(m_tgScrollString.rcRect.left-GetCharLength(TEXT('\0'),FONT_WIDTH));
m_tcHyperLink[i].rcRect.top+=m_tgScrollString.rcRect.top;
m_tcHyperLink[i].rcRect.bottom+=m_tgScrollString.rcRect.bottom;
}
return TRUE;
}
//加载位图
bool CSkinScroll::SetScrollImage(UINT uBitmapID, HINSTANCE hResInstance, bool bRenderImage, BYTE wDrawMode/*=DRAW_SPREAD*/)
{
//设置变量
m_bRenderImage=bRenderImage;
//设置资源
m_hResInstance=hResInstance;
m_pszResource=MAKEINTRESOURCE(uBitmapID);
m_wDrawMode=wDrawMode;
//更新窗口
if (m_hWnd!=NULL)
{
RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_UPDATENOW|RDW_ERASENOW);
}
return true;
}
//绘画背景
VOID CSkinScroll::DrawViewImage(CDC * pDC, CBitImage & BitImage, BYTE cbDrawMode)
{
//获取位置
CRect rcClient;
GetClientRect(&rcClient);
//无效区域
CRect rcDirty;
pDC->GetClipBox(&rcDirty);
//绘画位图
switch (cbDrawMode)
{
case DRAW_SPREAD: //平铺模式
{
//加载资源
INT nImageWidth=BitImage.GetWidth();
INT nImageHeight=BitImage.GetHeight();
//绘画位图
for (INT nXPos=0;nXPos<rcClient.right;nXPos+=nImageWidth)
{
for (INT nYPos=0;nYPos<rcClient.bottom;nYPos+=nImageHeight)
{
bool bIntersect=BitImage.IsRectIntersect(rcDirty,nXPos,nYPos,nImageWidth,nImageHeight);
if (bIntersect==true) BitImage.BitBlt(pDC->m_hDC,nXPos,nYPos);
}
}
return;
}
case DRAW_CENTENT: //居中模式
{
//变量定义
INT nImageWidth=BitImage.GetWidth();
INT nImageHeight=BitImage.GetHeight();
//位置计算
INT nXPos=(rcClient.Width()-BitImage.GetWidth())/2;
INT nYPos=(rcClient.Height()-BitImage.GetHeight())/2;
//绘画位图
bool bIntersect=BitImage.IsRectIntersect(rcDirty,nXPos,nYPos,nImageWidth,nImageHeight);
if (bIntersect==true) BitImage.BitBlt(pDC->m_hDC,nXPos,nYPos);
return;
}
case DRAW_ELONGGATE: //拉伸模式
{
//变量定义
INT nImageWidth=BitImage.GetWidth();
INT nImageHeight=BitImage.GetHeight();
//绘画位图
bool bIntersect=BitImage.IsRectIntersect(rcDirty,0,0,rcClient.Width(),rcClient.Height());
if (bIntersect==true) BitImage.StretchBlt(pDC->m_hDC,0,0,rcClient.Width(),rcClient.Height(),0,0,nImageWidth,nImageHeight);
return;
}
}
return;
}
//设置背景颜色
void CSkinScroll::SetBackColor(COLORREF crBackColor/*=RGB(241,197,126)*/)
{
m_crBack=crBackColor;
Invalidate(FALSE);
}
//设置字体颜色
void CSkinScroll::SetFontColor(COLORREF crFontColor/*=RGB(198,57,1)*/)
{
m_crFont=crFontColor;
Invalidate(FALSE);
}
头文件
#ifndef SKIN_SCROLL_CLASS
#define SKIN_SCROLL_CLASS
#pragma once
#include "SkinControlHead.h"
//绘画模式
#define DRAW_SPREAD 0 //平铺模式
#define DRAW_CENTENT 1 //居中模式
#define DRAW_ELONGGATE 2 //拉伸模式
#define TIME_SPEED 50 //滚动速度
//滚动文字
struct tagFontInfo
{
TCHAR szString[255]; //滚动字幕
CRect rcRect; //位置信息
INT nLenth; //字符长度
};
//超链接判断
struct tagHyperLink
{
TCHAR szLink[255]; //链接字符
WORD wNum; //位置信息
CRect rcRect; //所处位置
COLORREF crLink; //当前颜色
};
class SKIN_CONTROL_CLASS CSkinScroll :public CWnd
{
public:
CSkinScroll(void);
~CSkinScroll(void);
private:
CWHArray<CString> m_tcFontInfo; //字幕信息
CWHArray<tagHyperLink> m_tcHyperLink; //当前滚动的超链接
tagFontInfo m_tgScrollString; //当前滚动字幕
bool m_bLeftBTDown; //左键按下
CFont m_cDFontEx; //定义字体
CFont m_cDURLEx; //定义字体
COLORREF m_crFont; //字体颜色
COLORREF m_crBack; //背景颜色
WORD m_wNowScroll; //当前滚动的位置
WORD m_wRemoveTmp; //删除选择
//附加配置
private:
bool m_bSidewards; //横向滚动
WORD m_wTimeSpace; //间隔时间
bool m_bBreakScroll; //暂停标志
WORD m_wScrollSpeed; //滚动速度
//背景资源
private:
LPCTSTR m_pszResource; //资源信息
HINSTANCE m_hResInstance; //资源句柄
BYTE m_wDrawMode; //绘画方式
bool m_bRenderImage; //渲染背景
//继承函数
public:
//解决光标闪烁问题
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//控件绑定
virtual VOID PreSubclassWindow();
//附加函数
public:
//获取字符长度
static int GetCharLength(TCHAR chInfo, int nWidth);
//获取URL
WORD GetHypeLink(LPCTSTR pszString);
//字符判断
bool EfficacyUrlChar(TCHAR chChar);
//滚动准备
WORD PrepareScroll(LPCTSTR pszString);
//加载位图
public:
//加载背景图
bool SetScrollImage(UINT uBitmapID, HINSTANCE hResInstance, bool bRenderImage, BYTE wDrawMode=DRAW_SPREAD);
//绘画背景
VOID DrawViewImage(CDC * pDC, CBitImage & BitImage, BYTE cbDrawMode);
//设置接口
public:
//设置内容
void SetScrollString(TCHAR* szSourse);
//开始滚动
void StartScroll(bool bSidwards=false,WORD wScrollSpeed=TIME_SPEED,WORD wStartPoistion=0);
//移除内容
bool RemoveString(WORD nCount,bool bRightNow=false);
//移除内容
void RemoveAll(bool bRightNow=false);
//设置背景颜色
void SetBackColor(COLORREF crBackColor=RGB(241,197,126));
//设置字体颜色
void SetFontColor(COLORREF crFontColor=RGB(198,57,1));
//消息映射
public:
//重画函数
afx_msg void OnPaint();
//设置光标
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
//创建函数
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//时间消息
afx_msg void OnTimer(UINT nIDEvent);
//鼠标左键消息
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//鼠标左键消息
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//鼠标移动消息
afx_msg void OnMouseMove(UINT nFlags,CPoint point);
//鼠标双击消息
afx_msg void OnLButtonDblClk(UINT nFlags,CPoint point);
//窗口大小
afx_msg VOID CSkinScroll::OnSize(UINT nType, INT cx, INT cy);
DECLARE_MESSAGE_MAP()
};
#endif
渲染可以根据需要从代码中去掉
使用时在父窗口创建时配置属性
CRect rcClient;
GetClientRect(&rcClient);
m_SkinScroll.Create(NULL,NULL,WS_VISIBLE|WS_CHILD,CRect(430,95,rcClient.Width()-240,135),this,6);
m_SkinScroll.SetScrollString(TEXT("温馨提示:http://www.hao123.com/?tn=91800134这个http://www.sohu.com/仅仅是一个http://www.sohu.com/测试"));
m_SkinScroll.SetScrollString(TEXT("温馨提示2"));
m_SkinScroll.SetScrollString(TEXT("温馨提示3"));
m_SkinScroll.SetScrollImage(IDB_ITEM_FRAME_TM,hInstance,true);
//根据需要开始滚动
m_SkinScroll.StartScroll(true);
//在调整位置的地方添加
if(m_SkinScroll.GetSafeHwnd()!=NULL)
{
m_SkinScroll.SetWindowPos(NULL,rcScroll.left,rcScroll.top,rcScroll.Width(),rcScroll.Height(),NULL);
}