我做的,不一定完善:#if !defined(AFX_MARQUEEPANEL_H__2C011862_B3B8_11D3_A106_0080ADAB03DD__INCLUDED_)
#define AFX_MARQUEEPANEL_H__2C011862_B3B8_11D3_A106_0080ADAB03DD__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MarqueePanel.h : header file
///////////////////////////////////////////////////////////////////////////////
// CMarqueePanel windowclass CMarqueePanel : public CStatic
{
// Construction
public:
CMarqueePanel();// Attributes
public:// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMarqueePanel)
//}}AFX_VIRTUAL// Implementation
public:
UINT m_uFormat;
UINT m_uScrollGran;
UINT m_uInterval;
UINT m_uTimerID;
void End();
void Start();
CString m_strMarqueeText;
virtual ~CMarqueePanel(); // Generated message map functions
protected:
int m_nTopLine;
//{{AFX_MSG(CMarqueePanel)
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnDestroy();
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MARQUEEPANEL_H__2C011862_B3B8_11D3_A106_0080ADAB03DD__INCLUDED_)-------------------------------------------------------------------------// MarqueePanel.cpp : implementation file
//#include "stdafx.h"
#include "DialogApp.h"
#include "MarqueePanel.h"#define ID_TIMEREVENT 1975
#define DEFAULT_INTERVAL 25
#define DEFAULT_STEP 1#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMarqueePanelCMarqueePanel::CMarqueePanel()
{
m_uFormat = DT_CENTER | DT_WORDBREAK;
m_uScrollGran = DEFAULT_STEP;
m_nTopLine = 0;
m_uTimerID = 0;
m_uInterval = DEFAULT_INTERVAL;
}CMarqueePanel::~CMarqueePanel()
{
}
BEGIN_MESSAGE_MAP(CMarqueePanel, CStatic)
//{{AFX_MSG_MAP(CMarqueePanel)
ON_WM_TIMER()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMarqueePanel message handlersvoid CMarqueePanel::Start()
{
if(!m_uTimerID)
m_uTimerID = SetTimer(ID_TIMEREVENT, m_uInterval, NULL);
}void CMarqueePanel::End()
{
if(m_uTimerID)
{
KillTimer(m_uTimerID);
m_uTimerID = 0;
m_nTopLine = 0;
}
}void CMarqueePanel::OnTimer(UINT nIDEvent) 
{
int nScrollGran; nScrollGran = abs(m_uScrollGran);
for(int i = 0; i < nScrollGran; i++)
{
RedrawWindow();
if(m_uScrollGran < 0)
m_nTopLine--;
else
m_nTopLine++;
}
}void CMarqueePanel::OnDestroy() 
{
End();
CStatic::OnDestroy();
}void CMarqueePanel::OnPaint() 
{
// Do not call CStatic::OnPaint() for painting messages
CPaintDC dc(this); // device context for painting
CFont *pOldFont;
CFont *pDefaultFont;
CFont fontDefault;
LOGFONT oLogFont;
RECT rect;
RECT rect2;
POINT pt;
CBitmap bmpDraw;
CBitmap *pOldBitmap;
CDC cdcMem;
TEXTMETRIC tm;
int nHeight; GetClientRect(&rect);
cdcMem.CreateCompatibleDC(&dc);
dc.SetBkMode(TRANSPARENT);
cdcMem.SetBkMode(TRANSPARENT);
pDefaultFont = GetFont();
pDefaultFont->GetLogFont(&oLogFont);
fontDefault.CreateFontIndirect(&oLogFont);
pOldFont = cdcMem.SelectObject(&fontDefault);
bmpDraw.CreateCompatibleBitmap(&dc, rect.right, rect.bottom);
pOldBitmap = cdcMem.SelectObject(&bmpDraw);
cdcMem.GetTextMetrics(&tm);
pt.x = tm.tmAveCharWidth;
pt.y = tm.tmHeight;
cdcMem.LPtoDP(&pt);
cdcMem.FillSolidRect(&rect, GetSysColor(COLOR_BTNFACE));
rect2.left = 0;
rect2.top = rect.bottom - m_nTopLine;
rect2.right = rect.right;
rect2.bottom = rect.bottom;
nHeight = cdcMem.DrawText(m_strMarqueeText, &rect2, m_uFormat);
if(rect2.top < 0 && nHeight + rect2.top <= 0)
{
m_nTopLine = 0;
rect2.top = rect.bottom - m_nTopLine;
cdcMem.DrawText(m_strMarqueeText, &rect2, m_uFormat);
}
dc.BitBlt(0, 0, rect.right, rect.bottom, &cdcMem, 0, 0, SRCCOPY);
cdcMem.SelectObject(pOldBitmap);
cdcMem.SelectObject(pOldFont);
}BOOL CMarqueePanel::OnEraseBkgnd(CDC* pDC) 
{
return true;
}-------------------------------------------------------------------------------用法:
BOOL CMarqueeDlg::OnInitDialog() 
{
CDialog::OnInitDialog();

m_lblMarquee.m_strMarqueeText = 
"Maquee demo\nCopyright (c) 1999 Edward Yang\nAll rights reserved!\n--------------------\naaaaaaaaaa bbbbbbbbbbbb ccccccccccc ddddddddddd";
m_lblMarquee.Start();
return TRUE;  
}