孙鑫VC学习笔记:第六讲 菜单

  • CMenuApp 并不是从CWnd派生出来的,所以不能使用MessageBox函数。
               但可以使用全局的MessageBox函数:AfxMessageBox函数
  • 对菜单项Test响应的顺序:           View-Doc-MainFrame-App
  • 消息的分类

  • 菜单的操作
CWnd::GetMenu
CMenu* GetMenu()const;
 
CMenu封装了一些和菜单有关的操作,封装了windows的HMENU(菜单句柄)
 
CMenu::GetSubMenu
CMenu* GetSubMenu( int nPos) const; //获取子菜单

CMenu::SetMenuItemBitmaps
  //BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags,
                             const CBitmaps* pBmpUnchecked, const CBitmaps* pBmpChecked)
 创建图形标记菜单
 获取图形标记菜单位图的大小:
    int GetSystemMetrics( int nIndex)
    nIndex: //system metric or configuration setting
     SM_CXMENUCHECK  //缺省的菜单标记位图的高度
     SM_CYMENUCHECK  //缺省的菜单标记位图的宽度



//改变菜单项的状态
CMenu::EnableMenuItem
只有在CMainFrame的构造函数中将变量 m_bAutoMenuEnable=FALSE时,EnableMenuItem函数才会起作用


如何将整个菜单取消:
  CWnd::SetMenu
   //BOOL SetMenu( CMenu* pMenu);
   SetMenu( NULL);  //移走当前菜单
   
重新加载菜单:
  CMenu menu; // 不能是局部对象
  menu.LoadMenu( IDM_MAINFRAME /×菜单ID*/)//动态的更换菜单
  SetMenu(&menu);
  menu.Detach();//如果menu是局部对象,一定要调用Detach()函数,它将菜单的句柄和我们的C++对象断开,
                  这样当局部对象CMenu析构时,不会销毁我们的菜单


  • 命令更新

菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,
 MFC就在其中创建一个CCmdUI对象。我们可以通过手工或利用ClassWizard在消息映射中添加
 ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。
 
  在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管。
  它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。
  这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针。同一个
  CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。
 
  更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。

void CMainFrame::OnUpdateEditCut( CCmdUI* pCmdUI)
 {
  pCmdUI->Enable();//Enable()函数的缺省参数为 BOOL类型TRUE  
 }
 
 工具栏上的图标,和它所对应的菜单项的ID号是一样的。所以当对菜单项DISABLE或者ENABLE时能够相应
 的在工具栏上显现出来。
 CAYTION!:如果在改变菜单项状态的过程中是用的菜单项ID号,则菜单项状态的改变能在工具栏上相应的
         图标上显现出来,但如果使用的是菜单项的位置索引,则相应的状态不会在工具栏上显现出来。
         这是因为工具栏上的图标和相应菜单项具有相同的ID号,但位置索引是不相同的。
        
实现右键弹出菜单的功能:
   Project->Add To Project->Components and Controls->Visual C++ Components->Pop-up Menu
  
注意:应该把菜单加入CMenuView类

