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

不过经过更改后编译会出现两个错误,是关于:
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的继承关系:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法 及添加方法的更多相关文章
- 在vs2010中编译log4cxx-0.10.0详细方法(从下载、编译、解决错误详细介绍)
在vs2010中编译log4cxx-0.10.0详细方法(从下载.编译.解决错误详细介绍) http://blog.sina.com.cn/s/blog_a459dcf501013tbn.html
- mybatis sql语句中 in() 长度为0或null的情况
mybatis sql语句中 in() 长度为0或null的情况 比如: select * from A where colName IN <foreach collection="m ...
- 在vs2010中编译log4cxx-0.10.0详细方法
本文一共包含了17个步骤,按照下面的步骤就可以完成vs2010中编译log4cxx的工作了. 1. 下载 log4cxx 以及 apr 和 apr-util 源码: a) http://www.apa ...
- 输入框中的空"",0,null的判断
改了一个小项目,里面有一个小的问题他们是这样提需求的.两个输入框,第一个输入框里面,输入的内容会对第二个输入框中的内容产生影响.具体是这样的:如果第一个输入框中的值不是“0”,那么第二个输入框就不能填 ...
- bug -- android 7.0 popwindow显示位置异常情况解决
android 7.0 popwindow显示位置异常,在android7.1官方进行解决了,但是还是要多7.0的bug进行解决,我的解决方案里面通过重写popwindow进行适配: import a ...
- Javascript 中的false、0、null、undefined和空字符串对象
在Javascript中,我们经常会接触到题目中提到的这5个比较特别的对象——false.0.空字符串.null和undefined.这几个对象很容易用错,因此在使用时必须得小心. 类型检测 我们下来 ...
- 在vs2010中编译log4cxx-0.10.0具体方法(从下载、编译、解决错误具体介绍)
一. 简单介绍 log4cxx是Java社区著名的log4j的c++移植版.用于为C++程序提供日志功能,以便开发人员对目标程序进行调试和审计,log4cxx是apache软件基金会的开源项目,基于A ...
- 黄聪:VS2010中如何让webbrowser不弹出JS异常错误窗口(c#.net)
1.在属性窗口找到ScriptErrorsSuppressed,选择"true",这个选择的意思是,如果网页上有出现错误命令,这个错误提示将被抑制 2.[项目管理那里,在项目上右击 ...
- .Net中使用com组件后发生System.ArithmeticException异常的解决办法(Message=算术运算中发生溢出或下溢。)
最近在开发一个.Net程序,其中涉及到对com组件的调用,或者第三方DLL调用, 在调用完以后如果使用一些小的测试程序继续运行,一切正常,但是在使用带有GUI的form程序,或者WPF程序中,继续执行 ...
随机推荐
- asp.net ToString() 格式化字符串
c# ToString() 格式化字符串 格式化数值:有时,我们可能需要将数值以一定的格式来呈现,就需要对数值进行格式化.我们使用格式字符串指定格式.格式字符串采用以下形式:Axx,其中 A 为格式 ...
- Ptypes一个开源轻量级的c++库,包括对一些I/O操作、网络通信、多线程和异常处理的封装
C++开源项目入门级:Ptypes Ptypes一个开源轻量级的c++库,包括对一些I/O操作.网络通信.多线程和异常处理的封装.虽然代码有限,包括的内容不少,麻雀虽小,五脏俱全. 提高: ...
- 以太坊(ethereum)开发DApp应用的入门区块链技术教程
概述 对初学者,首先要了解以太坊开发相关的基本概念. 学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...
- Qt4.7.4下单独编译QtWebkit
最近编译出了Qt4.7.4的嵌入式版本,但没有编译QtWebkit库.在编译一个使用Webkit的工程时出错,而根据工程的需要,要单独编译QtWebkit库. 由于不想再次编译整个的Qt库,于是 ...
- 15 款 jQuery 社交分享插件
过去几年中社交媒体越来越流行了,能够分享音乐.视频.图像甚至是其他的 docs 文档到互联网上去,这样子还能够提高页面的点击量.通常,一些社交媒体插件都能允许你的用户分享你网站上的内容到其他的社交平台 ...
- 统计插件,Highcharts,以及modelformset
一.modelfromset组件 1.作用:用于批量处理多个表单 form表单对应的组件是formset Modelform对应的组件是modelformset 2.引入 From django.fo ...
- sqlserver/mysql按天,按小时,按分钟统计连续时间段数据
文 | 子龙 有技术,有干货,有故事的斜杠青年 一,写在前面的话 最近公司需要按天,按小时查看数据,可以直观的看到时间段的数据峰值.接到需求,就开始疯狂百度搜索,但是搜索到的资料有很多都不清楚,需要自 ...
- java写出PDF
1\包 <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</ar ...
- CI框架注意
1.在ci框架中,如果想继承自己写的控制器,从而不继承CI_Controller,可以在application/core中定义控制器,从而就可以在controllers中的控制器继承. 2.在ci框架 ...
- auth-booster配置和使用(yii1.5)
auth-booster这个是一个yii框架扩展中的一个模块.是非常好用的(但是里面的说明都是英文的,所以国人用还需要改一点里面的汉化) 1.下载auth-booster这个:http://www.y ...