对于前面问题的分析:来源于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格式。就在新建工程的一个对话框中选择回原始的菜单模式即可,如下图:

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

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

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

VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法 及添加方法的更多相关文章

  1. 在vs2010中编译log4cxx-0.10.0详细方法(从下载、编译、解决错误详细介绍)

    在vs2010中编译log4cxx-0.10.0详细方法(从下载.编译.解决错误详细介绍) http://blog.sina.com.cn/s/blog_a459dcf501013tbn.html

  2. mybatis sql语句中 in() 长度为0或null的情况

    mybatis sql语句中 in() 长度为0或null的情况 比如: select * from A where colName IN <foreach collection="m ...

  3. 在vs2010中编译log4cxx-0.10.0详细方法

    本文一共包含了17个步骤,按照下面的步骤就可以完成vs2010中编译log4cxx的工作了. 1. 下载 log4cxx 以及 apr 和 apr-util 源码: a) http://www.apa ...

  4. 输入框中的空"",0,null的判断

    改了一个小项目,里面有一个小的问题他们是这样提需求的.两个输入框,第一个输入框里面,输入的内容会对第二个输入框中的内容产生影响.具体是这样的:如果第一个输入框中的值不是“0”,那么第二个输入框就不能填 ...

  5. bug -- android 7.0 popwindow显示位置异常情况解决

    android 7.0 popwindow显示位置异常,在android7.1官方进行解决了,但是还是要多7.0的bug进行解决,我的解决方案里面通过重写popwindow进行适配: import a ...

  6. Javascript 中的false、0、null、undefined和空字符串对象

    在Javascript中,我们经常会接触到题目中提到的这5个比较特别的对象——false.0.空字符串.null和undefined.这几个对象很容易用错,因此在使用时必须得小心. 类型检测 我们下来 ...

  7. 在vs2010中编译log4cxx-0.10.0具体方法(从下载、编译、解决错误具体介绍)

    一. 简单介绍 log4cxx是Java社区著名的log4j的c++移植版.用于为C++程序提供日志功能,以便开发人员对目标程序进行调试和审计,log4cxx是apache软件基金会的开源项目,基于A ...

  8. 黄聪:VS2010中如何让webbrowser不弹出JS异常错误窗口(c#.net)

    1.在属性窗口找到ScriptErrorsSuppressed,选择"true",这个选择的意思是,如果网页上有出现错误命令,这个错误提示将被抑制 2.[项目管理那里,在项目上右击 ...

  9. .Net中使用com组件后发生System.ArithmeticException异常的解决办法(Message=算术运算中发生溢出或下溢。)

    最近在开发一个.Net程序,其中涉及到对com组件的调用,或者第三方DLL调用, 在调用完以后如果使用一些小的测试程序继续运行,一切正常,但是在使用带有GUI的form程序,或者WPF程序中,继续执行 ...

随机推荐

  1. Oracle序列使用:建立、删除、使用

    Oracle序列使用:建立.删除 在开始讲解Oracle序列使用方法之前,先加一点关于Oracle client sqlplus的使用,就是如果执行多行语句的话一定要加“/”才能表示结束,并执行!本篇 ...

  2. java模拟post请求发送json数据

    import com.alibaba.fastjson.JSONObject; import org.apache.http.client.methods.CloseableHttpResponse; ...

  3. asp.net网站在手机浏览器上全屏显示

    前段时间要把asp.net 网站,在手机上全屏浏览,发现总是小小的一块,不能全屏 后来发现 JQuery Mobile  中在开头都用 <meta name="viewport&quo ...

  4. QSocket 总体设计框架说明(观赏)

    QSocket 是 QDAC 开源组件的一个重要的组成部分,终于要开始开工了,为了方便大家了解 QSocket,对 QSocket 的总体设计的一些想法,我在这里给大家简要的描述一下. 首先,QSoc ...

  5. Tomcat cache 缓存 编译

    http://tomcat.apache.org/tomcat-7.0-doc/jasper-howto.html development - Is Jasper used in developmen ...

  6. isHiden和isVisible的区别(可是有nativeEvent进行设置)

    之前一直对isHiden和isVisible的区别比较模糊,都是乱用的.今天因需要仔细看了一下. 1.isHiden只是返回部件的隐藏属性,并不能表示部件当前的真实状态.比如A部件有个子部件B,而A处 ...

  7. 深入解析Windows窗口创建和消息分发(三个核心问题:怎么将不同的窗口过程勾到一起,将不同的hwnd消息分发给对应的CWnd类去处理,CWnd如何简单有效的去处理消息,由浅入深,非常清楚) good

    笔记:争取不用看下面的内容,只看自己的笔记,就能记住这个流程,就算明白了: _tWinMain-->AfxWinMain,它调用四个函数: -->AfxWinInit用于做一些框架的初始化 ...

  8. IT++数学、信号、通讯类库,Blitz++数学,Armadillo 线性代数,Dlib网络,线程,图形,数学,图像,数据挖掘/机器学习,XML等等

    https://en.wikipedia.org/wiki/Blitz%2B%2B https://en.wikipedia.org/wiki/IT%2B%2B https://en.wikipedi ...

  9. JS数据结构第三篇---双向链表和循环链表之约瑟夫问题

    一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...

  10. epoll模型的探索与实践

    我们知道nginx的效率非常高,能处理上万级的并发,其之所以高效离不开epoll的支持, epoll是什么呢?,epoll是IO模型中的一种,属于多路复用IO模型; 到这里你应该想到了,select, ...