您的位置:首页 > 其它

MFC 滚动字幕添加

2014-12-19 09:35 211 查看
实现文件

#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<=TE
dbe1
XT('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);

 }

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: