文章类型: VC&C++
关键词: vc,动态菜单,菜单响应,动态菜单响应,动态按钮响应
内容摘要: vc 创建动态菜单及其响应函数

vc 创建动态菜单及其响应函数

2016/12/6 15:59:46    来源:apple    阅读:

//vc 创建动态菜单及其响应函数  vc 创建动态响应的菜单

工作中时常需要变动一些项目,这就可能涉及到动态增加,删除菜单等问题。为了简单起见,使用SDI单文档的MainFrame,主要想借用它的菜单,同时从数组获得动态项目,实际可从数据库,文件等来获得。动态菜单的中心思想是将动态项目ID控制在一定的范围,这样一个响应函数就可分类处理它们。当然相同功能的按钮,只要ID控制在一定范围,本程序稍加改进也可利用。对于在视图,对话框等的情况,只要将其中的获得菜单方法适当改变即可。

 

直接上代码:

 

//一 动态菜单的开始和结束ID,为了简单动态从数组获得,实际可从数据库,文件中获得。

#define IDC_CMD_RANGE_1 (WM_USER+100)//连续命令,开始序号

#define IDC_CMD_RANGE_N (WM_USER+200)//连续命令,结束序号

CString strDynMenuName[]={"NotePad.exe","calc.exe",""};//动态项目

 

//二 动态菜单相关的函数

//为了演示全面,建立了3个类函数,增加,删除,处理动态菜单

// void AddDynamicMenu();

// void DelDynamicMenu(CString strMenuName);

// void ProcessDynamicMenu(UINT nID);


// 2.1 添加动态函数

void CMainFrame::AddDynamicMenu()

{

//1 定义CMenu对象

 CMenu popupMenu,menu1,menu2;

 CMenu haveMain,*pMainMenu;

 //haveMain.LoadMenu(IDR_MENU1); //从资源加载,

//2 创建固定子菜单1

 menu1.CreateMenu();  

 menu1.AppendMenu(0,(IDC_CMD_RANGE_1+11),"http://www.sohu.com"); // 第1项菜单项

 menu1.AppendMenu(0,(IDC_CMD_RANGE_1+12),"mailto:524392421@qq.com?subject=demo&Body=test vc Dynamic menu "); // 第2项菜单项

//3 创建动态子菜单2

 //这里为了简单,从数组得到。实际可以从数据库,磁盘文件等动态获得数据。

    int menuIdx=0;

 menu2.CreateMenu();

 int num=sizeof(strDynMenuName)/sizeof(CString); //动态数组个数  /sizeof(strDynMenuName[0])

 for (menuIdx=0;menuIdx<num;menuIdx++)

 {

  menu2.AppendMenu(0,IDC_CMD_RANGE_1+21+menuIdx,strDynMenuName[menuIdx]);

 }

//4 创建弹出式菜单

 popupMenu.CreatePopupMenu();  

 popupMenu.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING, IDC_CMD_RANGE_1,"删除动态菜单");

 popupMenu.AppendMenu(MF_SEPARATOR);

 popupMenu.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT) menu1.m_hMenu,"固定项目");

 popupMenu.AppendMenu(MF_SEPARATOR);

 popupMenu.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT) menu2.m_hMenu,"动态项目");

 

//5 动态为主菜单添加项目

 //取得指向窗口菜单的Cmenu对象的指针。

 pMainMenu=GetMenu(); //AfxGetMainWnd()->GetMenu();

 //将弹出式菜单插入到第4项菜单帮助之前(菜单项从0开始计算,文件,编辑,查看,帮助)。

 //haveMain.GetSubMenu(0)-> m_hMenu是被装入菜单的第一个菜单项的弹出式菜单的菜单句柄。

 CString strMenu="工作动态菜单";

 //pMainMenu->InsertMenu (3,MF_POPUP|MF_BYPOSITION|MF_STRING, (UINT)haveMain.GetSubMenu(0)->m_hMenu,strMenu);

 pMainMenu->InsertMenu (1,MF_POPUP|MF_BYPOSITION|MF_STRING, (UINT)popupMenu.m_hMenu,strMenu);

 //附加到最后,就是帮助之后

 //pMainMenu->AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT) popupMenu.m_hMenu,strMenu);

 

//6 将窗口菜单与Cmenu对象分离。

 pMainMenu->Detach();

 //haveMain.Detach();   

 menu1.Detach();     

 menu2.Detach();     

 popupMenu.Detach();

 

//7 重画菜单。

 DrawMenuBar();  

}


//2.2 删除动态函数

void CMainFrame::DelDynamicMenu(CString strMenuName)

{

 CMenu *pMainMenu;

 CString str;

 pMainMenu=GetMenu(); //取得指向窗口菜单的Cmenu对象的指针。

 for(int i=pMainMenu->GetMenuItemCount()-1;i>=0;i--) //取得菜单的项数。

 {

  //获得菜单项的标签

  pMainMenu->GetMenuString(i,str,MF_BYPOSITION);

  if (str.Find("动态菜单")>=0)//(str==strMenuName)//删除动态菜单

  {

   pMainMenu->DeleteMenu(i,MF_BYPOSITION);

   break;

  }

 }

 pMainMenu->Detach(); //将窗口菜单与Cmenu对象分离。

 DrawMenuBar(); //重画菜单。

}


