本文提供一套完整的 Office 2000 風格菜單與工具欄解決方案,包含:
示例程序截圖:


原作者代碼依賴特定 RC 資源,通用性不足。譯者重構了核心代碼,移除資源依賴,並翻譯為中文文檔。附帶示例為一個抓圖工具的界面部分,展示了所有功能點。
ID_SHOWFULL = 32792,標題「顯示完整菜單」ID_INTMODE = 32794,標題「啟用/禁用智能菜單模式」OffMenu 目錄下所有 .cpp、.h 加入專案。
#include "MDIFrmEx.h"
#include "ToolBarEx.h"
class CMainFrame : public CMDIFrameEx // 原為 CMDIFrameWnd
{
CToolBarEx m_wndToolBar; // 原為 CToolBar
// ...
};
IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameEx)
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameEx)
// ...
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameEx::OnCreate(lpCreateStruct) == -1) // 原為 CMDIFrameWnd
return -1;
// ...
}
#include "WinAppEx.h" class CTestMDIApp : public CWinAppEx // 原為 CWinApp
#include "DocTplEx.h"
BEGIN_MESSAGE_MAP(CTestMDIApp, CWinAppEx)
BOOL CTestMDIApp::InitInstance()
{
// ... 原有代碼替換為:
UINT nID = IDR_MAINFRAME;
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(nID)) return FALSE;
m_pMainWnd = pMainFrame;
CMultiDocTemplateEx* pDocTemplate = new CMultiDocTemplateEx(
IDR_TESTMDTYPE,
RUNTIME_CLASS(CTestMDIDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CTestMDIView),
&nID, 1);
AddDocTemplate(pDocTemplate);
CWinAppEx::InitInstance(); // 必須調用基類擴展初始化
return TRUE;
}
若需自定義菜單項使用統計與灰顯邏輯,可重載 CMenuBar 類的虛擬函數:
// 累加菜單項使用計數 virtual WORD IncMenuUsage(CMenuEx *pParent, UINT pos, WORD curusage); // 決定菜單項是否灰顯,可修改使用計數 virtual BOOL EvaluateIfGrayed(CMenuEx *pParent, UINT pos, WORD &curusage, int iMed, int iRange);
若需在菜單項附加應用層數據,可使用 CMenuEx::GetExtraDataPtr(UINT) 獲取擴展數據指針。
本庫當前僅直接支持 MDI。若需用於 SDI,請參考修改 CMultiDocTemplateEx、CMDIFrameEx、CMDIFrameEx(應為 CFrameWndEx 類)以適配單文檔架構。