MFC 標準進度條無法直接放入狀態欄。需自繪或建立子視窗管理。本文採用子視窗法:派生 CProgStatusBar : public CStatusBar,內含 CProgressCtrl m_wndProgBar,負責建立、定位、顯示/隱藏、文字協調。
int CProgStatusBar::OnCreate(LPCREATESTRUCT lpcs) {
lpcs->style |= WS_CLIPCHILDREN; // 減少閃爍
if (CStatusBar::OnCreate(lpcs) != 0) return -1;
if (!m_wndProgBar.Create(WS_CHILD, CRect(), this, 1)) return -1;
m_wndProgBar.SetRange(0, 100);
return 0; // 初始隱藏 (無 WS_VISIBLE)
}
void CProgStatusBar::OnSize(UINT nType, int cx, int cy) {
CStatusBar::OnSize(nType, cx, cy);
CRect rc; GetItemRect(0, &rc); // 第一格矩形
m_wndProgBar.MoveWindow(&rc, FALSE); // 隱藏狀態也要更新位置
}
void CProgStatusBar::OnProgress(UINT nPercent) {
if (nPercent > 0) {
SetWindowText(NULL); // 清除「就緒」文字,避免重疊
m_wndProgBar.ShowWindow(SW_SHOW);
m_wndProgBar.SetPos(nPercent);
} else {
m_wndProgBar.ShowWindow(SW_HIDE);
// 恢復預設閒置文字
GetParent()->PostMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
}
}
主框架類別 CMainFrame 定義自訂訊息 MYWM_PROGRESS:
#define MYWM_PROGRESS (WM_USER+100)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(MYWM_PROGRESS, OnProgress)
END_MESSAGE_MAP()
LRESULT CMainFrame::OnProgress(WPARAM wp, LPARAM) {
m_wndStatusBar.OnProgress((UINT)wp);
return 0;
}
任何物件 (文檔、視圖、執行緒) 只需 PostMessage(GetTopLevelFrame()->GetSafeHwnd(), MYWM_PROGRESS, percent),無須直接存取狀態欄成員,降低耦合。
void CMyDoc::Serialize(CArchive& ar) {
if (ar.IsLoading()) {
CWnd* pFrame = AfxGetMainWnd();
if (pFrame) {
for (int i=0; i<=100; i+=5) {
Sleep(150); // 模擬耗時操作
pFrame->PostMessage(MYWM_PROGRESS, i);
}
}
// 實際載入邏輯...
}
}

m_wndProgBar.SetMarquee(TRUE, 50)GetProgressCtrl() 供高級自訂CCustomStatusBar 實現圖示+文字+進度條混合佈局