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

移除浮動工具列關閉按鈕:CToolBarEx 重載 WM_WINDOWPOSCHANGED 實現

     編輯:關於VC++

MFC 浮動工具列標題列預設有「關閉」按鈕。本文透過衍生 CToolBarEx 重載 WM_WINDOWPOSCHANGED,偵測浮動狀態並修改父視窗樣式移除系統選單(含關閉按鈕),實現無關閉按鈕的浮動工具列。

核心邏輯

  1. 判斷工具列是否浮動:CControlBar::IsFloating()
  2. 取得停靠框架視窗:m_pDockBar->GetParent() → CMiniFrameWnd
  3. 修改樣式移除系統選單:ModifyStyle(WS_SYSMENU, 0)
  4. 狀態旗標 m_bMenuRemoved 防止重複操作

完整實作程式碼

class CToolBarEx : public CToolBar {
    BOOL m_bMenuRemoved = FALSE;
    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
    ON_WM_WINDOWPOSCHANGED()
END_MESSAGE_MAP()

void CToolBarEx::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) {
    CToolBar::OnWindowPosChanged(lpwndpos);
    
    if (IsFloating()) {
        // 浮動狀態:移除系統選單
        if (m_pDockBar && !m_bMenuRemoved) {
            CWnd* pParent = m_pDockBar->GetParent();
            if (pParent->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd))) {
                pParent->ModifyStyle(WS_SYSMENU, 0, 0);
                m_bMenuRemoved = TRUE;
            }
        }
    } else if (m_bMenuRemoved) {
        // 回到停靠狀態:重置旗標(下次浮動再處理)
        m_bMenuRemoved = FALSE;
    }
}

為何用 WM_WINDOWPOSCHANGED 而非 WM_SIZE?

WM_SIZE 僅在尺寸改變時觸發,浮動工具列移動位置不一定觸發尺寸變更。WM_WINDOWPOSCHANGED 涵蓋尺寸、位置、Z 座標所有變更,確保浮動狀態偵測不遺漏。

關鍵技術點

  • m_pDockBar:CControlBar 成員,指向停靠容器視窗
  • CMiniFrameWnd:MFC 浮動工具列的外層框架視窗類別
  • WS_SYSMENU:視窗樣式旗標,控制系統選單(含關閉按鈕)顯示
  • 旗標 m_bMenuRemoved:避免重複 ModifyStyle 導致閃爍或錯誤

注意事項

  • 違反 Windows UI 設計規範(視窗應提供關閉方式),需確認使用者真有此需求
  • 浮動工具列失去關閉按鈕後,使用者只能透過「檢視→工具列」選單隱藏
  • 多文檔介面 (MDI) 子視窗浮動工具列同樣適用

總結

以不到 30 行程式碼精準解決浮動工具列關閉按鈕移除需求。展示了 MFC 視窗架構(CControlBar→CDockBar→CMiniFrameWnd)與訊息處理機制的深度理解。原始碼可直接整合專案使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved