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