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

移除 MFC 浮動工具列標題列「關閉」按鈕:修改浮動框架視窗風格實現

     編輯:VC 教學

MFC 預設浮動工具列會在標題列顯示「關閉」按鈕 (系統選單)。若需求不允許使用者關閉特定工具列,必須在浮動狀態下移除父框架視窗 (CMiniFrameWnd) 的 WS_SYSMENU 風格。本文提供一個優雅的 CToolBarEx 派生類實現方案,自動偵測浮動狀態並動態切換關閉按鈕顯示。

效果對比

→

圖一:預設有關閉按鈕 → 圖二:移除關閉按鈕後

核心邏輯:攔截 WM_WINDOWPOSCHANGED 判斷浮動狀態

為何不用 WM_SIZE?因為浮動工具列移動位置不一定觸發 Size,但 WM_WINDOWPOSCHANGED 只要位置、大小、Z 序任一改變必觸發。利用 CControlBar::IsFloating() 判斷浮動,透過 m_pDockBar->GetParent() 取得 CMiniFrameWnd 指標,修改其風格。

完整類別實現 CToolBarEx

class CToolBarEx : public CToolBar
{
    BOOL m_bMenuRemoved = FALSE; // 標記是否已移除系統選單
protected:
    afx_msg void OnWindowPosChanged(WINDOWPOS* lpwndpos);
    DECLARE_MESSAGE_MAP()
};

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

void CToolBarEx::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
    CToolBar::OnWindowPosChanged(lpwndpos);

    if (IsFloating()) // 浮動狀態
    {
        if (m_pDockBar && !m_bMenuRemoved) // 有停靠條且未處理過
        {
            CWnd* pParent = m_pDockBar->GetParent(); // 取得 CMiniFrameWnd
            if (pParent && pParent->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)))
            {
                pParent->ModifyStyle(WS_SYSMENU, 0, 0); // 移除系統選單風格
                m_bMenuRemoved = TRUE;
            }
        }
    }
    else if (m_bMenuRemoved) // 重新停靠回主框架
    {
        m_bMenuRemoved = FALSE; // 重置標記,下次浮動再處理
    }
}

使用方式

  1. 將專案中所有需此行為的工具列類別從 CToolBar 改為 CToolBarEx。
  2. 確保工具列啟用浮動功能 (EnableDocking(CBRS_ALIGN_ANY) + CBRS_SIZE_DYNAMIC)。
  3. 編譯執行,拖離工具列觀察標題列變化。

設計考量

  • 狀態重置: 重新停靠時重置 m_bMenuRemoved,確保再次浮動時能正確處理 (避免 CMiniFrameWnd 重用導致風格殘留)。
  • 指標安全: 嚴格檢查 m_pDockBar、GetParent()、IsKindOf,防止空指標或類型錯誤崩潰。
  • 使用者體驗: 移除關閉按鈕意味著使用者無法透過標題列關閉工具列,務必提供替代方式 (如「檢視」選單勾選項) 讓使用者顯示/隱藏。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved