VS2005以后,MFC將Menu從MainFrame上移到了MenuBar上,因此在創建MainFrame(即調用OnCreate()中),執行到
if (!m_wndMenuBar.Create(this))
這句后,從MainFrame上執行GetMenu就不能獲得正確的CMenu指針了,以后的GetMenu就只能返回0了。要取得CMenu指針,需要執行:
m_wndMenuBar.GetMenu();
如果想要修改菜單的風格,象以前那樣利用SetMenuInfo()函數,無法改變菜單的風格。
這是由於Microsoft引入了UI管理器(VisualManager)來管理包括Menu、Tasks pane、 Auto-hide buttons、Edit box、Popup window、Ribbon control等在內的視圖風格。
因此,要改變視圖的風格,則需要利用這個UI管理器來實現,也可以利用它實現換膚。
以缺省生成的MFC單文檔程序為例,MainFrame中有一個OnApplicationLook()函數,在該函數中對設置不同的風格管理器:
{
CWaitCursor wait;
theApp.m_nAppLook = id;
switch (theApp.m_nAppLook)
{
case ID_VIEW_APPLOOK_WIN_2000:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager));
break;
case ID_VIEW_APPLOOK_OFF_XP:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP));
break;
case ID_VIEW_APPLOOK_WIN_XP:
CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE;
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
break;
case ID_VIEW_APPLOOK_OFF_2003:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003));
CDockingManager::SetDockingMode(DT_SMART);
break;
case ID_VIEW_APPLOOK_VS_2005:
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005));
CDockingManager::SetDockingMode(DT_SMART);
break;
default:
switch (theApp.m_nAppLook)
{
case ID_VIEW_APPLOOK_OFF_2007_BLUE:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
break;
case ID_VIEW_APPLOOK_OFF_2007_BLACK:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack);
break;
case ID_VIEW_APPLOOK_OFF_2007_SILVER:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver);
break;
case ID_VIEW_APPLOOK_OFF_2007_AQUA:
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua);
break;
}
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
CDockingManager::SetDockingMode(DT_SMART);
}
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);
theApp.WriteInt(_T( " ApplicationLook "), theApp.m_nAppLook);
}
CMFCVisualManager是其他UI管理器的基類(他還有一個基類:CMFCBaseVisualManager),他提供類似於Windows2000的風格。其他幾種UI界面類都是從它直接或間接派生的。SetDefaultManager用來設置不同的UI界面風格類。
我們可以從CMFCVisualManager、或者其他管理器的類,繼承生成一個新的類,重載其中的函數,就可以做成自己的管理器。
有關這部分內容,微軟還沒有提供幫助內容,具體如何做,還需要自己去分析源代碼。源代碼的位置是(我用的是VS2008):
Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc
雖然源代碼中沒有太多注釋,但函數名和變量名的命名還是不錯,基本上可以理解。
如果需要自定義UI管理器,建議首先決定近似於哪個風格,然后繼承自該風格的類,最后再進行必須的重載。