核心思路
- 定時器
SetTimer(ID_TIMER_MARQUEE, 200, nullptr) 每 200ms 觸發。
OnTimer 中維護偏移索引,截取子字串 text.Mid(pos) + text.Left(pos)。
SetWindowText 更新標題欄。
封裝類
class CMarqueeTitle {
CWnd* m_pWnd;
CString m_text;
int m_pos;
UINT m_timerId;
public:
CMarqueeTitle(CWnd* pWnd, LPCTSTR text, UINT interval = 200)
: m_pWnd(pWnd), m_text(text), m_pos(0), m_timerId(0) {
Start(interval);
}
~CMarqueeTitle() { Stop(); }
void Start(UINT interval) {
if (m_timerId) return;
m_timerId = m_pWnd->SetTimer(++s_timerId, interval, nullptr);
}
void Stop() {
if (m_timerId) {
m_pWnd->KillTimer(m_timerId);
m_timerId = 0;
m_pWnd->SetWindowText(m_text); // 恢復原標題
}
}
void OnTimer() {
if (m_text.IsEmpty()) return;
CString disp = m_text.Mid(m_pos) + m_text.Left(m_pos);
m_pWnd->SetWindowText(disp);
m_pos = (m_pos + 1) % m_text.GetLength();
}
static UINT s_timerId;
// 需在視窗類添加 ON_WM_TIMER() 並調用 marquee.OnTimer()
};
UINT CMarqueeTitle::s_timerId = 1000;
使用範例
// MainFrm.h
CMarqueeTitle m_marquee;
// MainFrm.cpp
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
m_marquee = new CMarqueeTitle(this, _T("歡迎使用本系統 - 通知:系統維護於今晚 22:00 進行 "), 150);
return 0;
}
void CMainFrame::OnTimer(UINT_PTR nIDEvent) {
if (nIDEvent == m_marquee.GetTimerId()) m_marquee.OnTimer();
CFrameWnd::OnTimer(nIDEvent);
}
參考資源
CSDN 下載:MFC 跑馬燈標題完整專案