//2.3 处理动态菜单工作的函数

void CMainFrame::ProcessDynamicMenu(UINT nEventID)

{

 CString strMenuText;  //菜单项名               

 GetMenu()->GetMenuString(nEventID,strMenuText,MF_STRING);//根据ID得到菜单项名

 int num=nEventID-IDC_CMD_RANGE_1 ;//实际使用的序号

    if (num==0)

 {//删除动态菜单

  DelDynamicMenu("动态菜单");//strMenuName);

 }

 if (11<=num && num<=20)

 {//固定项目处理,比如访问网站,发Email等

  ShellExecute(NULL,NULL,strMenuText,NULL,NULL,SW_SHOWNORMAL);

 }

 if (21<=num && num<=30)

 {//动态部分处理

  CString strCmd;

  strCmd=strDynMenuName[num-21];

  ShellExecute(this->m_hWnd,NULL,strCmd,NULL,NULL,SW_SHOWNORMAL);

 }

}


//三 动态加入自己的菜单到系统菜单


// 在函数 OnCreate中,调用加入动态菜单

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

AddDynamicMenu();//OnCreate最后调用加入动态菜单

}


//四 加入动态响应函数,有两种方法,各有利弊

//方法1 ,比较简单仅需加入系统的OnCmdMsg,只是所有命令消息都要进入,消息多,再从中判断命令ID,是否自己的即可。

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)

{

 if (0 == nCode)//判断是否是命令消息

 {


  if (IDC_CMD_RANGE_1 <= nID && nID<=IDC_CMD_RANGE_N)//在指定范围内

  {

   if (pHandlerInfo==NULL )

   {  

    ProcessDynamicMenu(nID);

   }

   return true;

  }

 } 

 return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

}

 

//方法2 ,稍微复杂,但仅处理自己范围的命令ID,消息少


//2.3  MainFrame.cpp 类中加入自己消息函数实现

void CMainFrame::OnDynamicCommandRange(UINT nEventID)

{

//响应菜单命令系统函数BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)  使用2个参数,

//但是,自定义范围的OnCommandRange(WPARAM wParam, LPARAM lParam) ,使用2个参数 Release 就会失败

 ProcessDynamicMenu(nEventID);

}

 

//五 附录

 

5.1

菜单命令消息处理过程:

当点击一个菜单项时,CMainFrame框架类最先接收,它会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View类检测到没对该菜单项消息做响应,则View类把菜单项消息继续交给文档类 Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息返还给View类,由View类再交还给 CMainFrame类处理。如果CMainFrame类查看到CMainFrame类中也没对该消息做响应,则最终交给App类进行处理。而且一个消息一旦在某个类中被响应过,则不再接着传递。

就像上面的OnCmdMsg处理了就返回   return true; 而不再返回 return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

5.2

添加菜单项消息响应函数:

MFC确定一个Command ID 是否有Handler与之对应,是通过OnCmdMsg(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO* pHandlerInfo),然后根据返回值来确定的。返回值为true,表示有对应的处理函数;返回值为false,表示没有。其中参数nID就是发送过来的消息ID号,对于菜单,就是菜单的ID;参数nCode为0表示是命令消息,如单击菜单项发出的消息,为-1就表示是 UPDATE_COMMAND_UI消息;参数pHandleInfo不为NULL时,表示在检测;当其为NULL时表示是在路由这个命令消息,希望能得到处理。

5.3

调用的ProcessDynamicMenu(nID);可用PostMessage(WM_USER+300,nID);

然后也可加入消息 WindowProc 进行处理

LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

{

 if (message == WM_USER+300)

 {

  UINT nID=LOWORD(wParam); //取 低位

  if (IDC_CMD_RANGE_1 <= nID && nID<=IDC_CMD_RANGE_N)//在指定范围内

  {

   ProcessDynMenu(nID);

  }

 }

 return CFrameWnd::WindowProc(message, wParam, lParam);

}

↑ 上一篇文章:判断文件是否存在,判断是否为文件夹 关键词:attributes,null,security,acc.. 发布日期:2016/12/6 10:03:08
↓ 下一篇文章:VC 动态创建菜单 关键词:VC,动态创建菜单 发布日期:2016/12/6 16:49:45
相关文章:
VC中,出现oxc0000005 读取位置oxddddddddd 时发生访问冲突,0xcccccccc、0xcdcdcdcd和 0xfeeefeee 异常值说明 关键词:VC,oxc0000005,读取,位置,oxddddddddd,0x0000000,发生,访问,.. 发布日期:2018-07-27 10:58
如何将bmp格式的图片转换成8位256色且保证不失真呢 关键词:VC,ps,将,bmp图片,转换,8位,256色,不失真,faststone,image,vie.. 发布日期:2016-08-10 16:28
在VC的MFC中修改静态文本框中文字的字体、颜色 关键词:VC,MFC,修改,静态,文本框,文字,字体,颜色 发布日期:2017-11-29 16:43
相关目录:.NETVC&C++软件开发
我要评论
正在加载评论信息......