MFC 滚动字幕添加

实现文件

#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);
 }

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值