MFC 浮動工具列標題列預設有「關閉」按鈕。本文透過衍生 CToolBarEx 重載 WM_WINDOWPOSCHANGED,偵測浮動狀態並修改父視窗樣式移除系統選單(含關閉按鈕),實現無關閉按鈕的浮動工具列。
CControlBar::IsFloating()m_pDockBar->GetParent() → CMiniFrameWndModifyStyle(WS_SYSMENU, 0)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_SIZE 僅在尺寸改變時觸發,浮動工具列移動位置不一定觸發尺寸變更。WM_WINDOWPOSCHANGED 涵蓋尺寸、位置、Z 座標所有變更,確保浮動狀態偵測不遺漏。
m_pDockBar:CControlBar 成員,指向停靠容器視窗CMiniFrameWnd:MFC 浮動工具列的外層框架視窗類別WS_SYSMENU:視窗樣式旗標,控制系統選單(含關閉按鈕)顯示m_bMenuRemoved:避免重複 ModifyStyle 導致閃爍或錯誤以不到 30 行程式碼精準解決浮動工具列關閉按鈕移除需求。展示了 MFC 視窗架構(CControlBar→CDockBar→CMiniFrameWnd)與訊息處理機制的深度理解。原始碼可直接整合專案使用。