带超链接的循环滚动静态控件

翻译|其它|编辑:郝浩|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

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP