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)); 

 

 

posted on 2009-10-07 22:33  wqj1212  阅读(2740)  评论(0编辑  收藏  举报

导航