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程序中,继续执行 ...
随机推荐
- Android零基础入门第46节:下拉框Spinner
原文:Android零基础入门第46节:下拉框Spinner 上一期学习了GridView的使用,你已经掌握了吗?本期一起来学习Spinner的使用. 一.认识Spinner Spinner其实就是一 ...
- MySQL 常用数据存储引擎区别
mysql有多种存储引擎,目前常用的是 MyISAM 和 InnoDB 这两个引擎,除了这两个引擎以为还有许多其他引擎,有官方的,也有一些公司自己研发的.这篇文章主要简单概述一下常用常见的 MySQL ...
- PHPstudy + phpstrom +xdebug 断点调试(windows) - CSDN博客
原文:PHPstudy + phpstrom +xdebug 断点调试(windows) - CSDN博客 php.ini 配置 需要添加如下内容 [XDebug]xdebug.profiler_ou ...
- 动态链接库(Dynamic Link Library)学习笔记(附PE文件分析)
转载:http://www.cnblogs.com/yxin1322/archive/2008/03/08/donamiclinklibrary.html 作者:EricYou 转载请注明出处 注 ...
- c#透明panel
先看下效果 纯透明的pane,然后设置一个半透明的图片,可以看出来显示了父控件的button 看代码 public partial class PanelEx : Panel { protected ...
- C#每天进步一点--异步编程模式
C#可以有一个简单易用的机制用于异步执行方法,那就是委托.下面我介绍三种模式,对于这三种模式来说,原始线程都发起了一个异步方法,然后做一些其他处理.然而这些模式不同的是,原始线程获取发起的线程已经完成 ...
- 30+简约和平铺的WordPress复古主题
现在复古风格的设计非常流行,你可以快速建立属于自己的复古风格的网站.继续阅读下去,我们将展示给你一些精彩的WordPress复古主题. 多年来,网页设计师们纷纷用3D效果,纹理,噪声,渐变的灯光效果, ...
- 30442数据操纵语言DML
5.5 SQL的数据操纵功能 5.5.1 数据插入 使用CREATE语句创建的数据表还只是一个“空壳”,表中没有任何数据.利用SQL语言提供的INSERT语句可以完成向数据表插入数据的任务. INSE ...
- python常用删除库的方法
本文记于初学py的时候,两年后补发. python常用库的安装方法一般有几种,比如: 1.编译过的exe包,直接无脑下一步就可以了. 2.pip install 库名,快速安装.自动匹配最新版本. 3 ...
- Django学习笔记(20)——BBS+Blog项目开发(4)Django如何使用Bootstrap
本文学习如何通过Django使用Bootstrap.其实在之前好几个Django项目中已经尝试使用过了Bootstrap,而且都留有学习记录,我已经大概有了一个大的框架,那么本文就从头再走一遍流程,其 ...