此时,会在CMenuView类中加入一个函数OnContextMenu( CWnd* , CPoint)
 //CWnd::OnContextMenu
 //afx_msg void OnContextMenu( CWnd* pWnd,CPoint pos)
 //Called by framework when the user has clicked the right mouse button(right clicked)
 //in the window.You can process(处理)this message by displaying a context menu using the
 //TrackPopupMenu(用来显示弹出菜单)
 CMenu:: TrackPopupMenu
  //BOOL TrackPopupMenu( UINT nFlags,  //弹出菜单相对于x的位置
                         int x, int y, //鼠标点击的位置坐标,注意这个位置坐标是相对于屏幕坐标
                                       //而不是客户区坐标,使用是需要进行坐标转换
                         CWnd* pWnd,   //菜单的拥有者
                         LPCRECT lpRect=NULL //指定一个矩形,当鼠标在矩形外点击时,菜单消失
                                             //在矩形内点击时,弹出菜单不消失
                       );
                      
                      
  坐标转换:
  CWnd::ClientToScreen
    void ClientToScreen( LPPOINT lpPoint) const;
    void ClientToScreen( LPRECT lpRect) const;
   
 为弹出菜单的“显示”菜单项,在CMenuView和CMainFrame类中分别加入命令捕获OnShow函数
 
 选中“显示”项,发现只有CMenuView类对菜单命令进行捕获,原因是用TrackPopupMenu显示弹出
 菜单时,指定了弹出菜单的拥有者窗口指针
 即使将指针设置为父窗口指针,子窗口依然最先响应菜单命令,只有当子窗口不响应时,才交由父窗口响应
 
 通过代码来动态添加菜单
 CMenu::AppendMenu
  //BOOL AppendMenu( UINT nFlags, UINT nIDNewItem=0, LPCTSTR lpszNewItem=NULL);
  //BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);
  //可以将一个菜单或者一个菜单项添加到现有菜单的末尾
  //nFlags: MF_STRING MF_POPUP MF_SEPARATOR
  //nIDNewItem:当nFlags=MF_POPUP,则nIDNewItem为POPUP菜单的句柄
               //当nFlags=MF_SEPARATOR,则nIDNewItem被Ignored
              
 CMenu::CreatePopupMenu
  //Creates an empty pop-up menu and attaches it to a CMenu object
  //BOOL CreatePopupMenu()
  
 插入菜单
  CMenu::InsertMenu
   //BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem=0,LPCTSTR lpszNewItem);
    //BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp);
    //nPosition的取值由nFlags来确定,如果nFlags=MF_BYPOSITION,则nPosition为位置所以号
                                   //如果nFlags=MF_BYCOMMAND,则nPosition为菜单项ID号
    //nIDNewItem:当nFlags=MF_POPUP,则nIDNewItem为POPUP菜单的句柄
               //当nFlags=MF_SEPARATOR,则nIDNewItem被Ignored
删除子菜单
  CMenu::DeleteMenu()
   //BOOL DeleteMenu( UINT nPosition, UINT Flags); //删除一个指定的菜单项或弹出菜单
   
对动态创建的菜单项进行命令响应
    头文件Resource.h定义了资源的ID
    做一个菜单命令的命令响应函数,它的添加和消息响应函数时一样的,一共有三个步骤:
    step1:首先在头文件中做命令响应函数的原型
               //MainFrm.h
               //protected:
               //afx_msg void OnHello();
    step2: 消息映射                       //使用教程中的方法时,消息映射一定要放到注释宏的外面
          //MainFrm.cpp  
          BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
        //{{AFX_MSG_MAP(CMainFrame)
          // NOTE - the ClassWizard will add and remove mapping macros here.
          //    DO NOT EDIT what you see in these blocks of generated code !
         ON_WM_CREATE()
        //}}AFX_MSG_MAP
        ON_COMMAND(IDM_HELLO/*ID号*/,OnHello/*命令响应函数*/)   //注意!不要加任何的标点符号
      END_MESSAGE_MAP()
    step3:命令响应函数的实现
             //MainFrm.cpp
             void CMainFrame::OnHello()
             {
          MessageBox("Hello!");
        }

编写电话本程序

注:菜单栏是属于框架窗口的,在view类中调用GetMenu()是无法获得指向菜单的指针的,因为view窗口根本
    没有菜单
   
对菜单栏进行重绘
    CWnd::DrawMenuBar
     void DrawMenuBar()
     //Redraw the menu bar .If a menu bar is changed after windows has created the window,
     //cal the function to draw the changed menu bar.
     利用父窗口(框架窗口)调用DrawMenuBar

对窗口进行重绘
    CWnd::Invalidate
    //void Invalidate( BOOL bErase=TRUE)
   
CString的查找功能
    CString::Find
      int Find( TCHAR ch)const;
      int Find( LPCTSTR lpszSub)const;
      int Find( TCHAR ch, int nStart)const;
      int Find( LPCTSTR pstr, int nStart)const;
    Return Value
      返回基于0的第一个匹配的字符(串)索引,如果找不到,返回-1

存储字符串集合类 CStringArray     
     
CWnd::OnCommand
 //virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam) 虚函数
 //The framework calls this member function when the user selects an item from a menu,when a
 //child control sends a notification message(通告消息),or when an accelerator keystroke is
 //translated
 //OnCommand 处理消息映射
 
如何得到框架窗口下的视图窗口的指针:
  CFrameWnd::GetActiveView
   CView* GetActiveView() const;
 Return Value
   A point to the current CView.If there is no current view, returns NULL.
   //获取当前视类的指针 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值