右键菜单的创建总结本文介绍Pop-up的创建,右键菜单在应用软件中可以说是使用极其频繁的一种技术.结合实际项目,做以下总结; 1.定义菜单项结构体:
#pragma pack(push, 1) struct stMenuItem { int iMenuID ; //资源ID char szItem[30] ; //菜单项显示文本 } ; #pragma pack(pop)
2.在要使用Pop-up Menu的文件前定义变量: //PerfTreeView.cpp
stMenuItem MenuItemInsertPerf[] = { {IDM_INSERT_ALLPERF, "增加性能"}, {IDM_END, ""} };3.在PerfTreeView.h定义CMenu对象:CMenu *m_pRightMenu; //初始化: CPerfTreeView::CPerfTreeView() : m_pRightMenu(NULL) { } 在析构函数中销毁 CPerfTreeView::~CPerfTreeView() { if(m_pRightMenu != NULL) { m_pRightMenu->DestroyMenu(); delete m_pRightMenu; m_pRightMenu = NULL; } } 4.创建菜单的函数: /********************************************************************* * 函数名称:void SetRightMenu() * 说明:创建Pop-Up Menu * 入口参数: * 空 * 返回值: * void -- * 作者: Duanyx * 时间 : 2008-03-24 13:23:30 *********************************************************************/ void CPerfTreeView::SetRightMenu() { if(m_pRightMenu == NULL) { m_pRightMenu = new CMenu(); m_pRightMenu->CreatePopupMenu(); } int iNum, i; stMenuItem *pItem = MenuItemInsertPerf; iNum = m_pRightMenu->GetMenuItemCount(); for(i = iNum - 1; i >= 0; i--) { m_pRightMenu->RemoveMenu(i, MF_BYPOSITION); } while (pItem->iMenuID != IDM_END) { if(pItem->iMenuID > 0) { m_pRightMenu->InsertMenu(-1, MF_BYCOMMAND, pItem->iMenuID, pItem->szItem); } else { m_pRightMenu->InsertMenu(-1, MF_SEPARATOR); } pItem++; } } 5.在右键消息中加载此菜单: /********************************************************************* * 函数名称:void OnRButtonDown(UINT nFlags, CPoint point) * 说明:右键消息响应中加载菜单 * 入口参数: * UINT nFlags * CPoint point * 返回值: * void -- * 作者: Duanyx * 时间 : 2008-03-24 14:03:30 *********************************************************************/ void CPerfTreeView::OnRButtonDown(UINT nFlags, CPoint point) { // CTreeView::OnRButtonDown(nFlags, point); CTreeCtrl &treeCtrl = GetTreeCtrl(); UINT nFlag; CPoint cp; GetCursorPos(&cp); treeCtrl.ScreenToClient(&cp); HTREEITEM hSel = treeCtrl.HitTest(cp, &nFlag); m_hPerfItemSel = hSel; treeCtrl.ClientToScreen(&cp); //右键单击时选中结点. if(hSel && (nFlag & (TVHT_ONITEMLABEL | TVHT_ONITEMICON)) != 0) { //选择此结点并使用删除菜单有效 //TreeCtrl默认右键不能选定结点,所以做此处理实现右键单击选定 treeCtrl.SelectItem(hSel); //使菜删除菜单失效 m_pRightMenu->EnableMenuItem(IDM_DELETE_DEFAULTPEF, MF_GRAYED); } else { //当前没有选择结点,使菜删除菜单失效 m_pRightMenu->EnableMenuItem(IDM_DELETE_DEFAULTPEF, MF_GRAYED); } //弹出菜单 m_pRightMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, cp.x, cp.y, this) ; } 6.当然也可用LoadMenu方法加载显式创建的菜单,个人觉得如果一个系统中要使用很多CMenu的话,这样做不是一个值得提倡的方法.