隨著Windows XP和Office XP的推出,兼具華美和清爽氣質的Office XP界面風格也逐漸取代了Windows經典界面風格而成為了當前應用程序的流行“時裝”,因而如何使自己的應用程序擁有Office XP風格的界面也成為了廣大程序員感興趣的問題。為此法國程序員Jean-Michel LE FOL針對於Visual C++編寫了CMenuXP類,使用CMenuXP類就可以輕松使自己的應用程序擁有Office XP風格的界面。下面我就以詳細介紹一下使用CMenuXP的步驟。
首先新建一個名叫“SDIXP”的單文檔的MFC應用程序。在我們能使用CMenuXP之前,必須進行一下幾步操作:
1. 將CMenuXP的源文件和頭文件所在的文件夾(一般放在名叫“Tools”)放到SDIXP源文件的目錄下。
2. 將Visual C++切換到“文件視圖(FileView)”,加入CMenuXP的源文件和頭文件。具體可以這樣進行:在FileVIEw的樹狀目錄下,展開SDI files,在Source Files目錄上點擊右鍵,創建新目錄(“New Folder…”),不妨取名叫“Tools”,再在Tools目錄上點擊右鍵,選擇加入文件(“Add Files to Folder…”),將Tools文件夾下的所有源文件(*.cpp)全部加進來。同理,在文件視圖的Header Files目錄下新建一個叫做“Tool Headers”,再將Tools文件夾下的所有頭文件(*.h)全部加到Tool Headers目錄裡。
3. (1)在控制菜單的類的頭文件(對於SDI程序通常是MainFrm.h)裡加入所需要的CMenuXP類的頭文件名:
#include "Tools/MenuXP.h"
#include "Tools/ToolBarXP.h"
#include "Tools/StatusBarXP.h"
#include "Tools/ComboBoxXP.h"
再在MainFrm.h裡加入下面的宏:
DECLARE_MENUXP()
上述語句可以加在CMainFrame類聲明裡的宏定義“DECLARE_MESSAGE_MAP()”的後面。
(2)在控制菜單的類的源文件(MainFrm.cpp)裡加入:
IMPLEMENT_MENUXP(類名, 基類名);
對於SDI工程就是
IMPLEMENT_MENUXP(CMainFrame, CFrameWnd);
上述語句加在CMainFrame開頭的“IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)”後面。
(3)接著繼續在消息映射裡如下加入:
BEGIN_MESSAGE_MAP(className, baseClass)
// ...
ON_MENUXP_MESSAGES() //加入這一行
END_MESSAGE_MAP()
(4)在繼承於CWinApp的類(這裡就是CSDIXPApp)中的InitInstance()函數裡加入:
CMenuXP::InitializeHook();
可以加在“AfxEnableControlContainer();”語句後面。
然後再為CSDIXPApp類重載ExitInstance()函數,可以在“類視圖(ClassVIEw)”裡點右鍵加入。再在ExitInstance()函數裡加入:
CMenuXP::UninitializeHook();
以上步驟做完之後可以按F7編譯一下,如果一切沒有問題我們就可以開始使用CMenuXP來美化我們的菜單和工具欄了。
首先,我們來將菜單和菜單項XP化。這很簡單,只要在CMainFrame:: OnCreate()函數裡加入:
CMenuXP::UpdateMenuBar(this);
CMenuXP::SetXPLookNFeel(this);
就OK了。現在你編譯運行一下,看看你的程序菜單是不是改頭換面了?
如果你想為自己菜單項定制圖標,我們可以用CMenuXP::SetMenuItemImage (UNIT nID, HIMAGELIST hImgList, int nIndex)函數來實現。為此,我們新建一個菜單“水果”和菜單項“蘋果”(ID設置為ID_MENUITEM_APPLE),打開ClassWizard為ID_MENUITEM_APPLE添加消息處理函數OnMenuitemApple()。然後再導入一個位圖資源“APPLE.bmp”,其ID設置為IDB_APPLE。
接著我們為CMainFrame添加CImageList類型的成員變量m_imgList,再在CMainFrame:: OnCreate()函數的“CMenuXP::SetXPLookNFeel (this);”後面加入:
m_imgList.Create(IDB_APPLE, 0, 0, RGB(192,192,192));
CMenuXP::SetMenuItemImage(ID_MENUITEM_APPLE, m_imgList, 0);
其中m_imgList.Create()函數中的第2,3個參數是位圖文件的圖像拷貝的左上角坐標,最後一個參數是圖像的背景色。建議使用16×16的位圖。SetMenuItemImage()函數的最後一個參數指的是m_imgList的中元素的索引,這裡因為m_imgList.只包含一個位圖,故取零。編譯後運行,看看“水果|蘋果”菜單項前面是不是多了一個蘋果的圖標?
下面我們在將使工具欄和狀態欄XP化,這個更加easy了。只要將CMainFrame類聲明中的
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
變成
CStatusBarXP m_wndStatusBar;
CToolBarXP m_wndToolBar;
就搞定了!不信,你編譯運行一下看看,^_*
CMenuXP還可以將按鈕和下拉列表框變成Office XP風格的。為此我們新建一個對話框IDD_APPLE。OK和Cancel按鈕保持不動,我們只增添一個下拉列表框控件IDC_COMBO1。然後按Ctrl+W打開ClassWizard為該對話框新建一個CAppleDlg類。再在ClassWizard中的Member Variable裡為IDC_COMBO1添加Control類型的變量m_cmbx1。接著為CAppleDlg重載OnInitDialog()用以初始化控件:
BOOL CAppleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_cmbx1.AddString("紅蘋果");
m_cmbx1.AddString("青蘋果");
return TRUE;
}
然後在“蘋果”菜單項的消息處理函數中使蘋果對話框彈出:
void CMainFrame::OnMenuitemApple()
{
// TODO: Add your command handler code here
CAppleDlg dialog;
dialog.DoModal();
}
如果這時編譯運行,就會看到打開“水果|蘋果”菜單項後彈出一個對話框,但上面的控件還不是Office XP風格的,下面我們就著手使其XP化,其實這同樣也是很easy的!
先在AppleDlg.h文件中包含"Tools/ComboBoxXP.h"和"Tools/ButtonXP.h",再找到定義m_cmbx1的位置,將CComboBox m_cmbx1;變成CComboBoxXP m_cmbx1;
這樣下拉列表框就有XP風格了,不信你編譯運行試試。關於OK和Cancel按鈕就稍微特殊一點,因為它們是直接用IDOK和IDCANCEL標識的默認按鈕,但為了使它們XP化,我們還是得為這兩個按鈕添加控制變量。因此,在CAppleDlg類的聲明中添加:
CButtonXP m_btnOK;
CButtonXP m_btnCancel;
再在CAppleDlg::DoDataExchange()函數中添加數據交換:
DDX_Control(pDX, IDOK, m_btnOK);
DDX_Control(pDX, IDCANCEL, m_btnCancel);
這樣,OK和Cancel按鈕也都XP化了。大家編譯運行一下,看看效果怎麼樣。
總之,使用Jean-Michel LE FOL的CMenuXP給用Visual C++開發的應用程序換上Office XP風格的界面還是很不錯的,操作起來也比較簡便。唯一不足的就是其他許多控件,如文本框等還是沒有Office XP風格,這就期待著原作者以及我們大家繼續完善CMenuXP類。