使用 GetWindowLong / SetWindowLong 配合 SetWindowPos 實現運行時動態修改 MFC 視窗樣式,涵蓋標題欄、邊框、最小化/最大化/關閉按鈕、工具視窗等常見場景。
核心模式
// 修改樣式通用模板
LONG style = GetWindowLong(m_hWnd, GWL_STYLE);
style |= WS_XXX; // 啟用某樣式
// 或 style &= ~WS_XXX; // 禁用某樣式
SetWindowLong(m_hWnd, GWL_STYLE, style);
SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
常見操作速查表
| 功能 | 啟用代碼 | 禁用代碼 |
| 最小化按鈕 | style |= WS_MINIMIZEBOX | style &= ~WS_MINIMIZEBOX |
| 最大化按鈕 | style |= WS_MAXIMIZEBOX | style &= ~WS_MAXIMIZEBOX |
| 關閉按鈕 | EnableMenuItem(GetSystemMenu(FALSE), SC_CLOSE, MF_ENABLED) | EnableMenuItem(GetSystemMenu(FALSE), SC_CLOSE, MF_GRAYED) |
| 標題欄 | style |= WS_CAPTION | style &= ~WS_CAPTION |
| 3D 邊框(可縮放) | style |= WS_THICKFRAME | style &= ~WS_THICKFRAME |
| 細邊框(不可縮放) | style |= WS_BORDER | style &= ~WS_BORDER |
| 無邊框 | — | style &= ~(WS_CAPTION | WS_THICKFRAME) |
進階場景:工具視窗 (不顯示在任務列)
// OnInitDialog() 中設定
LONG exStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
exStyle &= ~WS_EX_APPWINDOW;
exStyle |= WS_EX_TOOLWINDOW;
SetWindowLong(m_hWnd, GWL_EXSTYLE, exStyle);
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
MFC 視圖/框架邊框移除 (SDI 程式)
// 移除 View 邊框
BOOL CSDIView::PreCreateWindow(CREATESTRUCT& cs) {
cs.style &= ~WS_BORDER;
return CFormView::PreCreateWindow(cs);
}
// 移除 Frame 客戶區邊框
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
if (!CFrameWnd::PreCreateWindow(cs)) return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE; // 必須在基類調用後執行
return TRUE;
}
關鍵注意事項
- 僅對 Pop-up 視窗有效,子視窗 (Child Window) 樣式修改可能不生效
- 必須呼叫
SetWindowPos 並包含 SWP_FRAMECHANGED 旗標,變更才會立即重繪
GWL_STYLE vs GWL_EXSTYLE:標準樣式 vs 擴展樣式,勿混淆
- 位元操作:
| 開啟、& ~ 關閉、^ 切換
- 修改
WS_EX_DLGMODALFRAME 時需同步處理擴展樣式
常見錯誤排查