滚动文字实现已有很多方法
这个控件对 以前的滚动控件进行扩展,能够循环滚动消息,在鼠标停留在消息上时变为超链接
代码如下:
#pragma
once
#include
<
map
>
#include
<
vector
>
class
CScrollStatic :
public
CStatic
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
CScrollStatic()
: m_iExtend(0)
, m_iTotal(0)
, m_strText(_T("初始文字..."))
, m_colText(RGB(0, 0, 0))
, m_sHitMsg(_T(""))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_bmp.LoadBitmap(IDB_BK);
BITMAP bit;
m_bmp.GetBitmap(&bit);
m_iBackBmpWidth = bit.bmWidth;
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = 12;
lf.lfWeight = 400;
lf.lfCharSet = 134;
lf.lfPitchAndFamily = 2;
strcpy_s(lf.lfFaceName, LF_FACESIZE, "宋体");
m_font.CreateFontIndirect(&lf);
lf.lfUnderline = 1;
m_fontU.CreateFontIndirect(&lf);
m_hCursor = ::LoadCursor(NULL, IDC_HAND);
};
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
~CScrollStatic()...{ };
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
protected:
static const AFX_MSGMAP* PASCAL GetThisMessageMap()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
typedef CScrollStatic ThisClass;
static const AFX_MSGMAP_ENTRY _messageEntries[] =
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
static const AFX_MSGMAP messageMap =
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{ &CStatic::GetThisMessageMap, &_messageEntries[0] };
return &messageMap;
};
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
virtual const AFX_MSGMAP* GetMessageMap() const...{ return GetThisMessageMap(); };
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public:
afx_msg int CScrollStatic::OnCreate(LPCREATESTRUCT lpCreateStruct)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (CStatic::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1, 100, NULL);//滚动频率时间控制
SetTimer(2, 500, NULL);//滚动文字颜色时间控制
return 0;
}
afx_msg void CScrollStatic::OnTimer(UINT nIDEvent)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (nIDEvent == 2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (m_colText >= RGB(255, 255, 255))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_colText = RGB(0, 0, 0);
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_colText += RGB(1, 2, 1);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (nIDEvent == 1)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CDC* pDC = GetDC();
pDC->SelectObject(m_font);
CRect rect;
GetClientRect(rect);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (m_vMsg.size() == 0) // 没有消息时
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CSize size = pDC->GetTextExtent(m_strText);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (m_iExtend <= -size.cx)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_iExtend = rect.Width();
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_iExtend -= 1;
}
}
else // 有消息时逐条消息计算偏移
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int iCount = (int)m_vMsg.size();
for ( int iOffset(0), i(0); i < iCount; i++ )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MsgOut &msg = m_vMsg[i];
CSize size = pDC->GetTextExtent(msg.sMsg);
iOffset += size.cx + 20;
if (msg.iOffset < (rect.Width() > m_iTotal ?
-size.cx:rect.Width() - m_iTotal))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (i > 0)
msg.iOffset = m_vMsg[i-1].iOffset + size.cx + 20;
else
msg.iOffset = rect.Width();
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
msg.iOffset -= 1;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
}
Invalidate(FALSE);
ReleaseDC(pDC);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
afx_msg void CScrollStatic::OnPaint()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
CRect rc;
GetClientRect(rc);
CDC memDC, textDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(&m_bmp);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
textDC.CreateCompatibleDC(&dc);
CBitmap bmpBack;
bmpBack.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
textDC.SelectObject(&bmpBack);
textDC.FillSolidRect(rc, RGB(192, 192, 192));
textDC.SetBkMode(TRANSPARENT);
textDC.SetTextColor(m_colText);
textDC.SelectObject(&m_font);
if (m_vMsg.size() == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CSize size = textDC.GetTextExtent(m_strText);
textDC.TextOut(rc.left + m_iExtend, rc.top + (rc.Height() - size.cy)/2, m_strText);
}
else // 逐条消息输出
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
vMsg::iterator iter = m_vMsg.begin();
for ( ; iter != m_vMsg.end(); iter++ )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MsgOut msg = *iter;
CSize size = textDC.GetTextExtent(msg.sMsg);
CRect rect;
rect.CopyRect(rc);
rect.left += msg.iOffset;
rect.top += (rect.Height() - size.cy)/2;
rect.right = rect.left + size.cx;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if ( rect.right > rc.left ) //已超出
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
if (rect.PtInRect(pt))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
SetCapture();
KillTimer(1);
SetCursor(m_hCursor);
m_rcHitIn.CopyRect(rect);
textDC.SelectObject(&m_fontU);
m_sHitMsg = msg.sMsg;
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
textDC.SelectObject(&m_font);
}
textDC.TextOut(rect.left, rect.top, msg.sMsg);
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
dc.StretchBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, m_iBackBmpWidth, rc.Height(), SRCCOPY);
dc.TransparentBlt(0 ,0, rc.Width(), rc.Height(), &textDC, 0, 0, rc.Width(), rc.Height(), RGB(192, 192, 192));
memDC.DeleteDC();
textDC.DeleteDC();
bmpBack.DeleteObject();
}
afx_msg void OnMouseMove(UINT nFlags, CPoint point)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (!m_rcHitIn.PtInRect(point))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
SetTimer(1, 100, NULL);
ReleaseCapture();
}
}
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (!m_sHitMsg.IsEmpty())
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CStringW wStr = CA2W(m_sHitMsg);
int iLength = wStr.GetLength();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int i(0);
while (!iswdigit(wStr.GetAt(i++)) && i <= iLength);
int iBeg = i;
while (iswdigit(wStr.GetAt(i++)) && i <= iLength);
int iEnd = i;
CString sID = CW2A(wStr.Mid(iBeg-1, iEnd - iBeg));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
wrkMap::iterator mapiter = m_mapWork.find(m_sHitMsg);
if (mapiter != m_mapWork.end())
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//在此进行超链接处理,处理后移出消息
m_mapWork.erase(mapiter);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
vMsg::iterator iter = m_vMsg.begin();
for ( int i(0); iter != m_vMsg.end(); i++, iter++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MsgOut &msg = *iter;
if (msg.sMsg == m_sHitMsg)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int iPreOffset = msg.iOffset;
CDC * pDC = GetDC();
pDC->SelectObject(m_font);
CSize sz = pDC->GetTextExtent(m_vMsg[i].sMsg);
m_iTotal -= sz.cx + 20;
CRect rect;
GetClientRect(rect);
m_vMsg.erase(iter);
int iCount = (int) m_vMsg.size();
for (; i < iCount; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
sz = pDC->GetTextExtent(m_vMsg[i].sMsg);
int iTemp = m_vMsg[i].iOffset;
m_vMsg[i].iOffset = iPreOffset;
iPreOffset = iTemp;
}
break;
}
}
}
}
protected:
CFont m_font, m_fontU;
int m_iExtend;
int m_iTotal;
CString m_strText;
CBitmap m_bmp;
int m_iBackBmpWidth;
COLORREF m_colText;
struct MsgOut
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CString sMsg;
int iOffset;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
MsgOut() : sMsg(_T("")), iOffset(0)...{};
};
typedef std::map<CString, CString> wrkMap;
wrkMap m_mapWork;
typedef std::vector<MsgOut> vMsg;
vMsg m_vMsg;
CRect m_rcHitIn;
HCURSOR m_hCursor;
CString m_sHitMsg;
public:
void AddText(CString sText, CString sWorkID) // 添加消息
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
CRect rect;
GetClientRect(rect);
CDC * pDC = GetDC();
pDC->SelectObject(m_font);
CSize sz = pDC->GetTextExtent(sText);
MsgOut msg;
msg.sMsg = sText;
if (m_vMsg.size() > 0)
msg.iOffset = ((MsgOut)*m_vMsg.rbegin()).iOffset + sz.cx + 20;
else
msg.iOffset = rect.Width();
m_iTotal += sz.cx + 20;
m_vMsg.push_back(msg);
m_mapWork[sText] = sWorkID;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (m_vMsg.size() > 10) //保留10条信息
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
wrkMap::iterator iter = m_mapWork.find(((MsgOut)*m_vMsg.begin()).sMsg);
if (iter != m_mapWork.end())
m_mapWork.erase(iter);
m_vMsg.erase(m_vMsg.begin());
m_iTotal -= sz.cx + 20;
}
ReleaseDC(pDC);
}
}
;