翻译|其它|编辑:郝浩|2007-10-26 13:49:48.000|阅读 1086 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
滚动文字实现已有很多方法
这个控件对 以前的滚动控件进行扩展,能够循环滚动消息,在鼠标停留在消息上时变为超链接
代码如下:
#pragma once
#include <map>
#include <vector>
class CScrollStatic : public CStatic
...{
public:
CScrollStatic()
: m_iExtend(0)
, m_iTotal(0)
, m_strText(_T("初始文字..."))
, m_colText(RGB(0, 0, 0))
, m_sHitMsg(_T(""))
...{
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);
};
~CScrollStatic()...{ };
protected:
static const AFX_MSGMAP* PASCAL GetThisMessageMap()
...{
typedef CScrollStatic ThisClass;
static const AFX_MSGMAP_ENTRY _messageEntries[] =
...{
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
...{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
static const AFX_MSGMAP messageMap =
...{ &CStatic::GetThisMessageMap, &_messageEntries[0] };
return &messageMap;
};
virtual const AFX_MSGMAP* GetMessageMap() const...{ return GetThisMessageMap(); };
public:
afx_msg int CScrollStatic::OnCreate(LPCREATESTRUCT lpCreateStruct)
...{
if (CStatic::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1, 100, NULL);//滚动频率时间控制
SetTimer(2, 500, NULL);//滚动文字颜色时间控制
return 0;
}
afx_msg void CScrollStatic::OnTimer(UINT nIDEvent)
...{
if (nIDEvent == 2)
...{
if (m_colText >= RGB(255, 255, 255))
...{
m_colText = RGB(0, 0, 0);
}
else
...{
m_colText += RGB(1, 2, 1);
}
}
if (nIDEvent == 1)
...{
CDC* pDC = GetDC();
pDC->SelectObject(m_font);
CRect rect;
GetClientRect(rect);
if (m_vMsg.size() == 0) // 没有消息时
...{
CSize size = pDC->GetTextExtent(m_strText);
if (m_iExtend <= -size.cx)
...{
m_iExtend = rect.Width();
}
else
...{
m_iExtend -= 1;
}
}
else // 有消息时逐条消息计算偏移
...{
int iCount = (int)m_vMsg.size();
for ( int iOffset(0), i(0); i < iCount; i++ )
...{
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))
...{
if (i > 0)
msg.iOffset = m_vMsg[i-1].iOffset + size.cx + 20;
else
msg.iOffset = rect.Width();
}
else
...{
msg.iOffset -= 1;
}
}
}
Invalidate(FALSE);
ReleaseDC(pDC);
}
}
afx_msg void CScrollStatic::OnPaint()
...{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
CRect rc;
GetClientRect(rc);
CDC memDC, textDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(&m_bmp);
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)
...{
CSize size = textDC.GetTextExtent(m_strText);
textDC.TextOut(rc.left + m_iExtend, rc.top + (rc.Height() - size.cy)/2, m_strText);
}
else // 逐条消息输出
...{
vMsg::iterator iter = m_vMsg.begin();
for ( ; iter != m_vMsg.end(); iter++ )
...{
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;
if ( rect.right > rc.left ) //已超出
...{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
if (rect.PtInRect(pt))
...{
SetCapture();
KillTimer(1);
SetCursor(m_hCursor);
m_rcHitIn.CopyRect(rect);
textDC.SelectObject(&m_fontU);
m_sHitMsg = msg.sMsg;
}
else
...{
textDC.SelectObject(&m_font);
}
textDC.TextOut(rect.left, rect.top, msg.sMsg);
}
}
}
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)
...{
if (!m_rcHitIn.PtInRect(point))
...{
SetTimer(1, 100, NULL);
ReleaseCapture();
}
}
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point)
...{
if (!m_sHitMsg.IsEmpty())
...{
CStringW wStr = CA2W(m_sHitMsg);
int iLength = wStr.GetLength();
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));
wrkMap::iterator mapiter = m_mapWork.find(m_sHitMsg);
if (mapiter != m_mapWork.end())
...{
//在此进行超链接处理,处理后移出消息
m_mapWork.erase(mapiter);
}
vMsg::iterator iter = m_vMsg.begin();
for ( int i(0); iter != m_vMsg.end(); i++, iter++)
...{
MsgOut &msg = *iter;
if (msg.sMsg == m_sHitMsg)
...{
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++)
...{
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
...{
CString sMsg;
int iOffset;
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) // 添加消息
...{
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;
if (m_vMsg.size() > 10) //保留10条信息
...{
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);
}
};
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:csdn