|
- 一、单文档的菜单图标实现: 源程序下载
- 1、新建一个位图资源,大小为13*13,假设ID为IDB_BITMAP1,画好图标
- 2、在CMainFrame中添加成员变量:CBitmap bitmap
- 3、在CMainFrame的OnCreate中加入:
- bitmap.LoadBitmap(IDB_BITMAP1);
- GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION, &bitmap, &bitmap);//具体哪个菜单项为图标,可自己设定
- 4、编译,实现图标菜单。
- 二、多文档的菜单图标实现:
- 1、新建一个位图资源,大小为13*13,假设ID为IDB_BITMAP1,画好图标
- 2、在CMaoyeah_comDoc(你程序中的CDocument子类)中添加成员变量:CBitmap bitmap
- 3、在CMaoyeah_comDoc的OnNewDocument中加入:
- bitmap.LoadBitmap(IDB_BITMAP1);
- CMenu *pMenu;
- pMenu = CMenu::FromHandle(((CMultiDocTemplate *)m_pDocTemplate)->m_hMenuShared);
- CMenu *pSubMenu = pMenu->GetSubMenu(0);
- pSubMenu->SetMenuItemBitmaps(0,MF_BYPOSITION, &bitmap, &bitmap);
- 4、编译,实现图标菜单。
- /****************右键单击时间弹出快捷菜单********************************************/
- CMenu m_pop;
- CMenu* m;
- m_pop.LoadMenu(IDR_MENU_LIUYAN);
- m=m_pop.GetSubMenu(0);
- CPoint point;
- CPoint CursorPos;
- GetCursorPos(&CursorPos);
- //IDR_MENU_LIUYAN
- ClientToScreen(&point);
- m->TrackPopupMenu(TPM_LEFTALIGN,CursorPos.x,CursorPos.y,this);
- __________________________________________________________________________
- 如何动态添加菜单/菜单项、子菜单、右键菜单
- 有关菜单的操作主要用到CMenu类,当然也可用相应API函数,CMenu类只是MFC对API中操作菜单的函数的封装而已。 不过能用类就尽量用类,类的组织方式好呗,代码看着也舒服。 若是SDK编程,那就用API吧 。
- CMenu menuMain,menu1; //首先 定义CMenu对象
- 一、 创建菜单,有两种方法
- 1. 用LoadMenu函数从资源加载
- menuMain.LoadMenu(IDR_MAINFRAME); //从资源加载,这里使用SDI的主菜单资源
- 2. 用CreateMenu函数创建
- menu1.CreateMenu(); //创建菜单,还没有菜单项
- 二、 添加菜单项,可用AppendMenu()在菜单的最后加、InsertMenu()在指定的位置加.
- // ID_TEST1 在Resource.h 中定义,随便给个整数值,不要和已有的重复就行了
- menu1.AppendMenu(MF_STRING,ID_TEST1,"Test1"); // 第一项菜单项
- menu1.AppendMenu(MF_STRING,ID_TEST2,"Test2"); // 第二项菜单项
- menu1.InsertMenu(1,MF_BYPOSITION|MF_STRING,
- (UINT)ID_TEST1,"ID_TEST1"); // 在第二项菜单项前添加新菜单项
- 三、 添加子菜单
- 同样用AppendMenu()、InsertMenu()函数。不过要注意参数的设置。
- menu1.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING,
- (UINT) menuMain.GetSubMenu(0) ->m_hMenu,"子菜单");
- //第二个参数是菜单的句柄HMENU
- 四、 删除菜单
- 用DeleteMenu()、RemoveMenu()函数来删除指定位置的菜单/菜单项。
- 两者区别:如果菜单项是一个弹出式菜单,那么DeleteMenu和RemoveMenu之间的区别就很重要。DeleteMenu清除弹出式菜单,但RemoveMenu不清除它。一个是彻底的删除,一个只是移除.
- MSDN: 1.The DeleteMenu function destroys the handle to the menu or submenu and frees the memory used by the menu or submenu. 它使菜单或者子菜单的handle无效(destroys)。
- 2. RemoveMenu does not destroy the menu or its handle, allowing the menu to be reused. 可以再利用,并不从内存中将menu删除。
- 五、 添加右键菜单
- CMenu menu1;
- menu1.CreatePopupMenu(); //动态创建弹出式菜单对象
- menu1.AppendMenu(MF_STRING,ID_TEST1," 菜单项1");
- menu1.AppendMenu(MF_STRING,ID_TEST2," 菜单项2");
- menu1.InsertMenu(2,MF_BYPOSITION|MF_POPUP|MF_STRING,
- (UINT) menuMain.m_hMenu,"子菜单"); //添加子菜单
- CPoint pt;
- GetCursorPos(&pt);
- menu1.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
- menu1.DestroyMenu();
- 动态添加菜单项、子菜单、右键菜单(VC) - 深蓝 - 深蓝
- 六、 响应菜单的事件
- 1. 若是资源中添加的菜单可用Class Wizard添加菜单的响应事件。
- 2. 若是通过代码创建的菜单,要手工实现菜单的消息映射。本例是在CmainFrame类中,当然也可在View类、Doc类中,基于对话框的同样也可以。
- 1) 在.h文件中
- // Generated message map functions
- protected:
- //{{AFX_MSG(CMainFrame)
- afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
- afx_msg void OnChangmenuitem(); //这里添加菜单命令处理函数的声明
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- 2) 在.cpp文件中,
- BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
- //{{AFX_MSG_MAP(CMainFrame)
- ON_WM_CREATE()
- ON_COMMAND(IDM_CHANGMENUITEM, OnChangmenuitem) //这里添加,注意没有’ ;’
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- void CMainFrame::OnChangmenuitem()
- {
- // 这里写你要如何处理的代码
- ……
- }
- 其他方法:
- 若菜单ID值是连续的,最好用ON_COMMAND_RANGE来映射消息处理函数,可以在一个函数中处理一个范围内的所有消息。
- 当用户按下某个菜单项,会发出一个WM_COMMAND消息,而菜单项的ID号,就包含在参数wParam的低位中.
- BOOL CYourView::OnCommand(WPARAM wParam, LPARAM lParam)
- {
- // TODO: Add your specialized code here and/or call the base class
- UINT m_nItemID=LOWORD(wParam);
- if (m_nItemID==ID_YOURITEM) //ID_YOURITEM为你加入菜单项时指定的ID号
- {
- //在这里放入响应的代码
- }
- return CScrollView::OnCommand(wParam, lParam);
- }
- 对于右键菜单可以通过TrackPopupMenu的返回值来处理。在参数uFlags中设置TPM_ RETURNCMD,这样返回值就是你选择的菜单项的ID,然后可以根据ID来处理。
- TrackPopupMenu(TPM_ RETURNCMD ,pt.x,pt.y,this);
- MSDN:If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item identifier of the item that the user selected.
- 七、 其他
- DrawMenuBar () ; //当您改变菜单时,需要重画菜单才能显示所做的改变
- GetSystemMenu () ; //取得窗口控制窗口
- GetMenu() //取得当前程序使用的菜单
- GetSubMenu() //取得子菜单
- 应使用CMenu类的Detach()成员函数从Cmenu对象中分离出菜单句柄,避免对象失效后程序出错。
- 如:
- CMenu menu;
- menu.CreatePopupMenu(); //动态创建弹出式菜单对象
- menu.AppendMenu(0,ID_TEST1,"Test1");
- menu.AppendMenu(0,ID_TEST2,"Test2");
- CMenu* menuMain = GetMenu(); //取得程序主菜单 需在CMainFrame类中
- menuMain->AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING,(UINT)menu.m_hMenu,"子菜单1");
- menu.Detach(); //直接用menu.m_hMenu在运行时出错,menu对象在这个事件结束就销毁了
- DrawMenuBar();
复制代码 |
|