首先,MFC會自動生成一些菜單,我們也可以在resource view中添加菜單。點擊菜單欄屬性--〉左上角校園最圖形,可以將屬性頁顯示。不會隨着菜單項變動丟失。
ID號變灰的欄是不可以編輯的。是彈出的POPUP菜單。它不能被用來做響應。大寫字母標示資源。IDI IDC IDM分別表示不同的類型資源。
一個菜單項可以由CMAINFRAM CXXXVIEW CXXApp CXXDOC view類先對其響應,接着doc類對其進行響應,MAINFRAM第三個對其進行響應,第四個響應的APP類對其進行響應。
Afxmessagebox框架函數,可以響應非WND派生類的彈出的提示,而wnd派生的可以直接用MessageBox函數。
消息包括三類:WM_XXX標準消息,從cwnd派生的類可以接收也可以接受命令消息,WM_COMMANed命令消息(通過ID號標識識別,由cmdtarget派生的類可以接受,比如說文檔類,CEIDTview類),第三類通知消息,有cmdtarget派生的類可以接收。APP和Doc類從CMDTARGET派生,所以不能接收標準消息。命令消息,頭文件消息影射中添加原形,原文件中添加ON_COMMND宏完成影射,還有命令函數實現。命令函數由ONCOMMAND來處理,通知消息由ONNOTIFY來實現。命令消息到來時首先到達CMAINFRAM然後到送達CVIEW來處理,根據命令消息影射來處理,如果沒有處理函數,交給DOC類,如果還沒有處理函數,交還給VIEW類,------〉交還CMAINFRAM類,如果他也沒有處理函數,交給APP類來處理。
標記菜單(打對購得):在CMAINFRAM中ONCREATE中創建。菜單屬於框架窗口,獲取菜單欄指針的方法爲GetMenu,它返回一個返回CMenu的指針。但是其指向的對象是不一樣的,一個爲菜單,一個爲子菜單。CMenu中的checkmenuitem方法可以設置標記。
缺省菜單項:SetDefaultItem。例如:GetMenu->GetSubMenu(0)->SetDefaultItem(1,True);索引訪問時注意分隔欄也算一個索引值。缺省菜單,一個子菜單隻能有一個項爲缺省。
圖形標記菜單:CMenu::SetMenuItemBitmaps來創建。首先創建圖形,然後構造CMinFram 變量Cbitmap A,A.loadbitmap();然後GetMenu->GetSubMenu(0)->SetMenuItemBitmaps(0,標記,標記後圖像,標記前圖像)需要調整位圖大小適合顯示纔可以。
屏蔽菜單:enableMenuItem設置參數爲MF_disable|MF_GRAYED注意在CMAINFRAM的構造函數中M_bautomenuenable必須被賦予FALSE,此後菜單更新將由我們負責。
移除菜單:SetMenu(NULL);
更換菜單:先移除,後局部變量CMenu A;A.loadMenu(id);setMenu(A);然後調用A.Detach成員函數就可以了。
MFC對菜單項採用的命令更新機制:ON_UPDATE_COMMOND_UI宏來完成。CCMDUI類的相關方法可以進行相應的操作。如調用Enable或Setcheck。更新從第一個菜單項到最後一個菜單項。注意:不能應用於頂級菜單項。
菜單欄和工具欄的對應只需設置相應的ID號一致就可以了。使用pCMDUI->nindex索引來說,菜單欄和工具欄可以出現不同狀態,爲了保持一致,最後採用PCMDUI->ID號來訪問使用。
右鍵彈出菜單功能:在View類中創建相關函數,首先增加菜單資源,增加window消息處理,定義對象,加載菜單LoadMenu,定義菜單指針獲取定義的子菜單。指針->TrackpopupMenu,注意當前點座標是以客戶區爲原點,而顯示時是以屏幕爲原點。這樣需要,屏幕座標到客戶區座標的準換。此時,ClientToScreen完成客戶區座標到屏幕座標的轉換,參數要求是一個指針。TrackPopupMenu中的參數將規定擁有者。GetParent獲取父類對象。
動態創建菜單、刪除、增加、修改菜單。可以在CMainFram的OnCreate中創建,利用CMenu中的AppendMenu來添加,可以添加Popup(頂層菜單),seperate,MF_String等,創建空的探出菜單:CMenu::CreatePopupMenu,然後GetMenu()->appendmenu(MF_Popup,(UNIT)指針.m_hMenu,"菜單名稱"),指針.Detach();
插入菜單:InsertMenu(),然後再給其添加菜單項。用AppendMenu來實現。
刪除菜單:DeleteMenu();刪除菜單項或彈出菜單。
動態增加的菜單項的響應:首先在資源的頭文件中添加定義的ID與相應的ID值,三個步驟添加響應,頭文件中添加消息響應原形afx_msg void ONxxx(),添加消息映射,命令消息ONCOMMAND()宏來進行映射。然後寫消息處理函數。
前言
在用VC編程時,界面製作遠不如Delphi、VB容易。我又常常用到基於Dialog編寫應用程序。而在直接在Dialog使用Toolbar和Menu的資料很少。而我有機會可以總結一些經驗,供大家分享,希望能得到指教。
下載本文示例工程 大小:11.2K
運行效果如下圖
我們先建立一個基於Dialog 的程序,我給他起了個名字叫:DlgMenuToolbar。
一、如何往基於Dialog的程序添加菜單
[1.1] 先添加菜單(IDR_MENU1)資源,並加上需要的菜單項。
[1.2] 編輯對話框資源IDD_DLGMENUTOOLBAR_DIALOG的屬性,在屬性對話框中選擇IDR_MENU1即可。
[1.3] 假如您不希望在對話框屬性中直接設置菜單,而通過代碼在程序中動態生成可以採用如下方法:
[1.3.1]在CDlgMenuToolbarDlg類聲名中添加成員變量CMenu m_menu
再在CDlgMenuToolbarDlg::OnInitDialog() 中添加如下代碼://加載菜單 m_menu.LoadMenu(IDR_MENU1); //設置當前菜單 SetMenu(&m_menu); //當你不需要菜單時可以用 SetMenu(NULL);來取消當前菜單
二、如何往基於Dialog的程序添加工具欄
[2.1] 先添加工具欄(IDR_TOOLBAR1)資源,並畫好各個按鈕。
[2.2] 在CDlgMenuToolbarDlg類聲名中添加成員變量 CToolBar m_wndtoolbar;
[2.3] 在CDlgMenuToolbarDlg::OnInitDialog() 中添加如下代碼
//添加一個平面工具條 if (!m_wndtoolbar.CreateEx( this,TBSTYLE_FLAT , WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS, CRect(4,4,0,0)) || !m_wndtoolbar.LoadToolBar(IDR_TOOLBAR1) ) { TRACE0("failed to create toolbar/n"); return FALSE; } m_wndtoolbar.ShowWindow(SW_SHOW); RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
三、爲工具欄添加工具提示
[3.1] 在CDlgMenuToolbarDlg類定義中手工添加消息映射函數的定義,如下黑體部分
//{{AFX_MSG(CDlgMenuToolbarDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult); //}}AFX_MSG DECLARE_MESSAGE_MAP()
[3.2] 在CDlgMenuToolbarDlg.cpp添加函數的實現代碼
//工具欄提示 BOOL CDlgMenuToolbarDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult) { ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW); // UNICODE消息 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; //TCHAR szFullText[512]; CString strTipText; UINT nID = pNMHDR->idFrom; if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)) { // idFrom爲工具條的HWND nID = ::GetDlgCtrlID((HWND)nID); } if (nID != 0) //不爲分隔符 { strTipText.LoadString(nID); strTipText = strTipText.Mid(strTipText.Find(''/n'',0)+1); #ifndef _UNICODE if (pNMHDR->code == TTN_NEEDTEXTA) { lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText)); } else { _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText)); } #else if (pNMHDR->code == TTN_NEEDTEXTA) { _wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText)); } else { lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText)); } #endif *pResult = 0; // 使工具條提示窗口在最上面 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE| SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); return TRUE; } return TRUE; }
[3.3] 在CDlgMenuToolbarDlg.cpp中添加消息映射,請看如下代碼中的黑體部分
BEGIN_MESSAGE_MAP(CDlgMenuToolbarDlg, CDialog) //{{AFX_MSG_MAP(CDlgMenuToolbarDlg) ON_WM_PAINT() ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipText ) //}}AFX_MSG_MAP END_MESSAGE_MAP()
四、其它
爲了使你的程序看起來更酷,還可以在CDlgMenuToolbarDlg::OnPaint()中修改代碼實現Dialog 填充顏色。
CPaintDC dc(this); CRect rect; GetClientRect(rect); dc.FillSolidRect(rect, RGB(60,110,170));