vc的菜單,工具欄

首先,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)); 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章