CStatusBar 是框架視窗底部(或頂部)的狀態資訊列,通常分為多個**窗格**,分別顯示:
AppWizard 產生的專案已在 CMainFrame::OnCreate 自動建立,手動建立流程:
// 成員變量
CStatusBar m_wndStatusBar;
// OnCreate 中
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))
{
TRACE0("狀態列建立失敗\n");
return -1;
}
// 指標陣列(資源.h 定義)
static UINT indicators[] =
{
ID_SEPARATOR, // 第 0 格:訊息區(寬度自動延伸)
ID_INDICATOR_CAPS, // 第 1 格:Caps Lock
ID_INDICATOR_NUM, // 第 2 格:Num Lock
ID_INDICATOR_SCRL, // 第 3 格:Scroll Lock
ID_MY_CUSTOM_PANE // 第 4 格:自訂 ID
};
建立後可用 SetPaneInfo 調整每格屬性:
// 索引 0:訊息區,延伸佔滿剩餘寬度
m_wndStatusBar.SetPaneInfo(0, ID_SEPARATOR, SBPS_STRETCH | SBPS_NORMAL, 0);
// 索引 1~3:鍵盤狀態,固定寬度
m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_CAPS, SBPS_NORMAL, 40);
m_wndStatusBar.SetPaneInfo(2, ID_INDICATOR_NUM, SBPS_NORMAL, 40);
m_wndStatusBar.SetPaneInfo(3, ID_INDICATOR_SCRL, SBPS_NORMAL, 40);
// 索引 4:自訂,固定寬度 120 像素
m_wndStatusBar.SetPaneInfo(4, ID_MY_CUSTOM_PANE, SBPS_NORMAL, 120);
nStyle)| 旗標 | 說明 |
|---|---|
SBPS_STRETCH | 延伸佔滿剩餘空間(通常僅第 0 格使用) |
SBPS_NORMAL | 一般文字顯示,有邊框凹陷效果 |
SBPS_NOBORDERS | 無邊框 |
SBPS_DISABLED | 灰色禁用外觀 |
SBPS_POPOUT | 凸起邊框(像按鈕) |
// 設定文字(立即更新)
m_wndStatusBar.SetPaneText(4, _T("就緒"));
// 取得文字
CString str = m_wndStatusBar.GetPaneText(4);
// 進階:格式化輸出
CString strPos;
strPos.Format(_T("行 %d, 欄 %d"), nLine, nCol);
m_wndStatusBar.SetPaneText(4, strPos);
ON_UPDATE_COMMAND_UI 自動更新機制狀態列窗格支援 CCmdUI,可在閒置週期自動更新:
// 映射表(ID 必須與 indicators 陣列對應)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS, OnUpdateCaps)
ON_UPDATE_COMMAND_UI(ID_MY_CUSTOM_PANE, OnUpdateCustomPane)
void CMainFrame::OnUpdateCaps(CCmdUI* pCmdUI)
{
pCmdUI->Enable(::GetKeyState(VK_CAPITAL) & 0x0001); // 依實際鍵盤狀態啟用/禁用
// MFC 內建 ID_INDICATOR_CAPS/NUM/SCRL 已自動處理,通常無需手寫
}
void CMainFrame::OnUpdateCustomPane(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bEditingMode);
pCmdUI->SetText(m_bEditingMode ? _T("編輯中") : _T("瀏覽中"));
}
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CString str;
str.Format(_T("X:%d Y:%d"), point.x, point.y);
pFrame->m_wndStatusBar.SetPaneText(4, str);
CView::OnMouseMove(nFlags, point);
}
// OnCreate 中
CProgressCtrl* pProgress = new CProgressCtrl;
pProgress->Create(WS_CHILD | WS_VISIBLE, CRect(0,0,150,18), &m_wndStatusBar, ID_PROGRESS);
m_wndStatusBar.SetPaneInfo(4, ID_PROGRESS, SBPS_NOBORDERS, 150);
// 使用時
pProgress->SetPos(nPercent);
// Create 參數 dwStyle 指定 CBRS_TOP
m_wndStatusBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP);
CRect rect;
m_wndStatusBar.GetItemRect(4, &rect); // 相對狀態列客戶區座標
m_wndStatusBar.ClientToScreen(&rect); // 轉螢幕座標
indicators[0] == ID_SEPARATOR,且選單/工具列項目有提示文字(格式:「狀態列提示\nToolTip」)。OnIdle 或高頻率計時器中重複設定相同文字,改用 ON_UPDATE_COMMAND_UI 讓 MFC 決定何時更新。CStatusBar 高度由字型決定。可在 OnCreate 後呼叫 SetFont() 統一。