MFC SDI 專案預設會依據資源 ID 建立選單列。若需完全移除選單列(如全螢幕模式、自訂工具列介面),可採用以下兩種方式。
在主框架類別 CMainFrame 覆寫 Create,改呼叫 CreateEx 並將選單參數設為 NULL:
BOOL CMainFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, LPCTSTR lpszMenuName,
DWORD dwExStyle, CCreateContext* pContext)
{
// 不呼叫基類 Create,改用 CreateEx 並傳入 NULL 選單
HMENU hMenu = NULL;
return CFrameWnd::CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(),
hMenu, // 關鍵:傳入 NULL 移除選單列
(LPVOID)pContext);
}
優點:從視窗建立階段就不載入選單資源,最乾淨。
缺點:若專案後續需動態加入選單,需自行管理 HMENU。
保留視窗建立流程,於 OnCreate 取得選單控制代碼後逐項刪除:
// 輔助函數:遞迴刪除所有選單項目
static void DeleteAllMenuItems(HMENU hMenu)
{
int count = GetMenuItemCount(hMenu);
for (int i = count - 1; i >= 0; --i)
{
DeleteMenu(hMenu, i, MF_BYPOSITION);
}
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 建立工具列、狀態列等既有程式碼...
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("工具列建立失敗\n");
return -1;
}
// ... 狀態列建立碼略 ...
// 關鍵:取得選單控制代碼並清空
CMenu* pMenu = GetMenu();
if (pMenu != NULL)
{
DeleteAllMenuItems(pMenu->GetSafeHmenu());
}
return 0;
}
優點:保留原始視窗建立流程,若未來需動態重建選單較靈活。
缺點:選單資源仍會載入再刪除,稍微浪費資源。
| 比較項目 | 方法一 (CreateEx + NULL) | 方法二 (OnCreate + 刪除) |
|---|---|---|
| 實作複雜度 | 低 | 中 |
| 資源載入時機 | 完全不載入 | 載入後刪除 |
| 動態恢復選單 | 需自行建立 HMENU | 可重新 LoadMenu |
| 適用情境 | 永久無選單介面 | 條件式隱藏/顯示選單 |
EnableDocking、DockControlBar 呼叫順序正確。WS_SYSMENU 控制,非 MFC 選單資源。