首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

MFC CStatusBar 狀態列完整指南

     編輯:關於C語言

狀態列在 MFC 應用中的角色

CStatusBar 是框架視窗底部(或頂部)的狀態資訊列,通常分為多個**窗格**,分別顯示:

  • 第 0 格:命令提示(滑鼠懸停選單/工具列時自動顯示)
  • 其餘格:鍵盤狀態(Caps/Num/Scroll Lock)、應用程式自訂資訊(目前模式、游標位置、進度、時間等)

建立與初始化

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("瀏覽中"));
}

進階技巧

1. 顯示滑鼠座標(View 中)

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);
}

2. 進度條嵌入狀態列

// 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);

3. 狀態列頂部停靠

// Create 參數 dwStyle 指定 CBRS_TOP
m_wndStatusBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP);

4. 取得窗格矩形(用於 ToolTip 或自訂繪製)


CRect rect;
m_wndStatusBar.GetItemRect(4, &rect);  // 相對狀態列客戶區座標
m_wndStatusBar.ClientToScreen(&rect);  // 轉螢幕座標

常見問題

  • 第 0 格不顯示提示:確認 indicators[0] == ID_SEPARATOR,且選單/工具列項目有提示文字(格式:「狀態列提示\nToolTip」)。
  • 自訂窗格文字閃爍:避免在 OnIdle 或高頻率計時器中重複設定相同文字,改用 ON_UPDATE_COMMAND_UI 讓 MFC 決定何時更新。
  • 狀態列高度異常:檢查字型設定,CStatusBar 高度由字型決定。可在 OnCreate 後呼叫 SetFont() 統一。
  • 多文檔 (MDI) 子視窗最大化時選單合併:狀態列會暫時替換為子視窗的狀態列,還原時自動恢復。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved