• VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法 及添加方法


    对于前面问题的分析:来源于http://blog.163.com/yuyang_tech/blog/static/216050083201211144120401/

    解决方法1: //来源:http://www.cnblogs.com/yuzhoufeng/archive/2011/12/11/2284200.html

    今天学习VC++ 2010 MFC单文档应用程序中动态添加菜单,下面是代码部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    ......
    CMenu m_Menu;
    m_Menu.CreatePopupMenu();
    ASSERT(m_Menu.GetSafeHmenu());
    GetMenu()->AppendMenuW(MF_POPUP,(UINT)m_Menu.m_hMenu,_T("文件"));
    m_Menu.AppendMenuW(MF_STRING,111,_T("新建"));
    m_Menu.AppendMenuW(MF_STRING,112,_T("打开"));
    m_Menu.Detach();
    return 0;
    }

      但是GetMenu()返回始终未NULL,无法获取菜单指针,网上查了下,说VS2010建的SDI/MDI与之前的不一样,是类似BCG的一些东西,所以用之前的方法GetMenu()得到CMenu是NULL或者无效。

    【解决方案】:

      在CMainFrame类中找到CMFCMenuBar m_wndMenuBar;这个成员变量,将跟它相关的代码注释掉的话,然后运行,OK。

    解决方法2: //来源:http://blog.csdn.net/grasshopperwarbler/article/details/6337754

    这里说的是SDI的情况,如果在vs2010里面按着默认选项创建一个单文档工程(Single Document).

    问题分析:

    出错的代码如下 :
    GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);
    加在CMainFrame::Oncreate()里面,整个程序就会崩溃,出现的异常类似如此:Unhandled exception at 0x58aba12c (mfc100ud.dll) in menu1.exe: 0xC0000005: Access violation reading location 0x00000004.

    出错的原因是,在执行这段代码的时候,Menu并没有生成。因为采用断点来检测的话,此时的GetMenu返回值不是一个正常的地址。为什么会这样呢?

    后来才发现visual studio2010里默认采用的是Menu格式在OnCreate()末端并未生成。vs2010默认采用的是增加了扩展功能的Menu,所以调用GetMenu()会得到空指针。

    解决方法:

    最原始的解决方法是采用回原来的Menu格式。就在新建工程的一个对话框中选择回原始的菜单模式即可如下图:

    [整理]VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法 - 钰央 - 计算机视觉·图像处理

    不过经过更改后编译会出现两个错误,是关于:

    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)

    两句代码是关于打印功能的。如果不涉及这方面的功能,可以直接把这两句话注释掉。然后在CMainFrame::OnCreate()末尾加上GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);
    程序就可以顺利通过了。

    对于该问题在vs2010上面的解决方法出自http://blog.csdn.net/mjk1133/article/details/6681051

    在VC6.0和VS2010里面动态添加菜单项是不一样的,查看MSDN文档可知,VS2010采用的是MFC9.0版,其中有很多新增的项具体信息请查看http://msdn.microsoft.com/en-us/library/ws8s10w4.aspx,本文就根据自己的测试详细的比较一下二者的区别:

    1.在VC6.0里面动态添加一个子菜单项

    在CMainFrame::OnCtreate()中添加代码,另外要在Resource.h里面添加#define ID_MENU_ADDMENUITEM    32773

    CMainFrame::OnCtreate(){

    //下面是添加的代码

    CMenu *pMenu=AfxGetMainWnd()->GetMenu(); 
    CMenu *pmSub=pMenu->GetSubMenu(1); 
    pmSub->AppendMenu(MF_STRING,ID_MENU_ADDMENUITEM,L"Add Menu &Item"); 

    }//效果是在“Edit”菜单最下面添加了一个"Add Menu Item"子项 

    2.在VS2010里面添加一个子菜单项:

    要对CMainFrame类的OnShowPopupMenu()进行重载,另外要在Resource.h里面添加#define IDS_EDIT_MYITEM_1    32773

    BOOL CMainFrame::OnShowPopupMenu(CMFCPopupMenu* pMenuPopup) 

        // TODO: Add your specialized code here and/or call the base class

        int iIndex = -1; 
        if (!CMFCToolBar::IsCustomizeMode()&&(iIndex=pMenuPopup->GetMenuBar()->CommandToIndex(ID_EDIT_PASTE))>=0) 
        { 
            pMenuPopup->InsertSeparator(iIndex+1); 
            pMenuPopup->InsertItem(CMFCToolBarMenuButton(IDS_EDIT_MYITEM_1,NULL,-1,_T("&MyItem 1")),iIndex+2); 
        }   //使用CommandToIndex()来获得菜单项的索引,然后根据索引来确定子菜单项的添加位置 
        return CFrameWndEx::OnShowPopupMenu(pMenuPopup); 
    }//效果是在“Edit”菜单最下面添加了一个分割线和一个"MyItem 1"子项

    效果如图,因为还没有为其添加处理函数,所以呈灰色:

     

    给添加的子菜单项添加消息处理函数:

    在MainFrame.h里面添加消息处理函数声明:

       class CMainFrame : public CFrameWnd{

    //…

    protected:

      afx_msg void OnEditMyItem1 ();

    }

    然后在MainFrame.cpp消息映射里面添加消息映射项:

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 
         //…

        ON_COMMAND(IDS_EDIT_MYITEM_1, OnEditMyItem1) 
    END_MESSAGE_MAP()

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    CMFCMenuBar的继承关系:

    CObject

        CCmdTarget

               CWnd

                       CBasePane

                              CPane

                                     CMFCBaseToolBar

                                             CMFCToolBar

                                                       CMFCMenuBar

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    SqlMap入门
    本地文件上载到Docker容器
    CentOS7 安装Docker-ce
    windows10 子系统(WSL) 文件位置
    慕课网-安卓工程师初养成-5-1 编程练习
    慕课网-安卓工程师初养成-4-14 Java 循环语句之多重循环
    慕课网-安卓工程师初养成-4-13 练习题
    慕课网-安卓工程师初养成-4-12 Java循环跳转语句之 continue
    慕课网-安卓工程师初养成-4-11 Java循环跳转语句之 break
    慕课网-安卓工程师初养成-4-10 练习题
  • 原文地址:https://www.cnblogs.com/qiangge-blog/p/4899935.html
Copyright © 2020-2023  润新知