在 SDI (單文檔介面) 應用程式中,完全隱藏選單列、工具列與狀態列,實現純客戶區視窗。
預設在 CMainFrame::OnCreate 中建立,註解相關代碼即可:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
// 註解以下區塊隱藏工具列
/*
if (!m_wndToolBar.CreateEx(...)) return -1;
m_wndToolBar.LoadToolBar(IDR_MAINFRAME);
*/
// 註解以下區塊隱藏狀態列
/*
if (!m_wndStatusBar.Create(this)) return -1;
m_wndStatusBar.SetIndicators(...);
*/
return 0;
}
選單非在 CMainFrame 直接建立,而是在基類 CFrameWnd::OnCreateHelper 流程中透過 OnCreateClient -> LoadFrame 載入資源 IDR_MAINFRAME 定義的選單。解決方法:
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
// 移除 FWS_ADDTOTITLE 樣式可選,關鍵是不載入選單
// 直接呼叫基類但傳入 0 作為選單資源 ID
return CFrameWnd::LoadFrame(0, dwDefaultStyle, pParentWnd, pContext);
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// 移除 WS_CHILD 以外的樣式,關鍵移除 WS_SYSMENU 等
cs.style &= ~(WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
// 最徹底:不設定選單類別名稱
cs.lpszMenuName = NULL;
return CFrameWnd::PreCreateWindow(cs);
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
// 基類建立完成後,移除選單
SetMenu(NULL);
DrawMenuBar(); // 重繪非客戶區移除選單列空間
return 0;
}
透過在 CFrameWnd::OnCreate 設中斷點,逐步進入 OnCreateHelper -> OnCreateClient -> LoadFrame 追蹤 MFC 內部流程,確認選單載入時機,找到最合適的干預點。方法三最簡單直接,適合多數情況。