动态菜单

1.动态的添加/插入/删除菜单(弹出菜单,菜单项):
在CMainFrame::OnCreate中:


     CMenu menu;//局部变量
     menu.CreatePopupMenu(); //创建一个空的弹出菜单
     //GetMenu得到菜单栏的指针,AppendMenu添加一个弹出菜单
     //AppendMenu添加弹出菜单如何调用:
     //GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"WinSun");//添加一个弹出菜单


     GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,"WinSun");//在“编辑”项后面插入一个弹出菜单
     //AppendMenu添加菜单项如何调用:
     menu.AppendMenu(MF_STRING,111,"Hello");
     menu.AppendMenu(MF_STRING,112,"Weixin");
     menu.AppendMenu(MF_STRING,113,"Mybole");
 
     menu.Detach();//将这个句柄和CMenu的对象断开
   //在文件里面添加菜单项
   GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Welcome");
   //在“新建”与“打开”之间插入菜单项
   GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND | MF_STRING,115,"维新"); 
   //删除一个指定的菜单项,例如,删除“编辑”这个子菜单
   GetMenu()->DeleteMenu(1,MF_BYPOSITION);
   //删除“文件”中的“打开”菜单项
   GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);




2.完成以下功能:
  将输入的人名、电话号码,放到电话本里面。


  (1)在CMenu2View类中的OnChar中添加代码:


//我们所有的键盘输入,都会通过OnChar这个消息响应函数来捕获
//那么我们在处理的时候需要判断一下。因为我们在增加动态菜单的时候
//我们不能每次回车都去增加一个动态菜单,我们只有当第一输入的时候
//需要增加一个弹出菜单,那么以后再输入的时候,仅仅是往菜单里面增加
//菜单项了。
void CMenu2View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
if (0x0d==nChar) //如果回车等于nchar
{
//如果第一次回车要添加一个弹出菜单,以后每次回车我们只需要添加一个菜单项
//m_nIndex的初始值为-1,当它自加的时候变成0,0==0,就说明是第一次回车
if (0==++m_nIndex)
{
   //创建弹出菜单
m_menu.CreatePopupMenu();
//将弹出菜单添加到菜单栏上,首先应该获取菜单栏的指针,可以利用GetMenu去获取
//而调用GetMenu能不能获得菜单栏的指针,我们之前调用GetMenu是在CMenuFrame中调用的
//因为CMenuFrame属于框架类,而在View类的窗口上面并没有菜单,所以调用GetMenu就无法获得菜单了
            //我如果想要在View类中获得属于框架类的菜单栏的指针,那应该怎样去调用呢?
//既然是属于框架类的,那我们可以首先获得框架类的指针,要得到指向框架类的指针,可以利用GetParent
//然后再去调用GetMenu
GetParent()->GetMenu()->AppendMenu(MF_POPUP,
(UINT)m_menu.m_hMenu,"PhoneBook");
//当我们在CMenuFrame这个窗口,包括它的菜单创建,完全成功之后,当我们再去修改这个菜单之后
   //我们需要让菜单栏重绘
//DrawMenuBar是重画菜单栏,如果一个菜单栏被改变,在Windows已经创建了窗口之后被改变
//我们应该调用DrawMenuBar,来重画改变的菜单栏
   //我们是在VIew中调用的DrawMenuBar,而View类中根本就没有这个菜单栏
//要想让框架类的菜单栏重绘的话,我们需要利用父窗口,也就是CMenuFrame的指针去调用DrawMenuBar
GetParent()->DrawMenuBar();

}
m_menu.AppendMenu(MF_STRING,IDM_PHONE1+m_nIndex,m_strLine.Left(m_strLine.Find(' ')));
//这样就将输入的人名和电话号码都保存到CStringArray这个数组当中了,这个集合类当中
//接下来,我们就要取出来:
//我们是点击一个菜单项,然后它就取出一个
//要对我们动态添加的菜单项进行命令捕获
m_strArray.Add(m_strLine);
//回车的时候我们把先前的字符串清空了
   m_strLine.Empty();
//窗口的重绘是要先将窗口的内容擦出,然后重绘
//Invalidate是让整个客户端区域无效,当一个窗口区域无效,当下一个WM_AINT的消息被发送
//那我们这个客户端区域就会更新。
Invalidate();


}
//否则,我们要把我们输入的字符在窗口上输出
//把所以的字符都保存在CString这个对象当中,然后调用TextOut,将字符串全部输出
else
{
         m_strLine+=nChar;
dc.TextOut(0,0,m_strLine);
}


CView::OnChar(nChar, nRepCnt, nFlags);
}


void CMenu2View::OnPhone1() 
{
// TODO: Add your command handler code here
//将人名和电话号码进行输出
CClientDC dc(this);
dc.TextOut(0,0,m_strArray.GetAt(0));
}


void CMenu2View::OnPhone2() 
{
// TODO: Add your command handler code here
CClientDC dc(this);
dc.TextOut(0,0,m_strArray.GetAt(1));
}


void CMenu2View::OnPhone3() 
{
// TODO: Add your command handler code here
CClientDC dc(this);
dc.TextOut(0,0,m_strArray.GetAt(2));
}


void CMenu2View::OnPhone4() 
{
// TODO: Add your command handler code here
CClientDC dc(this);
dc.TextOut(0,0,m_strArray.GetAt(3));
}


   (2)在CMainFrame类中添加虚函数:OnCommand


//将添加菜单的响应由框架类来捕获,由框架类它首先对我们添加的菜单项
//进行响应,而不是由View类来完成
//这就是如何在框架类当中去截获本该有View类最先响应命令消息的机会,
//通过我们增加虚函数,就是覆盖基类的OnCommand来进行处理
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) 
{
// TODO: Add your specialized code here and/or call the base class
int MenuCmdId=LOWORD(wParam);//取低字节序
    
//要获取到它的子窗口关联的对象
//GetActiveView是CFrameWnd的基类的成员函数,它可以获取当前视类的一个指针
//GetActiveView它返回的是CView的一个指针,而我们需要的是CMenu2View的一个指针,所以要进行转换
CMenu2View *pView=(CMenu2View*)GetActiveView();
//判断:如果说传过来的菜单项它的范围如果在我们定义的四个菜单项之间
    //那我们就对它进行响应,否则,其他的命令消息,我们交由基类的OnCommand进行命令消息的路由
if(MenuCmdId>=IDM_PHONE1 && MenuCmdId<IDM_PHONE1+pView->m_strArray.GetSize())
{
//要在View类中输出人名和电话号码,当然就要用View类的指针去构造
//这样就可以动态的将我们保存的人名和电话号码取出来
CClientDC dc(pView);
dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdId-IDM_PHONE1));
// MessageBox("Test");
//为了让View类不再处理我们截获的几个菜单项的命令响应,我们可以在判断完成之后返回一个TRUE
return TRUE;
}
return CFrameWnd::OnCommand(wParam, lParam);
}






总结:讲了很多有关菜单操作方面的知识:
      1.静态菜单
      2.动态菜单
      3.菜单命令消息的路由 
      4.消息分为三个类:标准消息、命令消息、通告消息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值